Java 使用意图选择HomeLauncher应用程序

Java 使用意图选择HomeLauncher应用程序,java,android,android-intent,launcher,homescreen,Java,Android,Android Intent,Launcher,Homescreen,我正在编写一个Android应用程序,其中包含一个活动,当启用该活动时,该活动应充当home launcher活动。 为此,我在调用startActivityForResult之前启用活动,并将CATEGORY\u HOME作为意图类别,以启用选择活动作为主页启动器活动。选择“仅在启用时启用主密钥启动”后,该活动将被禁用 我的问题是,当出现提示要求用户选择启动器活动,并且用户选择默认主活动而不是自定义启动器活动时,后续选择器意图失败,只会显示主屏幕 以下是启动启动器活动选择器的代码: Packa

我正在编写一个Android应用程序,其中包含一个活动,当启用该活动时,该活动应充当home launcher活动。 为此,我在调用startActivityForResult之前启用活动,并将
CATEGORY\u 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);
当显示launcher选择器并且用户选择设备的默认launcher活动而不是自定义launcher时,“我的应用”将最小化,并显示主屏幕。重新进入应用程序并重复选择器过程会导致启动器选择器不再显示,而是显示主屏幕


有解决办法吗?如何从用户选择错误的home launcher活动中恢复?

我找到了问题的解决方案。我将上述代码替换为以下代码:

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\u ACTIVITY\u NEW\u TASK
FLAG\u ACTIVITY\u SINGLE\u TOP
)以及将
startActivityForResult
更改为简单的“startActivity”

writeSetupFlag
SharedReferences
写入一个标志,指示已显示选择器:

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

因此,我们可以首先检查我们的活动是否设置为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();
现在,如果我们的活动不是主启动器,我们将检查设置标志:

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
   }

因此,通过使用
SharedReferences
中的标志,我们可以从用户在显示选择器时选择错误的home launcher应用程序中恢复

我在我的一个项目中添加了确切的内容。 我在Github上发现了一个开源Android启动器项目,我确信我会在其中找到这个特性

我想直接从我的Android应用程序中启动更改默认Home Launcher应用程序,而不必启动进入设置和更改设置中Home Launcher应用程序的意图。 下图显示了结果:(图片摘自谷歌,用于说明)

这个开源启动器项目的功劳。

从下面的文件中选取工作代码并做了一些修改。

步骤1:创建一个名为
DummyActivity.java的空活动
步骤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>
        <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>
    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);

    }