android 接管launcher3桌面快捷方式

时间:2022-01-11 05:25:28

接管Android快捷方式解密

废话不多说,有时候我们想把launcher干掉,用我们自己的app,发现获取不到桌面快捷方式了,原因是你把launcher干掉了,他带着数据也走了,谁叫你把它干掉呢,那就自己搞吧!这只是我的初步判断,刚玩这个,说错了谢谢补充,共同学习。

先从创建快捷方式开始:

权限设置

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

通过广播创建快捷方式

/**
     * 添加快捷方式
     *
     * @param context      context
     * @param actionIntent 要启动的Intent
     * @param name         name
     */
    public static void addShortcut(Context context, Intent actionIntent, String name,
                                   boolean allowRepeat, Bitmap iconBitmap) {
        Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);
        // 是否允许重复创建
        addShortcutIntent.putExtra("duplicate", allowRepeat);
        // 快捷方式的标题
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
        // 快捷方式的图标
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, iconBitmap);
        // 快捷方式的动作
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, actionIntent);
        context.sendBroadcast(addShortcutIntent);
    }

这样发送这个广播就完事了,注册快捷方式网上有很多栗子,其实还有很多规则,我这里重点不是注册快捷方式,既然是发广播我们就把这个广播给劫了。

注册广播

<receiver
    android:name="包名.InstallShortcutReceiver"
    android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
    <intent-filter>
        <action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
    </intent-filter>
</receiver>

接收广播

public void onReceive(Context context, Intent data) {


    Intent launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
    String label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
}}

我们 startActivity( launchIntent);就完事了,其中呢这个data里面还有很多数据我就没写给你们看下launcher源码获取了哪些信息

源码获取data中的数据

 String name = ensureValidName(mContext, launchIntent, label).toString();
            Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
            Intent.ShortcutIconResource iconResource =
                data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);

 try {
                JSONStringer json = new JSONStringer()
                    .object()
                    .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
                    .key(NAME_KEY).value(name);
                if (icon != null) {
                    byte[] iconByteArray = Utilities.flattenBitmap(icon);
                    json = json.key(ICON_KEY).value(
                            Base64.encodeToString(
                                    iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
                }
                if (iconResource != null) {
                    json = json.key(ICON_RESOURCE_NAME_KEY).value(iconResource.resourceName);
                    json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY)
                            .value(iconResource.packageName);
                }
                return json.endObject().toString();
            } catch (JSONException e) {
                Log.d(TAG, "Exception when adding shortcut: " + e);
            }

源码是吧数据拿出来然后转化为字符串存起来。

重点来了

获取到 launchIntent之后你马上回调用
startActivity(launchIntent);
然而你会发现并不是你想象的那样跳转到了你该去的页面,而只是打开了该app
源码中最好跳转的时候加了句

launchInternt.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


这样就能调到如期的页面,可能是我对FLAG不是很熟悉吧,就到这里吧,拜拜。。。