Я попытался реализовать функциональность, которая позволяет пользователю выбирать приложение запуска 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 не установлен!
Итак, вопрос: как я могу позволить пользователю установить приложение запуска, а также получать информацию, которое он выбрал?
Попробуйте использовать следующий код:
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);
Вы можете использовать его в методе onResume, откуда вы запускаете это намерение
Но мне нужно, чтобы пользователь сначала выбрал приложение, если я вызову его сразу после создания селектора, это будет информация о старом домашнем приложении.
вы пробовали метод onResume? Я считаю, что это сработает, так как вы будете менять средство запуска через другое приложение, после того, как средство запуска будет изменено, оно вернется в наше приложение и вызовет метод onResume действия, из которого вы запустили намерение. Поправьте / объясните мне, если я не понимаю вашу боль.
Я получаю Current launcher Package Name: android, независимо от того, установлено ли мое приложение как домашнее или встроенное.
ты тестируешь на эмуляторе?
Если нет выбранной пусковой установки «по умолчанию», возвращается просто «android». Не частый случай, но бывает.
Да тестирую на эмуляторе
протестируйте его на реальном устройстве и обратите внимание, что он вернет "android" для пусковой установки по умолчанию.
В некоторой степени, но, к сожалению, метод onResume не вызывается, когда я выбираю приложение, отличное от текущего.
используйте startActivityForResult, затем
Пожалуйста, дайте мне знать, сработало ли это? Если нет, хотел бы помочь с альтернативами
В итоге я объявил свое приложение как android:launchMode = "singleTask". Таким образом, я могу обнаружить изменение между моим приложением и другим приложением - если я выберу свое приложение в качестве средства запуска, приложение перезапустится из-за singleTask, а в onResume я могу определить с помощью вашего метода (или любого другого метода на этом этапе), если мой приложение является пусковой установкой. Точно так же, когда мое приложение было home app, и я выбираю другое приложение, мое приложение закроется, потому что домашнее приложение изменится. Когда я снова открываю приложение (через значок), снова в onResume я проверяю, является ли мое приложение средством запуска. Это далеко не идеально для того, что я хотел, но я нашел такое решение.
Будет ли это возможно для вас, если вы сможете отредактировать ответ и пометить как ответ правильное решение, которое вы нашли для организации публикации.
Боюсь, моя реализация - не решение вопроса. Исходный вопрос требовал прислушиваться к изменению после того, как оно произошло, и это не тот случай, который я описал в моем предыдущем комментарии. Это всего лишь обходной путь, который точно соответствует тому, что я должен был реализовать.
С помощью 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
}
Считайте этот код только черновиком, так как у меня не было никаких настроек для его запуска.
Спасибо за Ваш ответ. Это работает, как задумано, но проблема в том, как прислушиваться к фактическим изменениям.
Как я уже сказал, на самом деле нет никакого способа прислушаться к этой информации. Таким образом, вам нужно время от времени запрашивать его из службы или в рамках вашей деятельности.
Где мне его использовать?