分享

android shortcut 快捷键 相关问题记录

 univasity 2017-02-13

快捷键的生成、删除、判断 那些方法 原生的系统一般木有问题 第三方rom 就会存在 适配问题 

一、权限:

1、manifest 文件中 添加权限 

  1. <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>  
  2.     <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>  
  1. </pre>下面就是关于这个权限 <p></p><p></p><pre name="code" class="html">com.android.launcher.permission.READ_SETTINGS  

不同版本 不同的机型 添加的不同 

Build.VERSION.SDK_INT  < 8 :

  1. com.android.launcher.permission.READ_SETTINGS  

Build.VERSION.SDK_INT  < 19 :

  1. com.android.launcher2.permission.READ_SETTINGS  
Build.VERSION.SDK_INT  >=19 :

  1. com.android.launcher3.permission.READ_SETTINGS  

以华为为例 就需要 添加

  1. uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>  
  2. <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>  
否则在下面的判断的方法里会报错出现

  1. java.lang.SecurityException: Permission Denial:  
  2.  opening provider com.huawei.android.launcher.LauncherProvider from ProcessRecord (pid=17220, uid=10150)   
  3.  requires com.huawei.android.launcher.permission.READ_SETTINGS or com.huawei.android.launcher.permission.WRITE_SETTINGS  

这里列出大部分的平牌机对应的相应权限

  1. <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>  
  2.     <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>  
  3. <uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS"/>  
  4. <uses-permission android:name="com.android.launcher2.permission.WRITE_SETTINGS"/>  
  5. <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS"/>  
  6. <uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS"/>  
  7. <uses-permission android:name="org.adw.launcher.permission.READ_SETTINGS"/>  
  8. <uses-permission android:name="org.adw.launcher.permission.WRITE_SETTINGS"/>  
  9. <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>  
  10. <uses-permission android:name="com.htc.launcher.permission.WRITE_SETTINGS"/>  
  11. <uses-permission android:name="com.qihoo360.launcher.permission.READ_SETTINGS"/>  
  12. <uses-permission android:name="com.qihoo360.launcher.permission.WRITE_SETTINGS"/>  
  13. <uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS"/>  
  14. <uses-permission android:name="com.lge.launcher.permission.WRITE_SETTINGS"/>  
  15. <uses-permission android:name="net.qihoo.launcher.permission.READ_SETTINGS"/>  
  16. <uses-permission android:name="net.qihoo.launcher.permission.WRITE_SETTINGS"/>  
  17. <uses-permission android:name="org.adwfreak.launcher.permission.READ_SETTINGS"/>  
  18. <uses-permission android:name="org.adwfreak.launcher.permission.WRITE_SETTINGS"/>  
  19. <uses-permission android:name="org.adw.launcher_donut.permission.READ_SETTINGS"/>  
  20. <uses-permission android:name="org.adw.launcher_donut.permission.WRITE_SETTINGS"/>  
  21. <uses-permission android:name="com.huawei.launcher3.permission.READ_SETTINGS"/>  
  22. <uses-permission android:name="com.huawei.launcher3.permission.WRITE_SETTINGS"/>  
  23. <uses-permission android:name="com.fede.launcher.permission.READ_SETTINGS"/>  
  24. <uses-permission android:name="com.fede.launcher.permission.WRITE_SETTINGS"/>  
  25. <uses-permission android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS"/>  
  26. <uses-permission android:name="com.sec.android.app.twlauncher.settings.WRITE_SETTINGS"/>  
  27. <uses-permission android:name="com.anddoes.launcher.permission.READ_SETTINGS"/>  
  28. <uses-permission android:name="com.anddoes.launcher.permission.WRITE_SETTINGS"/>  
  29. <uses-permission android:name="com.tencent.qqlauncher.permission.READ_SETTINGS"/>  
  30. <uses-permission android:name="com.tencent.qqlauncher.permission.WRITE_SETTINGS"/>  
  31. <uses-permission android:name="com.huawei.launcher2.permission.READ_SETTINGS"/>  
  32. <uses-permission android:name="com.huawei.launcher2.permission.WRITE_SETTINGS"/>  
  33. <uses-permission android:name="com.android.mylauncher.permission.READ_SETTINGS"/>  
  34. <uses-permission android:name="com.android.mylauncher.permission.WRITE_SETTINGS"/>  
  35. <uses-permission android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS"/>  
  36. <uses-permission android:name="com.ebproductions.android.launcher.permission.WRITE_SETTINGS"/>  
  37. <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>  
  38. <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>  
  39. <uses-permission android:name="com.lenovo.launcher.permission.READ_SETTINGS"/>  
  40. <uses-permission android:name="com.lenovo.launcher.permission.WRITE_SETTINGS"/>  
  41. <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>  
  42. <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>  
  43. <uses-permission android:name="telecom.mdesk.permission.READ_SETTINGS"/>  
  44. <uses-permission android:name="telecom.mdesk.permission.WRITE_SETTINGS"/>  
  45. <uses-permission android:name="dianxin.permission.ACCESS_LAUNCHER_DATA"/>  


二、provider.authority为null的问题

  1. public  boolean hasShortcut(Context context, String shortCutName)  
  2.     {  
  3.         boolean has = false;  
  4.         final ContentResolver cr = context.getContentResolver();  
  5.         String AUTHORITY = getAuthorityFromPermission(context,  
  6.                 "com.android.launcher.permission.READ_SETTINGS");  
  7.   
  8.         final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY  
  9.                 + "/favorites?notify=true");  
  10.   
  11.         // 确认content Provider中是否有快捷键信息  
  12.         Cursor c = cr.query(CONTENT_URI, new String[]  
  13.         { "title", "iconResource" }, "title=?", new String[]  
  14.         { shortCutName.trim() }, null);  
  15.         if (c != null && c.getCount() > 0)  
  16.         {  
  17.             has = true;  
  18.             if (c!=null&&!c.isClosed())  
  19.             {  
  20.                 c.close();  
  21.             }  
  22.         }  
  23.         return has;  
  24.     }  


  1. private  String getAuthorityFromPermission(Context context,  
  2.             String permission)  
  3.     {  
  4.         if (permission == null)  
  5.             return null;  
  6.         List<PackageInfo> packs = context.getPackageManager()  
  7.                 .getInstalledPackages(PackageManager.GET_PROVIDERS);  
  8.         if (packs != null)  
  9.         {  
  10.             for (PackageInfo pack : packs)  
  11.             {  
  12.                 ProviderInfo[] providers = pack.providers;  
  13.                 if (providers != null)  
  14.                 {  
  15.                     for (ProviderInfo provider : providers)  
  16.                     {  
  17.                         if (permission.equals(provider.readPermission))  
  18.                             return provider.authority;  
  19.                         if (permission.equals(provider.writePermission))  
  20.                             return provider.authority;  
  21.                     }  
  22.                 }  
  23.             }  
  24.         }  
  25.   
  26.         return null;  
  27.     }  

通常写法 应该是这样 或者再加入这些代码:

  1. if (TextUtils.isEmpty(AUTHORITY))  
  2.     {  
  3.         int sdkInt = Build.VERSION.SDK_INT;  
  4.         if (sdkInt < 8)  
  5.         { // Android 2.1.x(API 7)以及以下的  
  6.             AUTHORITY = "com.android.launcher.settings";  
  7.         } else if (sdkInt < 19)  
  8.         {// Android 4.4以下  
  9.             AUTHORITY = "com.android.launcher2.settings";  
  10.         } else  
  11.         {// 4.4以及以上  
  12.             AUTHORITY = "com.android.launcher3.settings";  
  13.         }  
  14.     }  

但对第三方rom来说 好像还是行不通  权限值虽然取到了 这样得到的uri 对应的cursor 依然为空 看来权限并没有获取 正确 。通过对provideInfo的遍历 我发现后缀字符串为"launcher.permission.READ_SETTINGS" 日志过滤出的权限只有一个 并且正是我想要的。以下是我对获取权限方法的些许改动

  1. private  String getAuthorityFromPermission(Context context)  
  2.     {  
  3.         List<PackageInfo> packs = context.getPackageManager()  
  4.                 .getInstalledPackages(PackageManager.GET_PROVIDERS);  
  5.         if (packs != null)  
  6.         {  
  7.             for (PackageInfo pack : packs)  
  8.             {  
  9.                 ProviderInfo[] providers = pack.providers;  
  10.                 if (providers != null)  
  11.                 {  
  12.                     for (ProviderInfo provider : providers)  
  13.                     {  
  14.                           
  15.                             //"launcher.permission.READ_SETTINGS" 规律总结 不见得适配所有 需要测试  
  16.                             if (!TextUtils.isEmpty(provider.readPermission)&&provider.readPermission.contains("launcher.permission.READ_SETTINGS"))  
  17.                             {  
  18.                                 return provider.authority;  
  19.                             }  
  20.                     }  
  21.                 }  
  22.             }  
  23.         }  
  24.   
  25.         return null;  
  26.     }  

 三 、创建快捷方式  点击进入相应的程序或界面

  1. public  void addShortCut(Context mContext)  
  2.     {  
  3.         Intent shortcut = new Intent(  
  4.                 "com.android.launcher.action.INSTALL_SHORTCUT");  
  5.         shortcut.putExtra("duplicate", false);  
  6.         shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, mContext.getResources()  
  7.                 .getString(R.string.str_shortCutName));  
  8.         Parcelable shortcutIcon = Intent.ShortcutIconResource.fromContext(  
  9.                 mContext, R.drawable.icon_shortcut);  
  10.         shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcon);  
  11.   
  12.         Intent intent = new Intent();  
  13. //      ComponentName comp = new ComponentName(mContext.getPackageName(),  
  14. //              mContext.getPackageName() + ".ui.xx."  
  15. //                      + IntentTargetClass.class.getSimpleName());  
  16.   
  17.         intent.setAction(Intent.ACTION_MAIN);  
  18.         intent.addCategory(Intent.CATEGORY_LAUNCHER);  
  19.         intent.setClass(mContext, IntentTargetClass.class);  
  20. //      intent.setComponent(comp);  
  21.         shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);  
  22.         mContext.sendBroadcast(shortcut);  
  23.   
  24.     }  

通常都没有问题 但个别版本 个别第三方又会出现  虽然出现了创建xxx 快捷方式的提醒 但是 手机桌面并没有快捷图标的出现 

这个时候 我把不重复创建的设置  置为true 是否已有创建 需要根据 快捷方式是否已经存在进行判断

  1. shortcut.putExtra("duplicate", true);  
另外 有的快捷方式虽已出现 但是点击快捷方式 并没有进入 我们想要进入的界面 activity

在该activity的声明里 加入  intent_filter  

  1. <intent-filter >  
  2.                <action android:name="android.intent.action.CREATE_SHORTCUT"/>  
  3.            </intent-filter>  
大部分情况下都是ok了 但时仍有个别 快捷方式 图标显示正确 但是 名称并没有显示出我们赋予的 shortcutName 而是显示 app_name 例如 LG部分机型

这个问题没有解决 希望有大神 能帮助解答 


本文 属于 只知其一不知其二 的尝试解决方式  很希望 那些看Launcher 模块源码的大神们 能分享指点一二 

如有错误 欢迎指正

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约