web-dev-qa-db-ja.com

デフォルトのアプリランチャーをプログラムで設定する方法

Googleからダウンロードできるランチャー(キオスク)アプリを作成しています。このアプリケーションを最初にインストールするとき、ユーザーはデフォルトのランチャー(鉱山または在庫)を選択できます。ユーザーがアプリケーションをデフォルトのランチャーにしない場合、これを手動で起動しようとしています。そのダイアログが表示されたら、ユーザーに「一度だけ」ではなく「常に」を選択するように強制します。そうしないと、ダイアログはフレンドリーメッセージで定期的に表示され続けます。これは私がこれまでに試みたことです。

アプリケーションがデフォルトかどうかを確認するメソッドを作成しました

_/**
 * method checks to see if app is currently set as default launcher
 * @return boolean true means currently set as default, otherwise false
 */ 
private boolean isMyAppLauncherDefault() {
    final IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
    filter.addCategory(Intent.CATEGORY_HOME);

    List<IntentFilter> filters = new ArrayList<IntentFilter>();
    filters.add(filter);

    final String myPackageName = getPackageName();
    List<ComponentName> activities = new ArrayList<ComponentName>();
    final PackageManager packageManager = (PackageManager) getPackageManager();

    packageManager.getPreferredActivities(filters, activities, null);

    for (ComponentName activity : activities) {
        if (myPackageName.equals(activity.getPackageName())) {
            return true;
        }
    }
    return false;
}   
_

次に、セレクターを起動しようとします

_/**
 * method starts an intent that will bring up a Prompt for the user
 * to select their default launcher. It comes up each time it is
 * detected that our app is not the default launcher
 */
private void launchAppChooser() {
    Log.d(TAG, "launchAppChooser()");
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}
_

これを行うと、アプリとストックランチャーのどちらかを選択できません。 startActivity(Intent.createChooser(intent, "Please set launcher settings to ALWAYS"));を使用してみましたが、アプリとストックランチャーの間で選択肢がありますが、常にまたは一度だけのオプションはありません。

セレクターを起動する代わりに、このためのカスタムダイアログを作成できますが、デフォルトのアプリランチャーをプログラムで設定する方法を知る必要があります。前もって感謝します!

36

これは実際には少しの回避策で可能です。

Activityというランチャーとして機能する空のFakeLauncherActivityを作成します。 disabledコンポーネントとしてマニフェストに追加します:

_<activity
    Android:name="com.path.to.your.FakeLauncherActivity"
    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>
_

目的のランチャーアクティビティがデフォルトのアクティビティかどうかを確認します(質問のisMyAppLauncherDefault()を使用)。

そうでない場合は、次のような優先ランチャーアクティビティを選択するようユーザーに提案します。

_public static void resetPreferredLauncherAndOpenChooser(Context context) {
    PackageManager packageManager = context.getPackageManager();
    ComponentName componentName = new ComponentName(context, com.path.to.your.FakeLauncherActivity.class);
    packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

    Intent selector = new Intent(Intent.ACTION_MAIN);
    selector.addCategory(Intent.CATEGORY_HOME);
    selector.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(selector);

    packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP);
}
_

このメソッドは、一時的にFakeLauncherActivityを有効にします。これにより、利用可能なランチャーアクティビティのセットが変更され、Androidはデフォルトのランチャーを忘れます。次のように表示されます。

_521-735/system_process I/PackageManager﹕ Result set changed, dropping preferred activity for Intent { act=Android.intent.action.MAIN cat=[Android.intent.category.HOME] flg=0x10000000 } type null
_

...あなたのログに。

メソッドは、インストールされたすべてのランチャーと「常に」/「一度だけ」ボタンを表示できるランチャーインテントを単に開きます。最後に、このメソッドはFakeLauncherActivityを再度無効にして、リストに表示されないようにします。

必要な回数だけ繰り返して、目的のランチャーアクティビティがデフォルトとして設定されている場合にのみユーザーに先を進ませることができます。

60
saschoar

質問のisMyAppLauncherDefault()関数は、何らかの理由で常に機能するとは限りません。このコードは、HOME画面のデフォルトパッケージを決定するのに適している場合があります。

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
String currentHomePackage = resolveInfo.activityInfo.packageName;
8
Zohar

そのダイアログが表示されたら、ユーザーに1回だけではなく常に選択を強制する

おそらくルート化されたデバイスを除き、Androidのセキュリティ上の欠陥を除いて、それは不可能です。

これを行うと、アプリとストックランチャーの選択ができません。

正しい。デフォルトがすでに選択されている場合、これは単にデフォルトを起動します。

StartActivity(Intent.createChooser(intent、 "ランチャー設定を常に設定してください"))を使用してみました。また、アプリとストックランチャーの間で選択肢が得られますが、常にまたは一度だけのオプションは得られません。

正しい。 createChooser()は選択を強制しますが、デフォルトの設定は許可しません。

7
CommonsWare