APP & program

Android 在手机桌面上创建应用快捷方式图标

2022-04-08  本文已影响0人  清朝公主大清正黄旗

一、目标结果:在手机桌面上生成一个和普通应用图标一样的图标,然后用户点击这个图标时,进入对应的应用中(当然你也可以给这个图标点击进入其他的app,主要根据你设置的包名而定)

知道了需求,现在直接上代码,也可以看官网说明:<a href="https://developer.android.google.cn/guide/topics/ui/shortcuts/creating-shortcuts?hl=zh-cn">创建快捷方式</a>

二、下面我直接把代码贴出来,用作记录,以备后用

    /**
     * 添加桌面快捷方式
     */
    @Throws(Exception::class)
    fun addShortcut(context: Context, build: AppInfoBean,id:String): String {
        val enter = getAppEnter(context,build.appPackageName)
        val uuid = id

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) {
                //构建点击intent
                val shortcutInfoIntent = Intent().apply {
                    action = Intent.ACTION_VIEW
                    setClassName(build.appPackageName, enter)
                    addCategory(Intent.CATEGORY_LAUNCHER)
                    flags = Intent.FLAG_ACTIVITY_NEW_TASK
                    putExtra("duplicate", false)//不允许重复创建
                }
                //构建快捷方式信息
                val pinShortcutInfo = ShortcutInfoCompat.Builder(context, uuid)
                    .setShortLabel(build.appName)
                    .setActivity(ComponentName(context, IconNUllActivity::class.java))
                    .setIcon(IconCompat.createWithBitmap(AppComUtil.drawableToBitmap(build.icon)))
                    .setIntent(shortcutInfoIntent)
                    .build()
                //回调intent
                val successCallback = PendingIntent.getBroadcast(
                    context, 1000, Intent(context, IconAddCallbackReceiver::class.java),
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
                //添加
                ShortcutManagerCompat.requestPinShortcut(
                    context,
                    pinShortcutInfo,
                    successCallback.intentSender
                )
            }
        } else {
            //构建点击intent
            val shortcutInfoIntent = Intent().apply {
                action = Intent.ACTION_VIEW
                setClassName(build.appPackageName.toString(), enter)
                addCategory(Intent.CATEGORY_LAUNCHER)
                putExtra("duplicate", false)//不允许重复创建
                //设置点击快捷方式,进入指定的Activity
                //注意:因为是从Lanucher中启动,所以这里用到了ComponentName
                //其中new ComponentName这里的第二个参数,是Activity的全路径名,也就是包名类名要写全。
                component = ComponentName(build.appPackageName.toString(), enter)
                flags = Intent.FLAG_ACTIVITY_NEW_TASK
            }

            //给Intent添加 对应的flag
            val resultIntent = Intent().apply {
                // Intent.ShortcutIconResource.fromContext 这个就是设置快捷方式的图标
                putExtra(Intent.EXTRA_SHORTCUT_ICON, AppComUtil.drawableToBitmap(build.icon))
                //启动的Intent
                putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutInfoIntent)
                //这里可以设置快捷方式的名称
                putExtra(Intent.EXTRA_SHORTCUT_NAME, build.appName.toString())
                //设置Action
                action = "com.android.launcher.action.INSTALL_SHORTCUT"
            }

            //发送广播、通知系统创建桌面快捷方式
            context.sendBroadcast(resultIntent)
        }
        return ""
    }

三、说明:
1、AppInfoBean 为需要创建的应用实体bean,包含应用的名称,应用的包名,已经应用的icon 在获取应用icon时,一般是Drawable 类型,
2、getAppEnter(context,build.appPackageName) 这个方法是通过包名,获取应用的启动页Activity的全包名路下面会给出代码
3、参数id 其实就是在创建每个快捷方式时,需要给每个快捷方式一个id 这里随便生成一个uuid 你可以在应用实体类中给每个应用先生成一个id 确保id唯一,因为同一个id,在桌面上只能生成一个快捷方式
4、IconNUllActivity 这是创建的一个空白的activity,里面啥也没有,用来在Manifest.xml中配置,处理快捷方式生成时,图标右下角有当前应用的标志问题,下面也会给出配置
5、AppComUtil.drawableToBitmap(build.icon) 这个简单,就是把Drawable 图 转成bitmap
6、IconAddCallbackReceiver 是一个注册在Manifest.xml的 广播,里面没什么东西,只在广播的onReceive 中打印log 接收当一个快捷方式创建完成后,会在这里提示,创建一个,会有一个广告接收。你可以在这里处理其他的逻辑

四、基本都在这里了,下面在给出上面的部分缺少的内容
,实体bean自己创建,不给了,
getAppEnter方法:

    /**
     * 通过包名获取app的入口activity
     */
    @SuppressLint("WrongConstant")
    fun getAppEnter(context: Context, packageName: String): String {
        var mainAct = ""
        try {
            val intent = Intent().apply {
                action = Intent.ACTION_MAIN
                addCategory(Intent.CATEGORY_LAUNCHER)
            }
            val list =
                context.packageManager.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES)

            list.forEach {
                if (TextUtils.equals(it.activityInfo.packageName, packageName)) {
                    mainAct = it.activityInfo.name
                }
            }
        } catch (ex: Exception) {

        } finally {
            return mainAct
        }
    }

五、IconNUllActivity 在Manifest.xml 的配置信息

<activity
            android:name=".ui.activity.IconLucencyActivity"
            android:configChanges="keyboardHidden|orientation|screenSize|uiMode"
            android:excludeFromRecents="true"
            android:exported="true"
            android:icon="@drawable/bg_transparent"
            android:label="@string/app_name"
            android:launchMode="singleInstance"
            android:noHistory="true"
            android:roundIcon="@drawable/bg_transparent"
            android:theme="@android:style/Theme.Translucent">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

bg_transparent这个是自定义的一个全透明的drawable 自己看着写

到这里就结束了。

上一篇下一篇

猜你喜欢

热点阅读