IJB
IJB

Reputation: 186

choosing home launcher app using intents

I am writing an Android app which contains an activity that should act as the home launcher activity when enabled. To do this, I enable the activity before calling startActivityForResult with CATEGORY_HOME as an intent category to enable choosing of the activity as the home launcher activity. The activity is then disabled after being selected to enable home-key launching only when enabled.

My problem is when the prompt asking the user to choose the launcher activity appears and the user selects the default home activity instead of the custom launcher activity, subsequent chooser intents fail and only result in the home screen being shown.

Here is the code for starting the launcher activity chooser:

PackageManager pm = getActivity().getPackageManager();
                            pm.setComponentEnabledSetting(new ComponentName(getActivity(), CustomLauncherActivity.class),
                                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
startActivityForResult(i, REQUEST_CODE_ENABLE_HOME_LAUNCHER);

When the launcher chooser is shown and the user selects the device's default launcher activity instead of the custom launcher, my app is minimized and the home screen is shown. Re-entering the app and repeating the chooser process then results in the launcher chooser not being shown again, but the home screen displayed instead.

Is there a solution for this? How is it possible to recover from the user selecting the incorrect home-launcher activity?

Upvotes: 0

Views: 1146

Answers (2)

Rahul Shyokand
Rahul Shyokand

Reputation: 1505

I had the exact thing to Add in one of my projects. I found an open-source Android Launcher project on Github and I was sure I'll find this feature in that.

I wanted the Fire the Change Default Home Launcher App right from my Android Application without having to fire an Intent to got to settings and Change Home Launcher App from Settings. Following Image Shows the result: (Photo picked from Google for Illustration)

enter image description here

Credits to this Open Source Launcher Project.

https://github.com/Neamar/KISS/

Picked Working Code from Following File and did some modifications. https://github.com/Neamar/KISS/blob/master/app/src/main/java/fr/neamar/kiss/preference/DefaultLauncherPreference.java

Step 1: Create An Empty Activity named DummyActivity.java

package com.packagedomain.projectname;

import android.app.Activity;

/**
 * An empty activity used for changing Android's Default Launcher
 */

public class DummyActivity extends Activity {
}

Step 2: Add Following Activity in AndroidManifest.xml File

Note that the Activity is Disabled by default.

        <activity
            android:name=".DummyActivity"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

Final Step: Add the following Function in your app and Call it whenever the specific UI View/Button is clicked.

    public void startChangeDefaultLauncherIntent() {
        // get context (in order to avoid multiple get() calls)
        Context context = getContext();

        // get packet manager
        PackageManager packageManager = context.getPackageManager();
        // get dummyActivity
        ComponentName componentName = new ComponentName(context, DummyActivity.class);
        // enable dummyActivity (it starts disabled in the manifest.xml)
        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);

        // create a new (implicit) intent with MAIN action
        Intent intent = new Intent(Intent.ACTION_MAIN);
        // add HOME category to it
        intent.addCategory(Intent.CATEGORY_HOME);
        // launch intent
        context.startActivity(intent);

        // disable dummyActivity once again
        packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

    }

Upvotes: 0

IJB
IJB

Reputation: 186

I found a solution to the problem. I replaced the code above with the following:

PackageManager pm = getActivity().getPackageManager();
pm.setComponentEnabledSetting(new     ComponentName(getActivity(), CustomLauncherActivity.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

writeSetupFlag(true);
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);

Note the flags added to the intent (FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_SINGLE_TOP) and the changing of startActivityForResult to simply 'startActivity'.

writeSetupFlag writes a flag to SharedPreferences indicating that the chooser was shown:

private void writeSetupFlag(boolean bInSetup) {
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(getString(R.string.setup_flag_active), bInSetup);
    editor.commit();
}

This enables us to determine if the chooser has been shown before. So suppose the user selected the wrong home activity during the choosing process (i.e. not our activity), the home screen will be shown. Re-launching the app will trigger reading of the flag written and we can detect that the chooser was shown, but the user selected the wrong launcher.

So we can first check whether our activity was set as the home launcher:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(context, CustomLauncherActivity.class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_ALL);
pm.setComponentEnabledSetting(new ComponentName(context, CustomLauncherActivity.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
String currentHomePackage = resolveInfo.activityInfo.packageName;
String customlauncherpackage = context.getApplicationContext().getPackageName();

Now if our activity is not the home launcher, we check the setup flag:

if (!currentHomePackage.equals(customlauncherpackage)) {
    boolean bChooserShown;
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
    bChooserShown = sharedPreferences.getBoolean(getString(R.string.setup_flag_active), false);

    if (bChooserShown) {
        //Display a dialog to the user indicating that they selected the wrong launcher before and will have to reset the launcher from settings.
        ... dialog here ...
        //Then redirect to settings
        if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
            Intent i = new Intent(Settings.ACTION_HOME_SETTINGS, null);
            startActivityForResult(i, REQUEST_LAUNCH_HOME_SETTINGS);
        } else {
            Intent i = new Intent(Settings.ACTION_SETTINGS, null);
            startActivityForResult(i, REQUEST_LAUNCH_HOME_SETTINGS);
        }
   }
   else {
       //do chooser process
   }

So by using the flag in SharedPreferences we can recover from the user selecting the incorrect home launcher application when we display a chooser.

Upvotes: 2

Related Questions