CL So
CL So

Reputation: 3759

How to get all apps in App Drawer?

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

Answers (2)

Zharf
Zharf

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

ligi
ligi

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

Related Questions