How to get an icon associated with specific Account from AccountManager.getAccounts() - java

There is an icon displayed in account settings for each account. For Google account there is one icon, for Facebook another.
Is there a way of getting this icon from the code in application?

Finally, I solved it:
private Drawable getIconForAccount(Account account, AccountManager manager) {
AuthenticatorDescription[] descriptions = manager.getAuthenticatorTypes();
PackageManager pm = getContext().getPackageManager();
for (AuthenticatorDescription description: descriptions) {
if (description.type.equals(account.type)) {
return pm.getDrawable(description.packageName, description.iconId, null);
}
}
return null;
}

Related

switch between two admob accounts

I got ads limit on my Account 1, so I want to use another admob account in my app. The hard part is that I want to use both accounts and I switch between accounts using remote config. That includes changing APP ID in AndroidManifest.xml and replacing ad unit IDs in my activity. Is it theoretically/practically possible? If yes, how can I do that? What's admob's policy regarding this.
I tried changing app ID using this:
`// Retrieve the boolean remote config parameter from Firebase Remote Config
Boolean useAdmobAppId1 = FirebaseRemoteConfig.getInstance().getBoolean("use_admob_app_id_1");
// Determine which Admob App ID to use based on the value of the remote config parameter
String admobAppId;
if (useAdmobAppId1) {
admobAppId = "ca-app-pub-496948190xxxxxxx~3460231xxx";
} else {
admobAppId = "ca-app-pub-659546309xxxxxxx~6818220xxx";
}
// Update the AndroidManifest.xml file with the determined Admob App ID
try {
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = ai.metaData;
bundle.putString("com.google.android.gms.ads.APPLICATION_ID", admobAppId);
} catch (PackageManager.NameNotFoundException e) {
Log.e("AdmobAppIdUpdater", "Failed to update Admob App ID in AndroidManifest.xml", e);
}
and also tried doing this:
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
updateAdUnitIds();
}
});
private void updateAdUnitIds() {
if (FirebaseRemoteConfig.getInstance().getBoolean("use_admob_account_1")) {
AD_UNIT_ID = getString(R.string.admob_account_1_rewarded_video_ad_unit_id);
REW_INT_AD_UNIT_ID = getString(R.string.admob_account_1_rewarded_int_ad_unit_id);
} else {
AD_UNIT_ID = getString(R.string.admob_account_2_rewarded_video_ad_unit_id);
REW_INT_AD_UNIT_ID = getString(R.string.admob_account_2_rewarded_int_ad_unit_id);
}}```

How can i disable any android app such that it cannot be opened until i change/press some button in app?

I am trying to build a parental control app. So now i want to disable or lock app (like Whatsapp, Facebook, etc). I have tried using PackageManager.setComponentEnabledSetting(). But it is throwing java.lang.SercurityException.
So how can I make a parental control app such that I can disable any app I want without root.
my code is
pm.setComponentEnabledSetting(new ComponentName(temp.activityInfo.packageName,
temp.activityInfo.name+".class"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
my error was this
java.lang.SecurityException: Permission Denial: attempt to change component state from pid=11537, uid=10067, package uid=10029
You must add below permissions to manifest.
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
but , these permissions are for System apps and you can not use. :(
You can not write a app to lock or close another app.this is a policy in Google.
for lock a app you must check running apps repeatedly, if specific app is open,then show a activity over that.
while(!Thread.currentThread().isInterrupted())
{
String topActivity = getFrontApp();
if(topActivity.isEmpty())
{
threadSleep(500);
continue;
}
if(topActivity.equals("lockApp"))
{
showLockActivity();
}
threadSleep(500);
}
// for Api21+ need permission
public static String getFrontApp()
{
if (Build.VERSION.SDK_INT >= 21)
{
UsageStatsManager usageManager = SystemMaster.getUsageStatsManager();
long now = System.currentTimeMillis();
List<UsageStats> localList = usageManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, now - 900_000L, now);
String str = "";
if (localList != null)
{
SortedMap<Long,UsageStats> mySortedMap = new TreeMap<>();
for(UsageStats usageStats : localList)
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
if(!mySortedMap.isEmpty())
str = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
return str;
}
else
{
ActivityManager am = (ActivityManager) getApplication().getSystemService(Context.ACTIVITY_SERVICE);
return am.getRunningTasks(1).get(0).topActivity.getPackageName();
}
above code is very simple , for real app must write more.

Detect if audio or video casting is active

I have recently added a system volume controller to my app & i have overlooked Casting.
The app detects a volume button click using an accessibility service, intercepts the system volume panel by broadcasting the close system dialogues intent and pops my overlay panel, allowing the user to control audio directly from the panel (alarm, music & ring).
I have already added stop checks if the user is in call or the screen is off.
Is there a way to determine if the android device is currently casting video or audio?
I have dug through several API's and they all seem to point to methods within the context of the app, nothing system wide.
The solution was to create a MediaSessionManager instance and check for active controllers, then get the PlaybackType.
MediaController = null;
boolean isCasting = false;
MediaSessionManager mediaSessionManager = (MediaSessionManager) getSystemService(MEDIA_SESSION_SERVICE);
assert mediaSessionManager != null;
List<MediaController> sessions = mediaSessionManager.getActiveSessions(new ComponentName(this, NotificationListener.class));
for(MediaController controller : sessions) {
try {
isCasting = Objects.requireNonNull(controller.getPlaybackInfo()).getPlaybackType() == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE;
} catch (Exception e) {
e.printStackTrace();
}
if(isCasting){
mediaController = controller;
break;
}
}

How to know if a specific app comes to foreground?

Check if an app, for example, Instagram is started by user.
Note: My app is targeting lollipop and above versions in android
Yeah the only way you can do it is through the Accessibility Service. Look at this page to understand how to create it. https://developer.android.com/training/accessibility/service.html They will also need to enable the service via the services -> accessibility screen.
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED you can probably interrogate the package in front to figure out if Instigram is on top.
You definitely don't want to use getRunningTasks since the function was modified in Android 5.0+
I figured out that I can do this by using usage access feature.
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static String getForegroundProcess(Context context) {
String topPackageName = null;
UsageStatsManager usage = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);
if (stats != null) {
SortedMap<Long, UsageStats> runningTask = new TreeMap<Long,UsageStats>();
for (UsageStats usageStats : stats) {
runningTask.put(usageStats.getLastTimeUsed(), usageStats);
}
if (runningTask.isEmpty()) {
return null;
}
topPackageName = runningTask.get(runningTask.lastKey()).getPackageName();
}
if(topPackageName==null) {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
context.startActivity(intent);
}
return topPackageName;
}
Now continuously check if the desired app is in the foreground.
String fg=getForegroundProcess(getApplicationContext());
if(fg != null && fg.contains("com.instagram.android")){
//Instagram is in foreground
}else {
}
I continuously run the above code with a job service.Which is available for
lollipop and above.

Android App Category via Play Store

I want to build a list of my apps which are installed on my android device. And i want to save the used categories of my apps in my list, too.
So for example. i can see how much "Games" apps i have etc.
I already have a list of the android apps installed in my device, and now i need the categories.
My first approach was to use appaware.com but my goal is to use the official play-store.
Do you have any ideas how i can use that beside scanning the website. Do you know any unofficial APIs in Java or JavaScript or are the any hidden official APIs for that?
so what i have: - a list of all my apps (incl. package etc.)
what i need: an API to get the categories of the apps :-)
thanks for your answers.
I also faced the same issue. The solution for the above query is stated below.
Firstly, download the Jsoup library or download the jar file.
or Add this to your build.gradle(Module: app) implementation 'org.jsoup:jsoup:1.11.3'
private class FetchCategoryTask extends AsyncTask<Void, Void, Void> {
private final String TAG = FetchCategoryTask.class.getSimpleName();
private PackageManager pm;
//private ActivityUtil mActivityUtil;
#Override
protected Void doInBackground(Void... errors) {
String category;
pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
Iterator<ApplicationInfo> iterator = packages.iterator();
// while (iterator.hasNext()) {
// ApplicationInfo packageInfo = iterator.next();
String query_url = "https://play.google.com/store/apps/details?id=com.imo.android.imoim"; //GOOGLE_URL + packageInfo.packageName;
Log.i(TAG, query_url);
category = getCategory(query_url);
Log.e("CATEGORY", category);
// store category or do something else
//}
return null;
}
private String getCategory(String query_url) {
try {
Document doc = Jsoup.connect(query_url).get();
Elements link = doc.select("a[class=\"hrTbp R8zArc\"]");
return link.text();
} catch (Exception e) {
Log.e("DOc", e.toString());
}
}
}
In return, you will get Application Company Name and category of the application

Categories