I tried to implement a functionality that allows user to pick default Android's default Launcher Application. Also, I need to receive information which application has been chosen. But there is a problem with that approach.
To let user pick Launcher Application, we can simply start given intent:
val selector = Intent(Intent.ACTION_MAIN)
selector.addCategory(Intent.CATEGORY_HOME)
selector.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(selector)
It results in such dialog:
What I observed, if I use startActivity
, the Launcher Application is set nicely and works as intended, but if I use startActivityForResult
, then I will get some callback, but the Launcher Application will not be set at all. Also, there was nothing interesting in intent received in onActivityResult
.
Then, I tried using IntentSender instead.
The code looks as follows:
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)
The receiver looks as follows:
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
}
}
This results in default chooser, without options "JUST ONCE" or "ALWAYS". I don't have exact picture, but it looks similar to this one:
This works in a way, in the receiver's onReceive
method I get ComponenName
object, that holds selected app packageName
. The problem is - again - Launcher Application is not set!
So question is: How can I let user set Launcher Application, and also receive information which one has he chosen?
An app launcher replaces the stock user interface for organizing the home screen and app icons predominantly in the Android world; however, they are also available for jailbroken iPhones (see iPhone jailbreaking and Cydia). See Launchpad and app drawer.
Try using the following code:
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);
With getPreferredActivities()
you can retrieve all activities which are preferred by the user. This should include the launcher as well.
Then you could try to implement a getPreferredLauncher()
function to get the current Launcher
. But since there's no way to listen for this change, you'd have to query it proactively within a Service
or whenever you'd assume the data could have changed:
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
}
Please consider this code a draft only, as I didn't have any setup to actually run it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With