web-dev-qa-db-fra.com

Comment définir le lanceur d'applications par défaut par programme?

Je crée une application de lancement (kiosque) qui sera téléchargeable via google. Lors de la première installation de cette application, l'utilisateur a la possibilité de choisir le lanceur (le mien ou le stock) par défaut. J'essaie de le faire manuellement si l'utilisateur ne fait pas de mon application le lanceur par défaut. Je veux que l'utilisateur soit obligé de sélectionner TOUJOURS au lieu de JUSTE UNE FOIS lorsque cette boîte de dialogue apparaît, sinon la boîte de dialogue continuera à apparaître périodiquement avec un message convivial. C'est ce que j'ai tenté jusqu'à présent.

J'ai créé une méthode pour vérifier si mon application est celle par défaut

/**
 * 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;
}   

Ensuite, je fais la tentative de lancement du sélecteur

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

Lorsque je fais cela, je ne reçois pas le choix entre mon application et le lanceur d'actions. J'ai essayé d'utiliser startActivity(Intent.createChooser(intent, "Please set launcher settings to ALWAYS")); et j'ai le choix entre mon application et le lanceur d'actions, cependant, je n'ai pas toujours les options ou JUSTE UNE FOIS.

Je peux créer une boîte de dialogue personnalisée pour cela au lieu de lancer le sélecteur, mais j'ai besoin de savoir comment définir le lanceur d'applications par défaut par programme. Merci d'avance!

36
portfoliobuilder

Ceci est en fait possible avec une petite solution:

Créez un Activity vide qui agit comme un lanceur appelé FakeLauncherActivity. Ajoutez-le à votre manifeste en tant que composant désactivé:

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

Vérifiez si votre activité de lancement souhaitée est celle par défaut (avec la fonction isMyAppLauncherDefault() de votre question).

Sinon, proposez à l'utilisateur de choisir l'activité de lancement préférée comme ceci:

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

Cette méthode active temporairement FakeLauncherActivity, ce qui entraîne une modification de l'ensemble des activités de lancement disponibles, ce qui force Android à oublier son lanceur par défaut. Vous verrez quelque chose comme ...

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

... dans votre journal.

La méthode ouvre alors simplement une intention de lancement où vous pouvez voir tous les lanceurs installés et les boutons "Toujours"/"Une seule fois". Enfin, la méthode désactive à nouveau FakeLauncherActivity pour qu'elle ne s'affiche pas dans la liste.

Vous pouvez répéter cela aussi souvent que vous le souhaitez et ne laisser l'utilisateur poursuivre que si l'activité de lancement souhaitée est définie par défaut.

60
saschoar

La fonction isMyAppLauncherDefault () dans la question ne fonctionne pas toujours pour une raison quelconque. Ce code pourrait être préférable pour déterminer quel est le package par défaut pour l'écran ACCUEIL.

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

Je veux que l'utilisateur soit obligé de sélectionner TOUJOURS au lieu de JUSTE UNE FOIS lorsque cette boîte de dialogue s'affiche

Ce n'est pas possible, sauf peut-être sur des appareils enracinés, à moins d'une faille de sécurité dans Android.

Lorsque je fais cela, je ne reçois pas le choix entre mon application et le lanceur de stock

Correct. Si un défaut a déjà été choisi, cela lancera simplement le défaut.

J'ai essayé d'utiliser startActivity (Intent.createChooser (intention, "Veuillez définir les paramètres du lanceur sur TOUJOURS")); et j'obtiens les choix entre mon application et le lanceur d'actions, cependant, je n'ai pas les options TOUJOURS ou JUSTE UNE FOIS.

Correct. createChooser() force un choix, mais ne permet pas de définir une valeur par défaut.

7
CommonsWare