如何收听已选择哪个应用程序作为启动器应用程序?

xin*_*aiz 13 android callback android-intent kotlin android-launcher

我尝试实现一种功能,允许用户选择默认的Android默认启动器应用程序.此外,我需要接收选择了哪个应用程序的信息.但这种方法存在问题.

要让用户选择Launcher Application,我们可以简单地启动给定的intent:

val selector = Intent(Intent.ACTION_MAIN)
selector.addCategory(Intent.CATEGORY_HOME)
selector.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(selector)
Run Code Online (Sandbox Code Playgroud)

它导致这样的对话:

在此输入图像描述

我观察到的,如果我使用startActivity,Launcher应用程序设置很好并按预期工作,但如果我使用startActivityForResult,那么我将得到一些回调,但Launcher应用程序根本不会设置.此外,收到的意图并没有什么有趣的onActivityResult.

然后,我尝试使用IntentSender.

代码如下:

val selector = Intent(Intent.ACTION_MAIN)
selector.addCategory(Intent.CATEGORY_HOME)
selector.flags = Intent.FLAG_ACTIVITY_NEW_TASK
val receiver = Intent(this, MyBroadcastReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this, 0, receiver, PendingIntent.FLAG_UPDATE_CURRENT)
val chooser = Intent.createChooser(selector, "Select a Home app", pendingIntent.intentSender);
startActivity(chooser)
Run Code Online (Sandbox Code Playgroud)

接收器如下:

class MyBroadcastReceiver: BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val componentName = intent.extras.getParcelable<ComponentName>(Intent.EXTRA_CHOSEN_COMPONENT)
        //com.example.myapp if my app was choosen
        val pkg = componentName.packageName
    }
}
Run Code Online (Sandbox Code Playgroud)

这导致默认选择器,没有选项"JUST ONCE"或"ALWAYS".我没有确切的图片,但看起来与此类似:

在此输入图像描述

在某种程度上起作用,在接收者的onReceive方法中我得到了ComponenName对象,它保存了所选的应用程序packageName.问题是 - 再次 - Launcher应用程序未设置!

所以问题是:我如何让用户设置启动器应用程序,并接收他选择的信息?

aan*_*shu 7

尝试使用以下代码:

PackageManager localPackageManager = getPackageManager();
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
String launcherName = localPackageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY).activityInfo.packageName;
Log.e("Current launcher Package Name:",launcherName);
Run Code Online (Sandbox Code Playgroud)

  • 我最终将我的应用程序声明为`android:launchMode ="singleTask"`.通过这种方式,我可以检测到我的应用程序和另一个应用程序之间的变化 - 如果我选择我的应用程序作为启动程序,应用程序将重新启动因为`singleTask`,并且在`onResume`中我可以使用您的方法(或任何方法)检测如果我的应用程序是启动器.同样,当我的应用程序*是*家庭应用程序,我选择另一个应用程序时,我的应用程序将关闭,因为主应用程序更改.当我再次打开应用程序(通过图标),再次在`onResume`中,我检查我的应用程序是否是启动器.它远非我想要的完美,但我最终得到了这样的解决方案. (2认同)

tyn*_*ynn 6

有了getPreferredActivities()你可以检索其用户首选的所有活动.这应包括发射器.

然后你可以尝试实现一个getPreferredLauncher()函数来获取当前值Launcher.但由于无法监听此更改,因此您必须主动在一个Service或每当您认为数据可能已更改时进行查询:

fun PackageManager.getPreferredLauncher(): ComponentName? {
    val filters = mutableListOf<IntentFilter>()
    val components = mutableListOf<ComponentName>()
    getPreferredActivities(filters, components, null)
    filters.forEachIndexed { (i, it) ->
        if (it.hasAction(ACTION_MAIN) && it.hasCategory(CATEGORY_LAUNCHER))
            return@getPreferredLauncher components[i]
    }
    return null
}
Run Code Online (Sandbox Code Playgroud)

请将此代码仅视为草稿,因为我没有任何设置来实际运行它.