创建应用快捷方式,教你如何适配android7.1以上和android8.0的新api ShortcutManager

本文主要是介绍创建应用快捷方式,教你如何适配android7.1以上和android8.0的新api ShortcutManager,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近公司有个需求,如何让用户快速使用App里面的某一个小功能,很显然创建桌面快捷很符合这个需求。效果页面可以参考微信或者支付宝的小程序添加到桌面快捷。

由于android7.1以上出了新的创建快捷方式,使用新的api ShortcutManager管理一个应用程序的快捷方式,ShortcutManager支持两种创建快捷方式,分别为:静态快捷方式和动态快捷方式。只要长按APP图标就会弹出快捷方式,通过点击快捷键,用户可以快速访问任意一个Activity。长按拖动快捷方式还可以生成桌面快捷(注:这种生成桌面快捷是不需要用户手动开启创建桌面快捷方式权限)。

android8.0在android7.1 ShortcutManager原有的静态快捷方式,动态快捷方式的基础上增加了固定快捷方式。

android7.1以后的长按APP图标效果:

废话不多说,直接上代码:

首先添加权限,在AndroidManiFest.xml里面添加下面权限:

    <!-- 添加快捷方式 --><uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /><uses-permission android:name="com.android.launcher2.permission.INSTALL_SHORTCUT" /><uses-permission android:name="com.android.launcher3.permission.INSTALL_SHORTCUT" /><!-- 查询快捷方式 --><uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" /><uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />

为了匹配各大手机的快捷方式还需添加以下的权限,从名字也可以看出是各大手机的权限:

<!-- 匹配各大手机的快捷方式 --><uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" /><uses-permission android:name="com.android.launcher2.permission.WRITE_SETTINGS" /><uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" /><uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" /><uses-permission android:name="org.adw.launcher.permission.READ_SETTINGS" /><uses-permission android:name="org.adw.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.htc.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.qihoo360.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.qihoo360.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.lge.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="net.qihoo.launcher.permission.READ_SETTINGS" /><uses-permission android:name="net.qihoo.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="org.adwfreak.launcher.permission.READ_SETTINGS" /><uses-permission android:name="org.adwfreak.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="org.adw.launcher_donut.permission.READ_SETTINGS" /><uses-permission android:name="org.adw.launcher_donut.permission.WRITE_SETTINGS" /><uses-permission android:name="com.huawei.launcher3.permission.READ_SETTINGS" /><uses-permission android:name="com.huawei.launcher3.permission.WRITE_SETTINGS" /><uses-permission android:name="com.fede.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.fede.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS" /><uses-permission android:name="com.sec.android.app.twlauncher.settings.WRITE_SETTINGS" /><uses-permission android:name="com.anddoes.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.anddoes.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.tencent.qqlauncher.permission.READ_SETTINGS" /><uses-permission android:name="com.tencent.qqlauncher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.huawei.launcher2.permission.READ_SETTINGS" /><uses-permission android:name="com.huawei.launcher2.permission.WRITE_SETTINGS" /><uses-permission android:name="com.android.mylauncher.permission.READ_SETTINGS" /><uses-permission android:name="com.android.mylauncher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.ebproductions.android.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" /><uses-permission android:name="telecom.mdesk.permission.READ_SETTINGS" /><uses-permission android:name="telecom.mdesk.permission.WRITE_SETTINGS" /><uses-permission android:name="dianxin.permission.ACCESS_LAUNCHER_DATA" />

1、android7.1以下的老式创建快捷方式,相信做过快捷方式的都有用过。

/*android7.1之前,生成快捷方式*/private static void createShortCut(Context context, String actionType) {//创建快捷方式的IntentIntent intent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");// 不允许重复创建,不是根据快捷方式的名字判断重复的intent.putExtra("duplicate", false);intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, context.getString(R.string.openDoor_oneKey));Parcelable icon = Intent.ShortcutIconResource.fromContext(context.getApplicationContext(), R.mipmap.onekey);intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);//这种方式只能进入指定的activity,在桌面长按时,只会出现删除一个选项Intent inte = new Intent(Intent.ACTION_MAIN, Uri.EMPTY, context.getApplicationContext(), ShortCutActivity.class);inte.putExtra(ShortcutsReciever.ACTION_NAME, actionType);intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, inte);context.sendBroadcast(intent);}

经测试部分华为手机需要手动开启创建桌面快捷方式权限才能创建成功,而且无法在app里面去动态申请这个权限。

参考微信支付宝的权限提示,自己也可以根据需求做自己的权限提示。

点击了解详情进入

2、android7.1和以上版本 的ShortcutManager使用静态快捷方式和动态快捷方式创建桌面快捷方式。这种方式创建快捷的好处就是不需要用户手动去打开创建桌面快捷方式的权限。只要长按APP图标就会弹出快捷方式,通过点击快捷键,用户可以快速访问任意一个Activity。长按拖动弹出的快捷方式图标还可以在桌面生成老式的桌面快捷方式。

1)动态创建

if (Build.VERSION.SDK_INT >= 25) {//api25 7.1以上系统使用新的快捷方式,静态快捷方式,动态快捷方式,ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);//点击快捷方式跳转页面ShortCutActivity.classIntent inte = new Intent(Intent.ACTION_MAIN, Uri.EMPTY, context.getApplicationContext(), ShortCutActivity.class);inte.putExtra(ShortcutsReciever.ACTION_NAME, actionType);inte.setAction(Intent.ACTION_VIEW);//设置创建快捷方式的名称和图标ShortcutInfo info = new ShortcutInfo.Builder(context, mPinShortcutId).setIcon(Icon.createWithResource(context, R.mipmap.onekey)).setShortLabel(context.getString(R.string.openDoor_oneKey)).setIntent(inte).build();//动态快捷方式,可以通过长按图标显示出快捷方式了shortcutManager.setDynamicShortcuts(Arrays.asList(info));}

2)静态创建快捷方式

静态方式就是通过xml文件进行配置,先配置快捷方式的选项:
res/xml/static_shortcuts.xml 主要配置如下参数:id、图标、标题、意图,还有分类,是否可用。

<?xml version="1.0" encoding="utf-8"?><shortcuts xmlns:android="http://schemas.android.com/apk/res/android"><!--搜索--><shortcutandroid:enabled="true"android:icon="@drawable/ic_bnsports"android:shortcutDisabledMessage="@string/lable_shortcut_static_search_disable"android:shortcutId="shortcut_id_search"android:shortcutLongLabel="@string/lable_shortcut_static_search_long"android:shortcutShortLabel="@string/lable_shortcut_static_search_short"><intentandroid:action="android.intent.action.VIEW"android:targetClass="com.example.song.jackwaiting.MainActivity"android:targetPackage="com.example.song.jackwaiting" /><!--当前只有这个分类--><categories android:name="android.shortcut.conversation" /></shortcut></shortcuts>

配置完图标的之后,再打开AndroidManiFest.xml配置启动的Activity
AndroidManiFest.xml

<activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><!--add static shortcut--><meta-data android:name="android.app.shortcuts"android:resource="@xml/static_shortcut" /></activity>

操作:长按拖动弹出的快捷方式图标在桌面生成老式的桌面快捷方式。

生成的桌面快捷方式

3、android8.0创建固定快捷方式,其创建的静态快捷方式,动态快捷方式代码跟7.1一样。固定快捷方式其实就是老式的创建快捷方式的效果,会直接在桌面生成一个桌面快捷方式。当然也需要用户手动开启创建桌面快捷方式权限才能创建成功。

//点击快捷方式跳转页面ShortCutActivity.classIntent inte = new Intent(Intent.ACTION_MAIN, Uri.EMPTY, context.getApplicationContext(), ShortCutActivity.class);inte.putExtra(ShortcutsReciever.ACTION_NAME, actionType);inte.setAction(Intent.ACTION_VIEW);//设置创建快捷方式的名称和图标ShortcutInfo info = new ShortcutInfo.Builder(context, mPinShortcutId).setIcon(Icon.createWithResource(context, R.mipmap.onekey)).setShortLabel(context.getString(R.string.openDoor_oneKey)).setIntent(inte).build();//8.0固定快捷方式if (Build.VERSION.SDK_INT >= 26 && shortcutManager.isRequestPinShortcutSupported()) {//8.0后新增了使用固定快捷方式,先判断手机是否支持固定快捷方式Intent reIn = new Intent(context, ShortcutsReciever.class);reIn.setAction(ShortcutsReciever.ACTION_0E);PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, reIn, PendingIntent.FLAG_UPDATE_CURRENT);shortcutManager.requestPinShortcut(info, shortcutCallbackIntent.getIntentSender());}

这里要创建一个广播监听快捷方式是否创建成功

public class ShortcutsReciever extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {LogUtils.v("ShortcutsReciever---", "onReceive : " + intent.getAction());}
}

4、至此创建方式已经完成了,有时候我们可能还需要判断一下桌面是否创建了快捷方式,才好去判断是否弹出提示用户创建快捷方式的弹框。源码如下:7.1以上的好判断,就获取创建快捷方式的所有ShortcutInfo,然后判断其ID是否存在自己创建的快捷方式的id。7.1以下的就要做各种手机和安卓版本的兼容了。

/*** 是否创建了快捷方式** @return*/public static boolean hasShortcut(Context context) {if (Build.VERSION.SDK_INT >= 25) {ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);List<ShortcutInfo> infos = shortcutManager.getPinnedShortcuts();for (int i = 0; i < infos.size(); i++) {ShortcutInfo info = infos.get(i);if (info.getId().equals(mPinShortcutId)) {return true;}}} else {return isShortCutExist(context, context.getString(R.string.openDoor_oneKey));}return false;}public static boolean isShortCutExist(Context context, String appName) {boolean isInstallShortcut = false;if (null == context || TextUtils.isEmpty(appName))return isInstallShortcut;String AUTHORITY = getAuthority(context);LogUtils.i("ShortCutUtil", "AUTHORITY = " + AUTHORITY);final ContentResolver cr = context.getContentResolver();if (!TextUtils.isEmpty(AUTHORITY)) {try {final Uri CONTENT_URI = Uri.parse(AUTHORITY);Cursor c = cr.query(CONTENT_URI, new String[]{"title", "iconResource"}, "title=?", new String[]{appName}, null);if (c != null && c.getCount() > 0) {isInstallShortcut = true;}if (null != c && !c.isClosed())c.close();} catch (Exception e) {// TODO: handle exception}}return isInstallShortcut;}public static String getAuthority(Context context) {// 获取默认String authority = getAuthorityFromPermissionDefault(context);LogUtils.i("ShortCutUtil", "获取默认 AUTHORITY = " + authority);// 获取特殊第三方if (authority == null || authority.trim().equals("")) {String packageName = getCurrentLauncherPackageName(context);packageName += ".permission.READ_SETTINGS";authority = getThirdAuthorityFromPermission(context, packageName);}LogUtils.i("ShortCutUtil", "获取特殊第三方 AUTHORITY = " + authority);// 还是获取不到,直接写死if (TextUtils.isEmpty(authority)) {int sdkInt = android.os.Build.VERSION.SDK_INT;if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的authority = "com.android.launcher.settings";} else if (sdkInt < 19) {// Android 4.4以下authority = "com.android.launcher2.settings";} else {// 4.4以及以上authority = "com.android.launcher3.settings";}}LogUtils.i("ShortCutUtil", "写死 AUTHORITY = " + authority);authority = "content://" + authority + "/favorites?notify=true";return authority;}public static String getAuthorityFromPermissionDefault(Context context) {return getThirdAuthorityFromPermission(context, "com.android.launcher.permission.READ_SETTINGS");}public static String getThirdAuthorityFromPermission(Context context, String permission) {if (TextUtils.isEmpty(permission)) {return "";}try {List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS);if (packs == null) {return "";}for (PackageInfo pack : packs) {ProviderInfo[] providers = pack.providers;if (providers != null) {for (ProviderInfo provider : providers) {if (permission.equals(provider.readPermission) || permission.equals(provider.writePermission)) {if (!TextUtils.isEmpty(provider.authority)// 精准匹配launcher.settings,再一次验证&& (provider.authority).contains(".launcher.settings"))return provider.authority;}}}}} catch (Exception e) {e.printStackTrace();}return "";}public static String getCurrentLauncherPackageName(Context context) {Intent intent = new Intent(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_HOME);ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);if (res == null || res.activityInfo == null) {// should not happen. A home is always installed, isn't it?return "";}if (res.activityInfo.packageName.equals("android")) {return "";} else {return res.activityInfo.packageName;}}

shortcuts扩展:

不管是静态形式还是动态形式,每个应用最多可以注册4个Shortcuts。

显示的顺序问题:添加在前的显示在下方,后面添加的显示在上面。

移除快捷方式
void removeDynamicShortcuts(@NonNull List shortcutIds);

移除快捷方式,并且拖到launcher上的图标会变灰,这个方法底层最终调用的方法跟removeDynamicShortcuts一样
void disableShortcuts(@NonNull List shortcutIds);

使拖到launcher的图标可用。 静态添加的快捷方式不能使用该方法,使用会报错
void enableShortcuts(@NonNull List shortcutIds);

更新快捷方式,例如图标、标题
boolean updateShortcuts(List shortcutInfoList);

参考文章:

https://www.jianshu.com/p/184db7c259ec

https://blog.csdn.net/zhanggang740/article/details/78554031

这篇关于创建应用快捷方式,教你如何适配android7.1以上和android8.0的新api ShortcutManager的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/783572

相关文章

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

SpringShell命令行之交互式Shell应用开发方式

《SpringShell命令行之交互式Shell应用开发方式》本文将深入探讨SpringShell的核心特性、实现方式及应用场景,帮助开发者掌握这一强大工具,具有很好的参考价值,希望对大家有所帮助,如... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

MySQL 分区与分库分表策略应用小结

《MySQL分区与分库分表策略应用小结》在大数据量、复杂查询和高并发的应用场景下,单一数据库往往难以满足性能和扩展性的要求,本文将详细介绍这两种策略的基本概念、实现方法及优缺点,并通过实际案例展示如... 目录mysql 分区与分库分表策略1. 数据库水平拆分的背景2. MySQL 分区策略2.1 分区概念

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S