Reputation: 3759
I use this to open app from package name
startActivity(getPackageManager().getLaunchIntentForPackage("packagename"));
Many apps in android cannot be opened, because they are system package, not apps. These packages are not openable
e.g.
V/sys﹕ 0000000100010000011111001000101 : com.android.keychain : true : Key Chain
V/sys﹕ 0000000000000000000000000000001 : com.android.keychain : true : Key Chain
^
^
^
Log.v("sys", String.format("%31s", Integer.toBinaryString(pkgInfo.applicationInfo.flags)).replace(' ', '0') +" : "+ pkgInfo.packageName+" : "+(((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true:false)+" : "+pkgInfo.applicationInfo.loadLabel(pm).toString());
Log.v("sys", String.format("%31s", Integer.toBinaryString(ApplicationInfo.FLAG_SYSTEM)).replace(' ', '0') +" : "+ pkgInfo.packageName+" : "+(((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true:false)+" : "+pkgInfo.applicationInfo.loadLabel(pm).toString());
I use this method to filter out all systempackage
private boolean isSystemPackage(PackageInfo pkgInfo)
{
Log.v("sys", String.format("%31s", Integer.toBinaryString(pkgInfo.applicationInfo.flags)).replace(' ', '0') +" : "+ pkgInfo.packageName+" : "+(((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true:false)+" : "+pkgInfo.applicationInfo.loadLabel(pm).toString());
Log.v("sys", String.format("%31s", Integer.toBinaryString(ApplicationInfo.FLAG_SYSTEM)).replace(' ', '0') +" : "+ pkgInfo.packageName+" : "+(((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true:false)+" : "+pkgInfo.applicationInfo.loadLabel(pm).toString());
return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true:false;
}
But this method cannot help me to determine which package is not system apps.
For example
this is whatsapp in LG g pro 2
V/sys﹕ 0000000110010000011111001000100 : com.whatsapp : false : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : false : WhatsApp
this is in Note4
V/sys﹕ 0000000110010000011111011000101 : com.whatsapp : true : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : true : WhatsApp
This is a special case, I don't understand why whatsapp in some device is system package
Another example
V/sys﹕ 0000000110110001011111011000101 : com.google.android.apps.plus : true : Google+
V/sys﹕ 0000000000000000000000000000001 : com.google.android.apps.plus : true : Google+
I know google+ is installed by default, so it is a system package, but it is in App Drawer.
So I think FLAG_SYSTEM that is not suitable to get all apps in android
How to get all apps which in App Drawer?
Update:
Now I use this way to get all apps
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(intent, 0);
PackageManager pm = getPackageManager();
for(ResolveInfo ri : resolveInfoList)
{
String appName=ri.activityInfo.loadLabel(pm).toString();
Drawable icon=ri.loadIcon(pm);
Log.v("sys",ri.activityInfo.packageName +":" + appName);
}
But some information is still incorrect
Use the way, I can get correct app name, correct icon drawable and almost all of correct package name.
Package names still have some wrong.
For example, this is some output of above program
V/sys﹕ com.android.contacts:Contacts
V/sys﹕ com.android.contacts:Phone <<<<wrong
V/sys﹕ com.google.android.apps.plus:Photos <<<<wrong
V/sys﹕ com.google.android.apps.plus:Google+
You can see the package name is wrong, so my app will open wrong app (But the drawable icon is correct)
I have looked the source code of FAST launcher, org.ligi.fast.model.AppInfo
. Our way to get package name is same.
How can I get the correct package name in this way?
I also tried
ri.resolvePackageName
ri.activityInfo.parentActivityName
ri.activityInfo.processName
But no one is work, some may make my app crash.
Upvotes: 0
Views: 838
Reputation: 2658
Activities that want to be visible in the launcher have to specify a specific intent-filter
.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
You can use this with PackageManager
to get a list of activities that can be launched.
List<ResolveInfo> list = packageManager.queryIntentActivities(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), 0);
Upvotes: 2
Reputation: 39529
You can do it this way:
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final List<ResolveInfo> resolveInfoList = ctx.getPackageManager().queryIntentActivities(mainIntent, 0);
for more details you might look into the source of this launcher: https://github.com/ligi/FAST
Upvotes: 3