Как я могу прослушать, какое приложение было выбрано в качестве приложения для запуска?

Я попытался реализовать функциональность, которая позволяет пользователю выбирать приложение запуска Android по умолчанию по умолчанию. Также мне нужно получить информацию о том, какое приложение было выбрано. Но у такого подхода есть проблема.

Чтобы позволить пользователю выбрать приложение запуска, мы можем просто запустить данное намерение:

val selector = Intent(Intent.ACTION_MAIN)
selector.addCategory(Intent.CATEGORY_HOME)
selector.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(selector)

В результате получается такой диалог:

Как я могу прослушать, какое приложение было выбрано в качестве приложения для запуска?

Я заметил, что если я использую startActivity, приложение-пусковая установка настроено правильно и работает по назначению, но если я использую startActivityForResult, я получу обратный вызов, но приложение-пусковая установка вообще не будет установлено. Также в 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)

Ресивер выглядит следующим образом:

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
    }
}

Это приводит к выбору по умолчанию без опций «ТОЛЬКО РАЗ» или «ВСЕГДА». У меня нет точной картины, но она похожа на эту:

Как я могу прослушать, какое приложение было выбрано в качестве приложения для запуска?

Это работает в некотором роде, в методе onReceive приемника я получаю объект ComponenName, который содержит выбранное приложение packageName. Проблема в том, что - опять же - Launcher Application не установлен!

Итак, вопрос: как я могу позволить пользователю установить приложение запуска, а также получать информацию, которое он выбрал?

13
0
665
2

Ответы 2

Попробуйте использовать следующий код:

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);

Где мне его использовать?

xinaiz 29.10.2018 09:53

Вы можете использовать его в методе onResume, откуда вы запускаете это намерение

aanshu 29.10.2018 09:57

Но мне нужно, чтобы пользователь сначала выбрал приложение, если я вызову его сразу после создания селектора, это будет информация о старом домашнем приложении.

xinaiz 29.10.2018 09:59

вы пробовали метод onResume? Я считаю, что это сработает, так как вы будете менять средство запуска через другое приложение, после того, как средство запуска будет изменено, оно вернется в наше приложение и вызовет метод onResume действия, из которого вы запустили намерение. Поправьте / объясните мне, если я не понимаю вашу боль.

aanshu 29.10.2018 10:08

Я получаю Current launcher Package Name: android, независимо от того, установлено ли мое приложение как домашнее или встроенное.

xinaiz 29.10.2018 10:16

ты тестируешь на эмуляторе?

aanshu 29.10.2018 10:20

Если нет выбранной пусковой установки «по умолчанию», возвращается просто «android». Не частый случай, но бывает.

aanshu 29.10.2018 10:21

Да тестирую на эмуляторе

xinaiz 29.10.2018 10:27

протестируйте его на реальном устройстве и обратите внимание, что он вернет "android" для пусковой установки по умолчанию.

aanshu 29.10.2018 10:29

В некоторой степени, но, к сожалению, метод onResume не вызывается, когда я выбираю приложение, отличное от текущего.

xinaiz 29.10.2018 11:11

используйте startActivityForResult, затем

aanshu 29.10.2018 11:15

Пожалуйста, дайте мне знать, сработало ли это? Если нет, хотел бы помочь с альтернативами

aanshu 03.11.2018 19:52

В итоге я объявил свое приложение как android:launchMode = "singleTask". Таким образом, я могу обнаружить изменение между моим приложением и другим приложением - если я выберу свое приложение в качестве средства запуска, приложение перезапустится из-за singleTask, а в onResume я могу определить с помощью вашего метода (или любого другого метода на этом этапе), если мой приложение является пусковой установкой. Точно так же, когда мое приложение было home app, и я выбираю другое приложение, мое приложение закроется, потому что домашнее приложение изменится. Когда я снова открываю приложение (через значок), снова в onResume я проверяю, является ли мое приложение средством запуска. Это далеко не идеально для того, что я хотел, но я нашел такое решение.

xinaiz 03.11.2018 20:14

Будет ли это возможно для вас, если вы сможете отредактировать ответ и пометить как ответ правильное решение, которое вы нашли для организации публикации.

aanshu 04.11.2018 08:39

Боюсь, моя реализация - не решение вопроса. Исходный вопрос требовал прислушиваться к изменению после того, как оно произошло, и это не тот случай, который я описал в моем предыдущем комментарии. Это всего лишь обходной путь, который точно соответствует тому, что я должен был реализовать.

xinaiz 04.11.2018 10:32

С помощью 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
}

Считайте этот код только черновиком, так как у меня не было никаких настроек для его запуска.

Спасибо за Ваш ответ. Это работает, как задумано, но проблема в том, как прислушиваться к фактическим изменениям.

xinaiz 04.11.2018 10:44

Как я уже сказал, на самом деле нет никакого способа прислушаться к этой информации. Таким образом, вам нужно время от времени запрашивать его из службы или в рамках вашей деятельности.

tynn 04.11.2018 14:02

Другие вопросы по теме