Android ShortCut快捷方式的创建/删除和判断

ShortCut 快捷方式的创建和判断

一、相关介绍

1. 快捷方式的创建、删除通过广播实现
2. 也就是要传一个intent
3. 接受intent的这个广播接收器负责把intent传的数据写入到launcher的favorite表
4. 系统是根据favorite生成桌面的快捷方式的
5. 抽屉,这个基本只有在原生的系统有的一个控件,里面罗列所有安装的appIcon

launcher数据库

本来呢,如果是原生的桌面,其实是十分简单,直接调用系统相关的API就行了。但是众多的系统厂商以及众多第三方自己定制的桌面(Launcher,launcher数据库路径不一致, 修改favorite的字段),导致在适配、兼容方面存在很多问题。
比如,有些桌面无法删除快捷方式(比如小米),有些桌面无法生成快捷方式(比如锤子),有些系统无法更新桌面图标(比如华为荣耀6)。
在升级、降级的时候快捷方式发生变化;比如,全部变成应用的主图标,升级、降级后点击快捷方式没有反应,删除应用后无法删除快捷方式。
很多问题都是需要解决的,虽然有些由于系统限制,没有办法搞定所有的,但是仍然需要寻求一个最优的方案。

二、实现

1、增加快捷方式

在AndroidManifest.xml增加权限:

<uses-permissionandroid:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

在部分手机中发现需要添加一下filter到activity中,才能创建快捷方式:

<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT"/>
</intent-filter>

同时,如果Intent是隐式,需要在Activity声明相关的intent-filter。
相关代码:

/**
* 创建应用入口的快捷方式
*/

public static boolean createAppShortcut(Context context, Class<?> cls, String shortCutName, int shortIconId) {

    boolean isShortCutExist = isShortCutExist(context, shortCutName);
    if (!isShortCutExist) {
        Intent intent = new Intent(ACTION_INSTALL_SHORTCUT);
        final Intent launchIntent = new Intent(context, cls);
        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        launchIntent.putExtra(ACTION_INTENT, shortCutName);
        Parcelable icon = Intent.ShortcutIconResource.fromContext(
                context.getApplicationContext(), shortIconId);
        intent.putExtra("duplicate", false);            // 不允许重复创建
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortCutName);    // 快捷方式的标题
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);   // 快捷方式的图片
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);  // 快捷方式的运行程序主入口
        context.sendBroadcast(intent);
    }
    return isShortCutExist;
} `
2、删除快捷方式

跟增加快捷方式一样,也是需要增加权限:


<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

相关代码:


/**
* 删除快捷方式 不一定能成功
* @param context
* @param cls
* @param shortCutName
*/

public static void delShortcut(Context context, Class<?> cls, String shortCutName) {

    boolean isShortCutExist = isShortCutExist(context, shortCutName);
    if (isShortCutExist) {
        Intent intent = new Intent(ACTION_UNINSTALL_SHORTCUT);
        final Intent launchIntent = new Intent(context, cls);
        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        launchIntent.putExtra(ACTION_INTENT, shortCutName);
        intent.putExtra("duplicate", false);            // 为true是循环删除快捷方式
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortCutName);    // 快捷方式的标题
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);  // 快捷方式的运行程序主入口
        context.sendBroadcast(intent);
    }
}

`

3、快捷方式的存在判断

需要增加的权限:


<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />

虽然说通过SharePreference来保证快捷方式不会重复创建,以及通过shortcutIntent.putExtra(“duplicate”, false)也可以确保,但是为了万无一失,还是可以通过去查询数据判断快捷方式是否存在,来避免重复创建。(用户清除应用数据后,不会删除快捷方式)


/**
* 检查快捷方式是否存在 <br/>
* <font color=red>注意:</font> 有些手机无法判断是否已经创建过快捷方式<br/>
* 因此,在创建快捷方式时,请添加<br/>
* shortcutIntent.putExtra("duplicate", false);// 不允许重复创建<br/>
* 最好使用{@link #isShortCutExist(Context, String, Intent)}
* 进行判断,因为可能有些应用生成的快捷方式名称是一样的的<br/>
* 此处需要在AndroidManifest.xml中配置相关的桌面权限信息<br/>
* 错误信息已捕获<br/>
*/

public static boolean isShortCutExist(Context context, String title) {

    boolean result = false;
    try {
        final ContentResolver cr = context.getContentResolver();
        StringBuilder uriStr = new StringBuilder();
        String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);
        if(authority==null||authority.trim().equals("")){
            authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");
        }
        uriStr.append("content://");
        if (TextUtils.isEmpty(authority)) {
            int sdkInt = android.os.Build.VERSION.SDK_INT;
            if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
                uriStr.append("com.android.launcher.settings");
            } else if (sdkInt < 19) {// Android 4.4以下
                uriStr.append("com.android.launcher2.settings");
            } else {// 4.4以及以上
                uriStr.append("com.android.launcher3.settings");
            }
        } else {
            Log.d("ShortcutUtil", "authority=" + authority);
            uriStr.append(authority);
        }
        uriStr.append("/favorites?notify=true");
        Uri uri = Uri.parse(uriStr.toString());
        Cursor c = cr.query(uri, null,
                "title=? ",
                new String[] { title }, null);
        if (c != null && c.getCount() > 0) {
            result = true;
        }
        if (c != null && !c.isClosed()) {
            c.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
        result=false;
    }
    Log.d("ShortcutUtil", "result isShortCutExist=" + result);
    return result;
}


/**
 * 不一定所有的手机都有效,因为国内大部分手机的桌面不是系统原生的<br/>
 * 更多请参考{@link #isShortCutExist(Context, String)}<br/>
 * 桌面有两种,系统桌面(ROM自带)与第三方桌面,一般只考虑系统自带<br/>
 * 第三方桌面如果没有实现系统响应的方法是无法判断的,比如GO桌面<br/>
 *  此处需要在AndroidManifest.xml中配置相关的桌面权限信息<br/>
 * 错误信息已捕获<br/>
 */
public static boolean isShortCutExist(Context context, String title, Intent intent) {
    boolean result = false;
    try{
        final ContentResolver cr = context.getContentResolver();
        StringBuilder uriStr = new StringBuilder();
        String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);
        if(authority==null||authority.trim().equals("")){
            authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");
        }
        uriStr.append("content://");
        if (TextUtils.isEmpty(authority)) {
            int sdkInt = android.os.Build.VERSION.SDK_INT;
            if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
                uriStr.append("com.android.launcher.settings");
            } else if (sdkInt < 19) {// Android 4.4以下
                uriStr.append("com.android.launcher2.settings");
            } else {// 4.4以及以上
                uriStr.append("com.android.launcher3.settings");
            }
        } else {
            uriStr.append(authority);
        }
        uriStr.append("/favorites?notify=true");
        Uri uri = Uri.parse(uriStr.toString());
        Cursor c = cr.query(uri, new String[] { "title", "intent" },
                "title=?  and intent=?",
                new String[] { title, intent.toUri(0) }, null);
        if (c != null && c.getCount() > 0) {
            result = true;
        }
        if (c != null && !c.isClosed()) {
            c.close();
        }
    }catch(Exception ex){
        result=false;
        ex.printStackTrace();
    }
    return result;
}
`

注意事项

因为国内rom改的太多,如需适配更多机型需要添加各个launcher的包名对应权限:


<uses-permission android:name="com.google.android.apps.nexuslauncher.permission.READ_SETTINGS"/>
<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="org.adw.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.qihoo360.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="net.qihoo.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="org.adwfreak.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="org.adw.launcher_donut.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.launcher3.permission.READ_SETTINGS" />
<uses-permission android:name="com.fede.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS" />
<uses-permission android:name="com.anddoes.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.tencent.qqlauncher.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.launcher2.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.mylauncher.permission.READ_SETTINGS" />
<uses-permission android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.lenovo.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.bbk.launcher2.permission.READ_SETTINGS" />
<uses-permission android:name="cn.nubia.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="cn.nubia.launcher.permission.WRITE_SETTINGS" />
<uses-permission android:name="cn.nubia.launcher2.permission.READ_SETTINGS" />
<uses-permission android:name="cn.nubia.launcher2.permission.WRITE_SETTINGS" />
<uses-permission android:name="net.oneplus.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="net.oneplus.launcher.permission.WRITE_SETTINGS" />

具体代码:https://github.com/AriesJiang/AriesDemo/tree/master/app/src/main/java/com/niqiu/shortcut

代码参考:https://gist.github.com/waylife/437a3d98a84f245b9582

以下是 Android 动态创建快捷方式的步骤: 1. 首先,您需要在 AndroidManifest.xml 文件中声明您的快捷方式。在应用程序的 <application> 标记内部,添加以下内容: ```xml <activity android:name=".MyShortcutActivity" android:label="@string/shortcut_label"> <intent-filter> <action android:name="android.intent.action.CREATE_SHORTCUT" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> ``` 2. 创建一个新的 Activity 类 MyShortcutActivity,该类将处理创建快捷方式的请求。在 onCreate() 方法中,您可以设置快捷方式的属性,例如快捷方式 ID、快捷方式标签和快捷方式图标。 ```java public class MyShortcutActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置快捷方式 ID 和标签 String shortcutId = "my_shortcut"; String shortcutLabel = "My Shortcut"; // 创建快捷方式意图 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW); shortcutIntent.setClassName(this, MainActivity.class.getName()); // 创建快捷方式 ShortcutInfo shortcut = new ShortcutInfo.Builder(this, shortcutId) .setShortLabel(shortcutLabel) .setIcon(Icon.createWithResource(this, R.drawable.shortcut_icon)) .setIntent(shortcutIntent) .build(); // 添加快捷方式 ShortcutManager shortcutManager = getSystemService(ShortcutManager.class); shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut)); // 结束 Activity finish(); } } ``` 3. 在您的应用程序中,您可以通过调用 ShortcutManager 的 setDynamicShortcuts() 方法来添加动态快捷方式。在这个例子中,我们只添加了一个快捷方式,但您可以添加多个快捷方式。 ```java ShortcutManager shortcutManager = getSystemService(ShortcutManager.class); shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut)); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值