Android适配

您所在的位置:网站首页 手机创建快捷方式图标 Android适配

Android适配

2023-10-11 06:10| 来源: 网络整理| 查看: 265

谷歌官方在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)] 微信小程序-OPPO[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RfGtCtNT-1579749312005)(https://s2.ax1x.com/2019/06/02/V8W6Te.png =150x)]简书-写文章-华为 简书-写文章-华为OPPO 8.1.0ColorOs 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. *

On API 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 broadcast if (callback == null) { context.sendBroadcast(intent); return true; } // Otherwise send the callback when the intent has successfully been dispatched. context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { @Override public 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));

@VisibleForTesting Intent 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_SHORTCUTIntent.EXTRA_SHORTCUT_INTENT :快捷方式启动的IntentIntent.EXTRA_SHORTCUT_NAME :快捷方式的名称如果设置 @see ShortcutInfoCompat.Builder#setAlwaysBadged()则将Activity组件的Icon或者APP的Icon和给定的图画在一起,Badged在右下角,@see IconCompat#addToShortcutIntent()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3