如何获取应用抽屉里的所有应用?
How to get all apps in App Drawer?
我用这个从包名打开应用程序
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());
我用这个方法过滤掉所有的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;
}
但是这个方法不能帮我判断哪个包不是系统应用
例如
这是 LG g pro 2 中的 whatsapp
V/sys﹕ 0000000110010000011111001000100 : com.whatsapp : false : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : false : WhatsApp
这是Note4
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+是默认安装的,所以是系统包,但是在应用抽屉里
所以我认为 FLAG_SYSTEM 不适合在 android
中获取所有应用程序
如何获取应用抽屉里的所有应用?
更新:
现在我用这种方式获取所有应用
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+
可以看到包名是错误的,所以我的应用程序会打开错误的应用程序(但可绘制图标是正确的)
我看过 FAST 启动器的源代码,org.ligi.fast.model.AppInfo
。我们获取包名的方法是一样的。
如何通过这种方式得到正确的包名?
我也试过了
ri.resolvePackageName
ri.activityInfo.parentActivityName
ri.activityInfo.processName
但是没有人在工作,有些可能会使我的应用程序崩溃。
你可以这样做:
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
想要在启动器中可见的活动必须指定特定的 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);
我用这个从包名打开应用程序
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());
我用这个方法过滤掉所有的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;
}
但是这个方法不能帮我判断哪个包不是系统应用
例如
这是 LG g pro 2 中的 whatsapp
V/sys﹕ 0000000110010000011111001000100 : com.whatsapp : false : WhatsApp
V/sys﹕ 0000000000000000000000000000001 : com.whatsapp : false : WhatsApp
这是Note4
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+是默认安装的,所以是系统包,但是在应用抽屉里
所以我认为 FLAG_SYSTEM 不适合在 android
中获取所有应用程序如何获取应用抽屉里的所有应用?
更新:
现在我用这种方式获取所有应用
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+
可以看到包名是错误的,所以我的应用程序会打开错误的应用程序(但可绘制图标是正确的)
我看过 FAST 启动器的源代码,org.ligi.fast.model.AppInfo
。我们获取包名的方法是一样的。
如何通过这种方式得到正确的包名?
我也试过了
ri.resolvePackageName
ri.activityInfo.parentActivityName
ri.activityInfo.processName
但是没有人在工作,有些可能会使我的应用程序崩溃。
你可以这样做:
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
想要在启动器中可见的活动必须指定特定的 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);