Android开发之桌面快捷键使用细则
好了,现在通过 XML 已经写好了快捷方式,那现在该如何使用,让快捷方式生效?那么,只需要在清单文件中启动 Activity 的里面,加入以下2行代码(也就是通过 meta-data 配置进去)即可看到效果:
<activity
android:launchMode="singleInstance"
android:name=".MainActivity"
android:excludeFromRecents="true"
>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
静态注册
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcut"/>
这里的 meta-data 就是配置了桌面快捷方式的一些信息。代码运行后,执行创建快捷方式的操作即可看到效果:
7eb277f9d930aba7c6a92ca5acc078a2
第二种注册:代码动态注册
首先,获取系统服务,固定写法:getSystemService(ShortcutManager.class);获取 ShortcutManager 类对象。接着,获取完 ShortcutManager 对象以后,通过 setDynamicShortcuts( List )方法去设置 Shortcut 快捷方式具体的名字、icon 以及逻辑。既然,现在要通过 ShortcutInfo 去完成信息填充,那么我们就先看下 ShortcutInfo 的基本写法:
//获取系统服务得到ShortcutManager对象
ShortcutManager systemService = getSystemService(ShortcutManager.class);
if (Build.VERSION.SDK_INT >= 25) {
//设置Intent跳转逻辑
Intent intent = new Intent(ShortCut7_0Activity.this, TargetActivity.class);
intent.setAction(Intent.ACTION_VIEW);
//设置ID
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(this, "onlyId")
//设置短标题
.setShortLabel("雅蠛蝶")
//设置长标题
.setLongLabel("江山留胜迹")
//设置icon
.setIcon(Icon.createWithResource(this, R.drawable.yuanbao))
//设置Intent
.setIntent(intent)
.build();
//这样就可以通过长按图标显示出快捷方式了
systemService.setDynamicShortcuts(Arrays.asList(shortcutInfo));
以上代码就可以创建桌面快捷方式,通过 ShortcutInfo 的 Builder 写法可以动态的插入快捷方式的名称、icon、以及 Intent 逻辑。值得一提的是,ShortcutManager 最大可以创建5个,但桌面上只能最多只能显示4个快捷方式,可能是谷歌团队基于何种情况的考虑进行的限制,这里就不做深入研究。另外,快捷方式的顺序排列是:前面添加的显示在下方,后面添加的显示在上面。
e4822c6d6580d138a1036aff3cf32f28
另外,移除快捷方式可以调用如下 API:
void removeDynamicShortcuts(@NonNull List shortcutIds);
Android 8.0 系统快捷方式的变化
可能是谷歌出新版本需要优化增加既有版本的一些功能从 Android 8.0(API 26,也就是 minSdkVersion 26,也就是Android O )开始,对 ShortcutManager 这个类新增了更多的管理措施。那么 O 系统主要的扩充说明有那些?我这里就简单说明下。
APP 可以使用 requestPinShortcut(ShortcutInfo,IntentSender)将现有的快捷方式(静态或动态)或全新的快捷方式固定到支持的启动器。这俩参数的意思是:
ShortcutInfo 对象 – 如果快捷方式已存在,则该对象仅包含快捷方式的 ID。如果快捷方式不存在,新的 ShortcutInfo 对象必须包含新快捷方式的 ID,意图和短标签。
PendingIntent 对象 – 此意图表示如果快捷方式成功固定到设备的启动器,您的应用程序将收到回调。
分析:也就是说,谷歌要求新的快捷方式需要编写的严谨,然后该快捷方式是否固定到设备加了新的判断标准
由于Android O 中引入的后台执行限制,最好使用清单声明的接收器来接收回调。
另外,为了防止其他应用程序调用接收器,需要将属性赋值 android:exported =”false” 添加到接收者的清单条目中。
分析:针对 O 系统对于服务的严格限制,这是对快捷方式功能的扩充
并不是所有的启动器都支持固定快捷方式!!!所以,如果要确定该 APP 是否支持国定快捷方式,可以使用 isRequestPinShortcutSupported() 这个方法的返回值。
根据返回值,可以决定隐藏 App 中允许,用户固定快捷方式的选项。该方法返回 TRUE,则意味着,桌面支持 requestPinShortcut;
但是用户也可能会更改,更改选项以后,再次启动 APP 返回值可能就会发生变化。另外,系统版本低于 Android O,那么它支持使用旧的私有意图com.android.launcher.action.INSTALL_SHORTCUT。requestPinShortcut 这个方法请求创建固定的快捷方式。默认启动器将收到该请求,并要求用户批准。如果用户批准,将创建快捷方式,并且将发送 resultIntent。但是,如果请求被用户拒绝,则不会向呼叫者发送任何响应。需要注意的是,只有具有前台活动或前台服务的应用程序才能调用此方法。否则,它将抛出 IllegalStateException。
分析:也就是说,这种启动器的固定快捷方式能否成功很大程度跟用户的操作密切相关(这个可以跟产品吹一波了)。另外可以看到O系统对于服务的严格控制,严格控制后台服务需要使用前台服务的举措在于让应用更加安全(因此 IntentService 在新版本上要慎用。当然谷歌在开发者文档上针对后台服务这一问题也给了对应的解决办法),这也看到了谷歌技术团队对后续版本使用应用安全的决心。
综上:可以有以下代码
@RequiresApi(api = Build.VERSION_CODES.O)
public static void testShortCut(Context context) {
ShortcutManager shortcutManager = (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
boolean requestPinShortcutSupported = shortcutManager.isRequestPinShortcutSupported();
Log.i(TAG, "启动器是否支持固定快捷方式: "+requestPinShortcutSupported);
if (requestPinShortcutSupported) {
Intent shortcutInfoIntent = new Intent(context, TargetActivity.class);
shortcutInfoIntent.setAction(Intent.ACTION_VIEW);
ShortcutInfo info = new ShortcutInfo.Builder(context, "tzw")
.setIcon(Icon.createWithResource(context, R.drawable.yuanbao))
.setShortLabel("O系统短")
.setLongLabel("O系统长")
.setIntent(shortcutInfoIntent)
.build();
//当添加快捷方式的确认弹框弹出来时,将被回调CallBackReceiver里面的onReceive方法
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, CallBackReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
shortcutManager.requestPinShortcut(info, shortcutCallbackIntent.getIntentSender());
}
}
class CallBackReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive: 固定快捷方式的回调");
}
}
下面是应用启动后,Android Studio 自带 8.0 模拟器,首先创建快捷方式的逻辑顺序:
点击 ADD…以后,我们的应用就显示这样了,可以看到快捷方式向卫星一样挂靠在应用icon 上面:
如果点击 CANCEL,那么就没有创建,退出以后 icon 还是原样,当我们第二次打开应用,选择申请桌面快捷方式的时候,又会弹出上面的申请界面。
总结
这篇博客花了一些时间,因为要考虑三种不同情况(如果想要看到三种情况的效果,需要手动更改 minSdkVersion 版本号、以及对应版本的模拟器资源),当然也参考了一些作者的文章。源码里面有所有代码,如果写的不好或者有任何问题可以直接在评论区或者github 指出。
文章用到的源码:
如果这篇文章对你有帮助,希望各位看官留下宝贵的 star,谢谢。
欢迎长按下图->识别图中二维码