i'm programming an android app, a Tasker, and i really don't find the way to obtain the label of another app. This is my point, i'm using an ListActivity where you select an installed app, then when you click it creates the Intent and all the app stuff, what i wanna do is to show to the user the android:label from the app he selected, i found in ResolverInfo an attribute called .activityInfo.labelRes, and i think is the label descriptor for the R class of the app the user selected, is there anyway to obtain the string that matches to that id???
Thanks!
D.Gómez
You can use the loadLabel(PackageManager) method of ResolveInfo to get the label of an activity. Here's a full example which finds all the launcher activities on the device and prints them to logcat:
// Get the package manager
PackageManager pm = getPackageManager();
// Create an intent that matches all launcher activities
// (and ignores non-launcher activities)
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
// Get all activites matching the intent
List<ResolveInfo> launchers = pm.queryIntentActivities(launcherIntent, 0);
for(ResolveInfo info : launchers) {
// Get the activity label and print it
CharSequence label = info.loadLabel(pm);
Log.v("LabelTest", "App found: " + label);
}
To answer the second part of your question too, about accessing the resources of an application: They can be accessed by calling getPackageManager().getResourcesForApplication(String), which will return a Resources object that you can use, though in your case, that should not be necessary.
Related
I need to get package name of an app which post notification about a missed call. As far as I understand it makes dialer app of a device. Can I get package name of dialer app on the device, I need it from API 19?
You can filter all dialer applications using Intent.ACTION_DIAL action and PackageManager.queryIntentActivities(...). Where it will return list of applications which can dial phone. Read more at Android: How to show a list of dialer app installed on my device instead of directly calling default dialer
You can use below code, as it is
public List<String> getPackagesOfDialerApps(Context context){
List<String> packageNames = new ArrayList<>();
// Declare action which target application listen to initiate phone call
final Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
// Query for all those applications
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
// Read package name of all those applications
for(ResolveInfo resolveInfo : resolveInfos){
ActivityInfo activityInfo = resolveInfo.activityInfo;
packageNames.add(activityInfo.applicationInfo.packageName);
}
return packageNames;
}
To get an app's package (and activity name) you can use adb command.
Launch the app and then:
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'
From the output:
mFocusedApp=AppWindowToken{
e224f9d token=Token{
d8b2e74 ActivityRecord{
1d97647 u0 com.android.dialer/.app.DialtactsActivity t1078
}
}
}
You can say the app's package is com.android.dialer and activity name is .app.DialtactsActivity
I'm trying to use enableSystemApp method to activate default system apps after provisioning device with the app that is set to device owner mode.
There are two methods to do this:
1) void enableSystemApp (ComponentName admin, String packageName) - in this case you need to pass package name explicitly as String. It works fine, the app gets enabled.
For example, calling this
devicePolicyManager.enableSystemApp(deviceAdminComponent, "com.google.android.gm");
enables default Gmail client, which is disabled after provisioning.
2) int enableSystemApp (ComponentName admin, Intent intent) - in this case, you need to pass an implicit intent and Android should enable all system apps that match this intent. In addition, this method returns int number of apps that match the intent. And here's the problem - I can't get this method to work, it always returns 0 and doesn't enable anything.
Here's the snippet I'm trying to use:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
int i = devicePolicyManager.enableSystemApp(deviceAdminComponent, intent);
It does not work and i == 0 in this case. What am I doing wrong?
Any help is appreciated!
Under the hood, the method that accepts an intent queries to get the list of activities that respond to that intent and then loops through the list passing in the package name string to enable the package. It's similar to doing this:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
List<ResolveInfo> infoes = getPackageManager()
.queryIntentActivities(intent, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
for (ResolveInfo info in infoes) {
devicePolicyManager.enableSystemApp(deviceAdminComponent, info.activityInfo.packageName);
}
Since you are able to enable the app using the package name string, the fault most likely lies in the way the intent is being resolved - which is supported by the fact that it always returns 0.
It is counter-intuitive, but my suspicion is that the application does not resolve the ACTION_MAIN intent because the app is disabled. Have you tried a less generic intent? I would try the following
Intent i;
// #1
// This goes full circle, but I expect it should work
i = getPackageManager().getLaunchIntentForPackage("com.google.android.gm")
// #2
i = new Intent(Intent.ACTION_SEND).setPackageName("com.google.android.gm");
// #3
// Generic, but should resolve _all_ email apps - not just the default one.
// The mailto schema filters out non-email apps
i = new Intent(Intent.ACTION_VIEW , Uri.parse("mailto:"));
Option #1 and #2 are more academic. Both require the package name at which point you may as well use the string overload of enableSystemApp. Option #3 is my best guess for something generic that might still work, but it's possible that it still won't work because the app is disabled.
Note: I find it interesting that enableSystemApp only passes the MATCH_DIRECT_BOOT_AWARE and MATCH_DIRECT_BOOT_UNAWARE flags when querying activities that can resolve the intent, because the MATCH_DISABLED_COMPONENTS and MATCH_SYSTEM_ONLY flags seem much more relevant in this situation.
I did peel the documentation in order to see if there is any method that can check if a particular Settings exists on the current device but I did not find anything.
For example, I would like to do the following:
if "Settings.ACTION_DATA_ROAMING_SETTINGS" exists on the current device then ...
If anyone has the answer, I'm taker.
Intent intent = new Intent(android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS, null);
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
Run the above code to check whether there are some components that handle this specific action. If the activities is not empty, the answer is yes.
Given an applications package name how to know if that application supports widgets on homescreen ??
David Wasser's solution was my first guess too, but it failed to detect one of my widget.
Here's another approach if the first one doesn't work for you.
You can list all receivers for the ACTION_APP_WIDGET_UPDATE action, which allhome screen widget should listen to, and then filter by package name :
PackageManager pm = getPackageManager();
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
List<ResolveInfo> list = pm.queryBroadcastReceivers(intent, 0);
for (ResolveInfo info : list) {
Log.i("package", info.activityInfo.packageName);
}
Use PackageManager and call getPackageInfo(packageName, GET_RECEIVERS) for the application.
Loop through all PackageInfo.receivers and call PackageManager.getReceiverInfo(componentName, GET_META_DATA) for each ActivityInfo object in PackageInfo.receivers.
Look at the field metadata. This may be null or it may contain a Bundle. If it contains a Bundle, look in the Bundle for an item with key "android.appwidget.provider". If you find that then you can be pretty sure that the application supports widgets on the homescreen.
In my application I want to show a list of every available launcher (for homescreen) on that specific Android phone. Is it possible to get some kind of information from Android OS and how do I make this call?
Thanks!
Kind regards
Daniel
You can query the list of ResolverInfo that match with a specific Intent. The next snippet of code print all installed launchers.
PackageManager pm = getPackageManager();
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> lst = pm.queryIntentActivities(i, 0);
for (ResolveInfo resolveInfo : lst) {
Log.d("Test", "New Launcher Found: " + resolveInfo.activityInfo.packageName);
}
The code snippet above does NOT work accurately, as the result of launchers' list also includes system's setting's app whose package name is com.android.settings. This unexpected result happens on both my Pixel 2 (Android 8.0 ) and Nexus 6 (Android 7.1).
Try the following:
Obtain the list of installed applications:
List pkgList = getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
Iterate over this list and obtain launcher activity using:
getPackageManager().getLaunchIntentForPackage(packageName);
For details read here: PackageManager. Hope this helps.