使用意图选择家庭启动器应用程序

时间:2018-02-21 12:51:55

标签: java android android-intent launcher homescreen

我正在编写一个Android应用,其中包含一项活动,该活动应在启用时充当主启动器活动。 为此,我在调用 startActivityForResult 之前启用活动,并将CATEGORY_HOME作为意图类别,以启用选择活动作为主启动器活动。选择此选项后,活动将被禁用,仅在启用时启用主页启动。

我的问题是当出现询问用户选择启动器活动的提示并且用户选择默认主页活动而不是自定义启动器活动时,后续选择器意图失败并且仅导致显示主屏幕。

以下是启动启动器活动选择器的代码:

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

当显示启动器选择器并且用户选择设备的默认启动器活动而不是自定义启动器时,我的应用程序被最小化并显示主屏幕。重新进入应用程序并重复选择器过程然后导致启动器选择器不再显示,而是显示主屏幕。

有解决方案吗?如何从用户选择不正确的家庭启动器活动中恢复?

2 个答案:

答案 0 :(得分:1)

我找到了问题的解决方案。我用以下内容替换了上面的代码:

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

请注意添加到意图(FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_SINGLE_TOP)的标记以及将startActivityForResult更改为简单的' startActivity'。

writeSetupFlagSharedPreferences写入一个标记,表示选择器已显示:

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

这使我们能够确定之前是否显示过选择器。因此,假设用户在选择过程中选择了错误的家庭活动(即不是我们的活动),将显示主屏幕。重新启动应用程序将触发读取写入的标志,我们可以检测到选择器已显示,但用户选择了错误的启动器。

因此我们可以先检查我们的活动是否设置为主发射器:

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

现在,如果我们的活动不是主发射器,我们检查设置标志:

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
   }

因此,通过使用SharedPreferences中的标志,我们可以在用户选择不正确的主启动器应用程序时从我们显示选择器中恢复。

答案 1 :(得分:0)

我有一个确切的内容要添加到我的一个项目中。 我在Github上找到了一个开源Android启动器项目,并且确定可以在其中找到此功能。

我想要直接从我的Android应用程序中启动“更改默认家庭启动器应用程序”,而无需触发意图进入设置并从“设置”更改“家庭更改启动器应用程序”。 以下图片显示了结果:(从Google提取的图片用作插图)

enter image description here

此开源启动器项目的信用。

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

从后续文件中选择工作代码,并进行了一些修改。 https://github.com/Neamar/KISS/blob/master/app/src/main/java/fr/neamar/kiss/preference/DefaultLauncherPreference.java

步骤1:创建一个名为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 {
}

步骤2:在AndroidManifest.xml文件中添加后续活动

请注意,默认情况下,“活动”处于禁用状态。

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

最后一步:在您的应用中添加以下函数,并在每次单击特定的UI视图/按钮时调用它。

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

    }