代码之家  ›  专栏  ›  技术社区  ›  IJB

使用意图选择home launcher应用程序

  •  0
  • IJB  · 技术社区  · 7 年前

    我正在编写一个Android应用程序,其中包含一个活动,该活动在启用时应充当home launcher活动。 为此,我在调用之前启用活动 startActivityForResult公司 具有 CATEGORY_HOME 作为意图类别,允许选择活动作为主启动器活动。选择“仅在启用时启用home key launching”后,该活动将被禁用。

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

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

    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 回复  |  直到 7 年前
        1
  •  2
  •   IJB    7 年前

    我找到了这个问题的解决办法。我将上述代码替换为以下代码:

    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_TASK FLAG_ACTIVITY_SINGLE_TOP )以及 startActivityForResult 简单地说是“startActivity”。

    writeSetupFlag 将标志写入 SharedPreferences 指示已显示选择器:

    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
       }
    

    所以通过在 共享引用 当我们显示选择器时,我们可以从用户选择错误的主启动器应用程序中恢复。

        2
  •  0
  •   Dharman Aman Gojariya    4 年前

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

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

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