这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
兼容使用应用快捷方式
- 需要申请权限
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
- 在国产rom中可能默认是关闭该权限设置无法动态申请,需要用户自行在系统设置中打开。
旧版本实现(7.0及以下)
public static final String ACTION_ADD_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";
public void addShortcutBelowAndroidN(Context context) {
Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);
// 不允许重复创建,不是根据快捷方式的名字判断重复的
addShortcutIntent.putExtra("duplicate", false);
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Shortcut Name");
//图标
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.mipmap.ic_shortcut));
// 设置关联程序
Intent launcherIntent = new Intent();
launcherIntent.setClass(context, ShortcutActivity.class);
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);
// 发送广播
context.sendBroadcast(addShortcutIntent);
}
高版本实现
Android8.0
出于安全考虑,废弃了添加快捷方式的旧方法不再使用广播通知的形式,取而代之新增了ShortcutManager
管理类,通过ShortCutManager去创建快捷入口。用户可以在应用内添加快捷方式,不需要微件面板去实现。
- 动态注册方式实现:
public static void addShortCut(Context context) {
ShortcutManager shortcutManager = (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
if(shortcutManager.isRequestPinShortcutSupported()) {
Intent shortcutInfoIntent = new Intent(context, ShortcutActivity.class);
shortcutInfoIntent.setAction(Intent.ACTION_VIEW);
ShortcutInfo info = new ShortcutInfo.Builder(context, "The only id")
.setIcon(Icon.createWithResources(context, R.mipmap.ic_shortcut))
.setShortLabel("Short Label")
.setIntent(shortcutInfoIntent);
.build();
//当添加快捷方式的确认弹框弹出来时,将被回调
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
shortcutManager.requestPinShortcut(info, shortcutCallbackIntent.getIntentSender());
}
}
- XML注册方式
在
res/xml
目录下创建新xml
文件,如下所示
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="setting"
android:enabled="true"
android:icon="@drawable/demo"
android:shortcutShortLabel="@string/shortcutShortLabel"
android:shortcutLongLabel="@string/shortcutLongLabel"
android:shortcutDisabledMessage="@string/shortcutDisabledMessage">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.demo.shortcut"
android:targetClass="com.demo.shortcut.DemoTargetActivity" />
<categories android:name="android.shortcut.conversation"/>
</shortcut>
</shortcuts>
实现xml
文件之后在清单文件下启动Activity
下面配置注册实现。
<activity
android:launchMode="singleInstance"
android:name=".MainActivity"
android:excludeFromRecents="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
/// 必须加上这个。否则无法直接使用自定的action
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
/// 在这下注册实现
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcut"/>
</activity>
兼容方法
同时官方还提供出一个兼容高低API的方法。
public static void addShortCutCompact(Context context) {
if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) {
Intent shortcutInfoIntent = new Intent(context, ShortcutActivity.class);
shortcutInfoIntent.setAction(Intent.ACTION_VIEW); //action必须设置,不然报错
ShortcutInfoCompat info = new ShortcutInfoCompat.Builder(context, "The only id") // 配置ID
.setIcon(R.mipmap.ic_shortcut) //图标显示
.setShortLabel("Short Label") //短标题
.setLongLabel("Long Label") //长标题
.setIntent(shortcutInfoIntent) // 跳转逻辑
.build();
//当添加快捷方式的确认弹框弹出来时,将被回调
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
ShortcutManagerCompat.requestPinShortcut(context, info, shortcutCallbackIntent.getIntentSender());
}
}
其他问题
- 通过小米9.0手机、谷歌9.0Nexus、oppo5.1手机测试发现谷歌原生系统在添加快捷方式会出现原生提示弹窗来告知用户是否允许添加,而在国产rom手机上并没有而是直接生效。
- 另外在原生手机中多次添加会在桌面生成重复同样的桌面快捷方式,我也找到了办法来避免这种情况。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
ShortcutManager shortcutManager = (ShortcutManagecontext.getSystemService(Context.SHORTCUT_SERVICE);
List<ShortcutInfo> shortcutInfos = shortcutManager.getPinnedShortc();
for(ShortcutInfo shortcutInfo : shortcutInfos){
if(TextUtils.equals(shortcutInfo.getId(),"speech_cut")){
return;
}else{
continue;
}
}
createShortCut(context);
}