最近在使用Android版Chrome的时候发现长按应用图标会出现如下图所示的快捷键:
![](https://i-blog.csdnimg.cn/blog_migrate/ec4a8896ad69be4d3815ff6713bb0437.jpeg)
这种新特性被我发现之后,我又找了几个出名的应用尝试了一下,又发现支付宝、UC浏览器这些APP也接入了这一新特性。接着我又去找了度娘,从度娘的搜索结果中我才知道这一新特性在Android7.0的时候就被提出来了,只是在国内的APP中应用的不广泛罢了。经过阅读网上大牛的技术博客以及自己的尝试,我自己对此新特性有了一定的认识。这个新特性的使用方式有点类似于广播,一个是静态使用,一个是动态使用。
一、静态使用shortcuts
1.1 创建资源文件
在res目录下创建xml文件夹,创建成功之后继续在该文件夹下shortcuts的资源文件。Shortcuts.xml的源代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<!--静态方式的使用,产生的标签最多也只有4个-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<!--
android:enabled
用来区分当前快捷方式是否激活,值为false表示当前条目失效,
值为true表示当前条目激活;失效的时候依次类推
android:icon用来指定条目的图标
android:shortcutId用来指定条目的唯一识别名
android:shortcutLongLabel用来指定条目的长标签
android:shortcutShortLabel用来指定条目短标签
android:shortcutDisabledMessage用来指定条目未被激活时条目被点击时候的弹出信息
-->
<shortcut
android:enabled="true"
android:icon="@drawable/ic_first"
android:shortcutDisabledMessage="@string/first_disable_message"
android:shortcutId="first"
android:shortcutLongLabel="@string/first_long_label"
android:shortcutShortLabel="@string/first_short_label">
<!--
android:action指定开启Activity的意图
android:targetClass指定条目的目标类名
android:targetPackage必须是当前应用的包名,否则会提示“未安装该应用”
-->
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.FirstStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
<!--此处可填可不填,默认即可-->
<categories android:name="android.shortcut.conversation"/>
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_second"
android:shortcutDisabledMessage="@string/second_disable_message"
android:shortcutId="second"
android:shortcutLongLabel="@string/second_long_label"
android:shortcutShortLabel="@string/second_short_label">
<!--类似栈算法由上到下-->
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.SecondStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
<!--点击此条目时首先显示的是MainActivity,其次才是SecondStaticActivity-->
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.MainActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_third"
android:shortcutDisabledMessage="@string/third_disable_message"
android:shortcutId="third"
android:shortcutLongLabel="@string/third_long_label"
android:shortcutShortLabel="@string/third_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.ThirdStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_forth"
android:shortcutDisabledMessage="@string/forth_disable_message"
android:shortcutId="forth"
android:shortcutLongLabel="@string/forth_long_label"
android:shortcutShortLabel="@string/forth_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.ForthStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
</shortcut>
<!--从此处开始以下的shortcut都不会显示-->
<shortcut
android:enabled="true"
android:icon="@drawable/ic_fifth"
android:shortcutDisabledMessage="@string/fifth_disable_message"
android:shortcutId="fifth"
android:shortcutLongLabel="@string/fifth_long_label"
android:shortcutShortLabel="@string/fifth_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.FifthStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_sixth"
android:shortcutDisabledMessage="@string/sixth_disable_message"
android:shortcutId="sixth"
android:shortcutLongLabel="@string/sixth_long_label"
android:shortcutShortLabel="@string/sixth_short_label">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.study.yang.staticshortcutsdemo.static_short.SixthStaticActivity"
android:targetPackage="com.study.yang.staticshortcutsdemo" />
</shortcut>
</shortcuts>
1.2 在清单文件中使用shortcuts.xml文件
Shortcuts.xml文件必须在带有如下标签的内容的activity标签中使用,具体使用如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.study.yang.staticshortcutsdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!--
静态注册
shortcuts.xml文件必须注册在应用的启动Activity下面
-->
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
</activity>
<activity android:name=".static_short.FirstStaticActivity" />
<activity android:name=".static_short.SecondStaticActivity" />
<activity android:name=".static_short.ThirdStaticActivity" />
<activity android:name=".static_short.ForthStaticActivity" />
<activity android:name=".static_short.FifthStaticActivity" />
<activity android:name=".static_short.SixthStaticActivity"></activity>
</application>
</manifest>
最终效果图如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/1aae59afe1d58e322c5852d486befce1.jpeg)
二、动态使用shortcuts
在正式的使用中我们还是用动态比较好,因为其可配置。动态使用shortcuts的核心类就是ShortcutManager,由其进行shortcuts的添加、修改、删除的操作。
2.1 添加shortcuts
此处的代码实现如下所示:
/**
* 动态添加Shortcuts应用
*/
private void addDynamicShortcuts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
mShortcutManager = (ShortcutManager) getSystemService(SHORTCUT_SERVICE);
//返回至是4
int maxShortcutCountPerActivity = mShortcutManager.getMaxShortcutCountPerActivity();
List<ShortcutInfo> infos = new ArrayList<>();
for (int i = 0; i < maxShortcutCountPerActivity; i++) {
Intent intent = new Intent(this, MessageActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra("message", "我和好汉" + mAdapter.getItem(i) + "的切磋");
ShortcutInfo info = new ShortcutInfo
//添加shortcuts条目的唯一id
.Builder(this, "id" + i)
//给条目添加短标签
.setShortLabel(mAdapter.getItem(i))
//给条目添加长标签
.setLongLabel("水浒好汉:" + mAdapter.getItem(i))
//给条目设置图标
.setIcon(Icon.createWithResource(this, R.drawable.ic_first))
//设置点击条目之后要触发的intent
.setIntent(intent)
.build();
infos.add(info);
}
mShortcutManager.addDynamicShortcuts(infos);
}
}
效果图如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/3e4c93679cca196af9cf0dfeeb3b4d10.jpeg)
2.2 修改shortcuts
此处的代码实现如下所示:
//给ListView添加单击事件进行修改shortcut
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
data.add(0, "刘备、张飞、关羽");
mAdapter.notifyDataSetChanged();
updateShortcut(position);
}
});
/**
* 更新Shortcut
* @param index
*/
@TargetApi(Build.VERSION_CODES.N_MR1)
private void updateShortcut(int index) {
Intent intent = new Intent(this, MessageActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra("message", "我和好汉" + mAdapter.getItem(index) + "的切磋");
ShortcutInfo info = new ShortcutInfo
//给指定的id重新赋值内容
.Builder(this, "id" + index)
.setShortLabel(mAdapter.getItem(index))
.setLongLabel("水浒好汉:" + mAdapter.getItem(index))
.setIcon(Icon.createWithResource(this, R.drawable.ic_first))
//此处可以添加多个intent
.setIntents(new Intent[]{intent, new Intent("android.intent.action.MAIN", null, this, MainActivity.class)})
.setDisabledMessage("好汉失效了")
.build();
//更新
mShortcutManager.updateShortcuts(Arrays.asList(info));
}
效果图如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/a399fafecda14557cde61b01fe06e97f.jpeg)
2.3 删除shortcuts
此处的代码实现如下所示:
//给ListView添加长按事件进行删除shortcut
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(MainActivity.this, data.get(position) + "陨落了", Toast.LENGTH_SHORT).show();
removeShortcut(position);
return false;
}
});
/**
* 移除Shortcut
*
* @param
*/
@TargetApi(Build.VERSION_CODES.N_MR1)
private void removeShortcut(int index) {
//获取已有快捷条目
List<ShortcutInfo> infos = mShortcutManager.getPinnedShortcuts();
for (ShortcutInfo info : infos) {
if (info.getId().equals("id" + index)) {
//使得标签失效
mShortcutManager.disableShortcuts(Arrays.asList(info.getId()), "好汉陨落了");
}
}
//通过标签id移除指定标签
mShortcutManager.removeDynamicShortcuts(Arrays.asList("id" + index));
}
效果图如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/6ce597b8521d43be32bb6492f69e9c18.jpeg)
shortcut被设置为不可用之后,其移植在桌面上的快捷方式将会变成灰色。