Android适配 - 桌面快捷方式
谷歌官方在Android 7.1(25)新增了桌面长按弹出菜单,并且在8.0(26)以后可以固定快捷方式至桌面上。围绕桌面快捷方式的需求也比较多,例如微信将联系人、小程序都可以添加至桌面;简书将“写文章”添加至桌面;高德将“坐标信息”添加到桌面。
相关Sample代码链接 https://github.com/scauzhangpeng/Shortcut
权限
谷歌原生系统、三星系统不需要用户主动打开权限,在AndroidManifest声明即可
华为、小米、OPPO、vivo、魅族需要“创建桌面快捷方式”权限
由于各厂家ROM的Launcher改动并且原生也不需要申请权限,所以:
- 无法检测用户是否开启了“创建桌面快捷方式”权限(已有方法检查,可以检查华为、小米、OPPO、VIVO,目前手上测试机都测试通过,后面会给出机型和版本列表,360手机助手这个APP可以有提示权限未开启。根据http://www.lefo.me/2017/05/19/shortcut-permission/>的思路已经整理好相关代码)
- 无法按照运行时权限一样申请“创建桌面快捷方式”权限
- 魅族:系统自动弹窗询问是否可以添加桌面快捷方式
借鉴各大APP的做法,大致上都是弹窗文案指引,并且可以跳转至系统权限设置:
微信 | 支付宝 | 简书 |
---|---|---|
微信在华为手机上没有“前往设置” | 支付宝都没有做权限设置跳转 |
华为跳转到具体的“设置单项权限”界面 需要华为接口权限,因此只能跳转如下界面 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WItqF4BH-1579749312003)(https://s2.ax1x.com/2019/06/02/V8W2Yd.png =150x)] | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RfGtCtNT-1579749312005)(https://s2.ax1x.com/2019/06/02/V8W6Te.png =150x)] | |
OPPO 8.1.0 ColorOs 5.2.1 |
小米 8.1.0 MIUI 9.5 |
华为 8.1.0 EMUI 8.1.0 |
跳转至系统权限设置,在不同厂商机型表现得略有不同(OPPO和vivo只有路径二和三)
- 路径一:设置 - 应用列表 - XX应用 - 权限 - 创建桌面快捷方式
- 路径二:设置 - 权限列表 - 创建桌面快捷方式 - xx应用
- 路径三:自带手机管家 - 权限列表 - 创建桌面快捷方式 - xx应用
图标
自定义图标以及形状(图片bitmap不能太大,不然会超过binder最大数据量显示导致异常)
- 圆形图片:部分机型(三星、vivo、小米)会带一个圆角白色的背景,导致非常丑
- 圆角图片:如果图片不会过大,正常的Launcher的Icon标准是可以的
- 正方形图片(推荐):让系统Launcher自动适配裁剪(三星手机部分版本会存在创建的快捷方式图标偏大,猜测由于正常App图标加了Padding,推荐直接根据桌面图标进行合成裁剪)
系统自动添加应用Icon在快捷方式图标的右下角
- 8.0以上系统自动,并且无法设置不添加
- 8.0以前可以代码设置是否添加,
@see ShortcutInfoCompat.Builder#setAlwaysBadged()
图标的删除方式
- 用户手动清除应用数据会一并清除所有的桌面快捷方式(仅支持8.0以上)
- 用户手动删除桌面快捷方式
- 用户卸载应用
唯一性
在Android 8.0(26)以下,创建快捷方式的方法是发广播给Launcher,无法对快捷方式进行管理;在Android 8.0以上才有相应的API支持管理桌面快捷方式。
是否创建成功
- 8.0以下采用发广播给Launcher,是否创建成功无法知道或者说回调广播不准确
- 8.0以上采用系统API,可以同步返回操作是否成功,然后成功后异步广播回调。
根据ID去重还是根据名称去重
- 8.0以下都是厂商的Launcher的做法,去重依据是根据名称是否一致,去重的效果可能是:
OPPO | 华为 |
---|---|
无提示,不更新 | 有提示已存在,不更新 |
8.0以上可以根据ID进行判断是否存在,然后再进行创建或者更新操作
@see ShortcutManager#getPinnedShortcuts()
@see ShortcutInfo#getId()
华为有点特殊,8.0以上(8.0以及8.1的bug,9.0已经正常)按照ID + 名称去重,不允许同名称的桌面快捷方式即使ID不一致(微信将两个联系人改同样的备注名,然后添加到桌面,即使ID不一致也会提示重复)(目前的做法是检测到重名的,随机生成一个UUID,然后创建成功后再进行更新原名称操作)
源码分析
Support包下的兼容类:ShortcutManagerCompat#requestPinShortcut()
/*** Request to create a pinned shortcut.* <p>On API <= 25 it creates a legacy shortcut with the provided icon, label and intent. For* newer APIs it will create a {@link android.content.pm.ShortcutInfo} object which can be* updated by the app.** <p>Use {@link android.app.PendingIntent#getIntentSender()} to create a {@link IntentSender}.** @param shortcut new shortcut to pin* @param callback if not null, this intent will be sent when the shortcut is pinned** @return {@code true} if the launcher supports this feature** @see #isRequestPinShortcutSupported* @see IntentSender* @see android.app.PendingIntent#getIntentSender()*/public static boolean requestPinShortcut(@NonNull final Context context,@NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {if (Build.VERSION.SDK_INT >= 26) {return context.getSystemService(ShortcutManager.class).requestPinShortcut(shortcut.toShortcutInfo(), callback);}if (!isRequestPinShortcutSupported(context)) {return false;}Intent intent = shortcut.addToIntent(new Intent(ACTION_INSTALL_SHORTCUT));// If the callback is null, just send the broadcastif (callback == null) {context.sendBroadcast(intent);return true;}// Otherwise send the callback when the intent has successfully been dispatched.context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {try {callback.sendIntent(context, 0, null, null, null);} catch (IntentSender.SendIntentException e) {// Ignore}}}, null, Activity.RESULT_OK, null, null);return true;}
源码简洁并配以简单易懂的注释,显得十分优雅。
- 8.0以上调用系统API,返回结果;
- 8.0以下判断当前系统Launcher是否支持创建固定桌面快捷方式
- 当前支持创建固定桌面快捷方式,发送广播;
分析2,源码中如何判断Launcher是否支持创建固定桌面快捷方式
/*** @return {@code true} if the launcher supports {@link #requestPinShortcut},* {@code false} otherwise*/public static boolean isRequestPinShortcutSupported(@NonNull Context context) {if (Build.VERSION.SDK_INT >= 26) {return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();}if (ContextCompat.checkSelfPermission(context, INSTALL_SHORTCUT_PERMISSION)!= PackageManager.PERMISSION_GRANTED) {return false;}for (ResolveInfo info : context.getPackageManager().queryBroadcastReceivers(new Intent(ACTION_INSTALL_SHORTCUT), 0)) {String permission = info.activityInfo.permission;if (TextUtils.isEmpty(permission) || INSTALL_SHORTCUT_PERMISSION.equals(permission)) {return true;}}return false;}
这个检测相当严谨,本人有点想将源码复制出来,去掉这个检测,因为发送广播的方式也不会影响程序运行,只管尝试发广播即可。
- 8.0以上根据新API进行检测
- 8.0以下检测是否有注册权限,如果没有则返回fasle
- 检测是否有Launcher接收
ACTION_INSTALL_SHORTCUT
这个Action的广播,如果有再判断一次它是否注册了权限
分析3,发送广播之前重新构造了Intent,Intent intent = shortcut.addToIntent(new Intent(ACTION_INSTALL_SHORTCUT));
@VisibleForTestingIntent addToIntent(Intent outIntent) {outIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, mIntents[mIntents.length - 1]).putExtra(Intent.EXTRA_SHORTCUT_NAME, mLabel.toString());if (mIcon != null) {Drawable badge = null;if (mIsAlwaysBadged) {PackageManager pm = mContext.getPackageManager();if (mActivity != null) {try {badge = pm.getActivityIcon(mActivity);} catch (PackageManager.NameNotFoundException e) {// Ignore}}if (badge == null) {badge = mContext.getApplicationInfo().loadIcon(pm);}}mIcon.addToShortcutIntent(outIntent, badge);}return outIntent;}
源码也就是将Intent的各种参数设置进去,然后再返回即可
- action :
@see Intent#ACTION_INSTALL_SHORTCUT
- Intent.EXTRA_SHORTCUT_INTENT :快捷方式启动的Intent
- Intent.EXTRA_SHORTCUT_NAME :快捷方式的名称
- 如果设置
@see ShortcutInfoCompat.Builder#setAlwaysBadged()
则将Activity组件的Icon或者APP的Icon和给定的图画在一起,Badged在右下角,@see IconCompat#addToShortcutIntent()
Android适配 - 桌面快捷方式相关推荐
- Android创建桌面快捷方式所遇到的问题与解决方案
将近二个多月没写博客了. 之前一段时间一直在搞红包助手,就没抽时间写博客,但写这个真的是很好玩.没想到居然在Android上实现模拟点击,从而实现自动抢红包,有兴趣的同学可以参考https: ...
- android launcher3桌面快捷方式分析
背景 一般情况下,为了让用户更方便的打开应用,程序会在桌面上生成一些快捷方式. 本来呢,如果是原生的桌面,其实是十分简单,直接调用系统相关的API就行了.但是众多的系统厂商以及众多第三方自己定制的桌面 ...
- android 4.2 桌面快捷方式,Android 添加桌面快捷方式操做
/** android * 为程序建立桌面快捷方式 app */ ide private void addShortcut(){ this Intent shortcut = new Intent(& ...
- android 启动桌面快捷方式,安卓桌面快捷方式传递启动参数
应用里需要根据不同的主题在安卓桌面创建快捷方式.快捷方式可以创建成功,并添加了参数.如下: function createShortcut(){ // 创建快捷方式意图 var shortcut = ...
- android 桌面添加快捷,Android 添加桌面快捷方式操作
/** * 为程序创建桌面快捷方式 */ private void addShortcut(){ Intent shortcut = new Intent("com.android.laun ...
- Android判断桌面快捷方式是否存在
前两天做了个应用,需要实时获取桌面快捷方式是否存在,在某些第三方ROM下无法获取. 网上大量的例子都是谷歌原生系统或者小米.三星这类系统起作用,但是对于第三方ROM无法获取如:HTC.华为.一加.联想 ...
- Ubuntu 17.04系统创建Android Studio桌面快捷方式的方法
下面以"Android Studio"为例,阐述Ubuntu系统中创建桌面快捷方式的方法,假设已将"Android Studio"下载到"/home/ ...
- android自动创建桌面,Android创建桌面快捷方式
需求:点击按钮创建快捷方式 1.用户触发创创建事件时,在手机桌面创建指定页面的快捷方式. 2.当APP关闭时,点击桌面快捷方式打开APP,跳转至指定页面 3.当APP在后台是,点击桌面快捷方式,跳转至 ...
- android 添加桌面快捷方式
.在桌面创建快捷方式方法: 方法一:通过长按某一个应用程序的图标在桌面上创建启动该应用程序的快捷方式. 这个方法安装完程序都用户都能实现. 方法二:在应用程序中构建一个Intent,然后以Broadc ...
- android保存连接地址到桌面快捷方式,Android创建桌面快捷方式两种方法
谈谈在桌面上直接生成.个人觉得这个比较爽快,既然都是快捷方式了干嘛还要再隐藏一层呢?当然喜欢桌面干净的就比较喜欢第二个了. 第一个是通过广播(Broadcast)的形式向Luncher发送请求生成快捷 ...
最新文章
- androidstudio判断手指滑动方向_方向盘的黑科技有多“黑”
- 进阶学习(3.4) Builder Pattern 建造者模式
- 博客园markdown语法扩展
- mysql 5.5 5.6 主从_mysql5.6+主从集的版本号(mysql5.5主机和从机载带后,5.5在设置有一定的差距)...
- Class 17 - 1 动态渲染页面爬取 — Selenium使用
- 关于 ie8不兼容的一些方法
- 多线程下的生产者消费者(一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮)
- 数据结构——单链表的C++实现
- 爱奇艺首页底部导航按钮android,仿爱奇艺/腾讯视频ViewPager导航条实现
- weakhashmap_Java WeakHashMap entrySet()方法与示例
- mysql数据库报错1075_MySQL数据库之在MAC OS X上安装MYSQL
- 使用FastReport报表工具生成标签打印文档
- 谷歌FLASH无法添加保存网站
- AB PLC仿真过程
- 计算机固态硬盘装系统,固态硬盘如何装系统
- Wordpress采集开心版,免费Wordpress采集发布伪原创
- 2022-02-05大数据学习日志——Hadoop离线阶段——Hive SQL DDL
- 超灵敏检测!Enzo HEK293T宿主细胞蛋白ELISA试剂盒
- 试算平衡表两种方法比较
- 翁恺C语言PTA 7-29 二分法求多项式单根
热门文章
- 巫师3储物箱在哪_【沉没的宝箱】巫师3:狂猎全任务全教程全剧情流程图文攻略-挖辣椒攻略...
- 操作系统的目标与作用
- 北大AI公开课第十课--人工智能在生命科学中的应用by碳云智能李英睿
- Python解线性方程组的直接法(5)————平方根法求解线性方程组
- 2017总结,附书单、项目,只喜欢有趣的。。
- 废弃台式计算机类别,废旧台式电脑(台式机)属于什么垃圾分类?
- PythonR LEfSe 分析
- java中实现正态分布
- JS_js数组倒序排列、字符串数组转为数字数组,反转数组/字符串/数字
- 域用户登陆显示计算机图标,PC用户或域用户登陆后任务栏无显示桌面的小图标...