0

我用它从包名打开应用程序

startActivity(getPackageManager().getLaunchIntentForPackage("packagename"));

android中的很多应用程序都无法打开,因为它们是系统包,而不是应用程序。这些包裹无法打开

例如

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());

我用这个方法过滤掉所有系统包

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;
}

但是这种方法不能帮助我确定哪个包不是系统应用程序。

例如

这是 LG g pro 2 中的 whatsapp

V/sys﹕ 0000000110010000011111001000100 : com.whatsapp : false : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : false : WhatsApp

这是在注4

V/sys﹕ 0000000110010000011111011000101 : com.whatsapp : true : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : true : WhatsApp

这是一个特例,我不明白为什么某些设备中的whatsapp是系统包

另一个例子

V/sys﹕ 0000000110110001011111011000101 : com.google.android.apps.plus : true : Google+
V/sys﹕ 0000000000000000000000000000001 : com.google.android.apps.plus : true : Google+

我知道 google+ 是默认安装的,所以它是一个系统包,但它在 App Drawer 中。

所以我认为 FLAG_SYSTEM 不适合在android中获取所有应用程序

如何获取 App Drawer 中的所有应用程序?


更新:

现在我用这种方式获取所有应用程序

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);
}

但有些信息仍然不正确

使用这种方式,我可以获得正确的应用程序名称、正确的可绘制图标和几乎所有正确的包名称。

包名还是有些不对。

例如,这是上述程序的一些输出

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+

可以看到包名是错误的,所以我的app会打开错误的app(但是drawable icon是正确的)

我查看了 FAST 启动器的源代码,org.ligi.fast.model.AppInfo. 我们获取包名的方法是一样的。

我怎样才能以这种方式获得正确的包名?

我也试过

ri.resolvePackageName
ri.activityInfo.parentActivityName
ri.activityInfo.processName

但是没有人工作,有些人可能会使我的应用程序崩溃。

4

2 回答 2

3

你可以这样做:

  final Intent intent = new Intent(Intent.ACTION_MAIN, null);
  intent.addCategory(Intent.CATEGORY_LAUNCHER);
  final List<ResolveInfo> resolveInfoList = ctx.getPackageManager().queryIntentActivities(mainIntent, 0);

有关更多详细信息,您可以查看此启动器的来源: https ://github.com/ligi/FAST

于 2015-10-19T08:28:14.947 回答
2

想要在启动器中可见的活动必须指定特定的intent-filter.

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

您可以使用它PackageManager来获取可以启动的活动列表。

List<ResolveInfo> list = packageManager.queryIntentActivities(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), 0);
于 2015-10-19T08:47:01.077 回答