1原理:
com.android.launcher.permission.READ_SETTINGS或者com.android.launcher.permission.WRITE_SETTINGS
然后我就添加了权限,虽然是可以判断了,但是小米,HTC等手机都不能正常使用,这时候突然发现了网上了一段代码,才明白了网友们的想法,现在就来简单分析下,并做出优化。
String url = "content://" + authority + "/favorites?notify=true";
其实判断快捷方式也就是根据这个ContentProvider来判断。但是我们并不知道这个authority,那么怎么知道呢?查询,根据PackageManager得到ProviderInfo,然后判断ProviderInfo的读写权限是否包含com.android.launcher.permission.READ_SETTINGS或者com.android.launcher.permission.WRITE_SETTINGS。
至此原理我们已经明白了。
2解决方案:
1这是网上通用的写法:
public static boolean hasShortcut(Context context, String appName) { String readSettingsPermission = "com.android.launcher.permission.READ_SETTINGS"; String authority = getAuthorityFromPermission2(context, readSettingsPermission); String url = "content://" + authority + "/favorites?notify=true"; final Uri CONTENT_URI = Uri.parse(url); Cursor c = context.getContentResolver().query(CONTENT_URI, null, " title= ? ", new String[] { appName }, null); if (c != null && c.moveToNext()) { return true; } return false; } @SuppressLint("NewApi") private static String getAuthorityFromPermission2(Context context, String permission) { List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS); if (packs != null) { for (PackageInfo pack : packs) { ProviderInfo[] providers = pack.providers; if (providers != null) { for (ProviderInfo provider : providers) { if (permission.equals(provider.readPermission)) return provider.authority; if (permission.equals(provider.writePermission)) return provider.authority; } } } } return null; }
2这是我自己想的方法,虽然思路走到一起了,但是多少有点出入:
public static boolean hasShortcut(Context context, String appName) { String readSettingsPermission = "com.android.launcher.permission.READ_SETTINGS"; String authority = getAuthorityFromPermission1(context, readSettingsPermission); String url = "content://" + authority + "/favorites?notify=true"; final Uri CONTENT_URI = Uri.parse(url); Cursor c = context.getContentResolver().query(CONTENT_URI, null, " title= ? ", new String[] { appName }, null); if (c != null && c.moveToNext()) { return true; } return false; } private static String getAuthorityFromPermission1(Context context, String permission) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appProcessInfos = am.getRunningAppProcesses(); for (int i = 0; i < appProcessInfos.size(); i++) { RunningAppProcessInfo appInfo = appProcessInfos.get(i); List<ProviderInfo> info = context.getPackageManager().queryContentProviders(appInfo.processName, appInfo.uid, PackageManager.GET_PROVIDERS); if (info != null) { for (int j = 0; j < info.size(); j++) { ProviderInfo provider = info.get(j); if (permission.equals(provider.readPermission)) { return provider.authority; } if (permission.equals(provider.writePermission)) { return provider.authority; } } } } return null; }
3这是最后一个版本,速度又提升了20%,而且兼容性更强。记得加下权限。
public static boolean hasShortcut(Context context, String appName) { long start = System.currentTimeMillis(); String authority = getAuthorityFromPermission(context); if (authority == null) { return false; } long end = System.currentTimeMillis() - start; Log.e("Finals", end + " eee"); String url = "content://" + authority + "/favorites?notify=true"; try { Uri CONTENT_URI = Uri.parse(url); Cursor c = context.getContentResolver().query(CONTENT_URI, null, " title= ? ", new String[] { appName }, null); if (c != null && c.moveToNext()) { return true; } } catch (Exception e) { } return false; } private static String getAuthorityFromPermission(Context context) { // 先得到默认的Launcher Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); PackageManager mPackageManager = context.getPackageManager(); ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0); if (resolveInfo == null) { return null; } List<ProviderInfo> info = mPackageManager.queryContentProviders(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.applicationInfo.uid, PackageManager.GET_PROVIDERS); if (info != null) { for (int j = 0; j < info.size(); j++) { ProviderInfo provider = info.get(j); if (provider.readPermission == null) { continue; } if (Pattern.matches(".*launcher.*READ_SETTINGS", provider.readPermission)) { return provider.authority; } } } return null; }
这是常用的各种桌面的权限:
<!-- 快捷方式权限 -->
<uses-permissionandroid:name="com.android.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.android.launcher2.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.android.launcher3.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="org.adw.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.qihoo360.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.lge.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="net.qihoo.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="org.adwfreak.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="org.adw.launcher_donut.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.huawei.launcher3.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.fede.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS"/>
<uses-permissionandroid:name="com.anddoes.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.tencent.qqlauncher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.huawei.launcher2.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.android.mylauncher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.ebproductions.android.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.oppo.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.lenovo.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>