【问题标题】:choosing home launcher app using intents使用意图选择家庭启动器应用程序
【发布时间】:2018-08-01 01:33:06
【问题描述】:

我正在编写一个 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);

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

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

【问题讨论】:

    标签: java android android-intent launcher homescreen


    【解决方案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();
    }
    

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

    所以我们可以先检查一下我们的activity是否被设置为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
       }
    

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

    【讨论】:

      【解决方案2】:

      我有确切的东西要添加到我的一个项目中。 我在 Github 上找到了一个开源 Android Launcher 项目,我确信我会在其中找到这个功能。

      我希望直接从我的 Android 应用程序中触发更改默认主页启动器应用程序,而无需触发进入设置的意图并从设置中更改主页启动器应用程序。 下图显示了结果:(从 Google 中挑选的用于插图的照片)

      感谢这个开源启动器项目。

      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 的空 Activity

      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 处于禁用状态。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多