2010-10-01 12 views
23

pour certains besoins spécifiques je dois changer l'application d'accueil par défaut Android avec ma demande d'accueil personnalisée (un réglage dans mon application qui permet de basculer par défaut home = ma demande ou à la maison précédente)Android: défaut de changement Accueil application

Je ne veux pas que l'utilisateur Voyage paramètres Android qui sont très compliqués.

peut me aider comme où il enregistre launcher.apk pour une application à domicile par défaut ou comment changer cette

La seule chose que je pouvais trouver était cette vieille question: How to change default Android's Desktop application?

mais pas de réponses du tout.

J'ai vu HomeSwitcher sur le marché qui fait l'affaire, mais pas de réponse pour le développeur qui pourrait être occupé.

EDIT

J'ai trouvé sur le web http://www.mail-archive.com/[email protected]/msg74167.html

Mais je suis arrivé la même question:

voici mon code:

private void makePreferred() { 
      PackageManager pm = getPackageManager(); 
      IntentFilter f = new IntentFilter("android.intent.action.MAIN"); 
      f.addCategory("android.intent.category.HOME"); 
      f.addCategory("android.intent.category.DEFAULT"); 
      ComponentName cn = new ComponentName("com.example.android.home", "com.example.android.home.Home"); 
      pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, null, cn); 

Je l'ensemble android.permission.SET_PREFERRED_APPLICATIONS dans le manifeste . Après l'exécution du code ci-dessus, les journaux affirment que les choses ont été ajoutées comme prévu (mêmes journaux que lorsque je coche "Make default" de la liste d'IntentResolver). Cependant, quand je passe en cliquant sur la maison, la liste apparaît toujours et les journaux disent:

INFO/PackageManager(52): Result set changed, dropping preferred 
activity for Intent { act=android.intent.action.MAIN cat= 
[android.intent.category.HOME] flg=0x10200000 } type null 

Il semble donc le résolveur supprime l'entrée par défaut. Est-ce que je fais quelque chose ne va pas, ou est-ce une mesure de sécurité? Quelles sont les idées derrière cela?

+1

Je suis sûr que vous ne pouvez pas forcer un utilisateur à utiliser votre intention par défaut pour quoi que ce soit - il devrait toujours être leur choix. L'enregistrer comme une intention Home devrait suffire à l'utilisateur pour obtenir une boîte de dialogue demandant quelle application home ils veulent lancer. –

+0

Cela n'est pas possible SAUF si vous travaillez avec une version principale pour un téléphone et même si c'est encore risqué. Pensez à dire à votre demandeur NON. Parce que ce comportement n'est pas attendu du point de vue d'une application. – JoxTraex

Répondre

8

J'ai fait une recherche approfondie à ce sujet et à partir de la version 2.2, il n'y a aucun moyen de le faire. La seule façon est d'utiliser un peu de piratage que l'application de verrouillage des tout-petits fait, mais cette application a mis les téléphones Samsung récemment dans la boucle infinie, donc c'est une approche risquée.

si vous regardez le code source de froyo here de classe packagemanager, vous verrez cette petite condition dans la méthode addPreferredActivity:

if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) 
        < Build.VERSION_CODES.FROYO) { 
       Slog.w(TAG, "Ignoring addPreferredActivity() from uid" 
         + Binder.getCallingUid()); 
       return; 
      } 

HomeSwitcher ne fonctionne pas correctement sur 2.2 car il utilise cette méthode très et développeur fait un commentaire sur la page d'application « Froyo (2.2) ne sont pas pris en charge en raison du changement d'API »

+0

L'OP ne frappe pas ça. Son erreur est "abandon de l'activité préférée ..." qui est générée plus bas dans le code. Tout ce que fait cette vérification est d'empêcher d'appeler addPreferredActivity à partir d'une application qui n'a pas été compilée avec Froyo. –

7

« le jeu de résultats changé » signifie que l'ensemble des paquets correspondant à cette intention a changé de l'ensemble que vous avez spécifié lorsque vous c répété la valeur par défaut - - donc la valeur par défaut n'est plus valide. Votre liste de composants (que vous définissez actuellement sur null) doit contenir toutes les applications d'écran d'accueil présentes sur l'appareil, pas seulement les vôtres.

Voici un exemple de code que j'ai testé (en utilisant adb shell am start http://www.google.co.uk/) et utilisé pour définir le navigateur par défaut.XXX représente un nom de client que j'ai dû noircir.

Notez que pour appeler addPreferredActivity, vous devez avoir compilé avec une version minimum-sdk de 8 (2.2) et vous devez avoir spécifié l'autorisation SET_PREFERRED_APPLICATIONS. Cette autorisation est le niveau de protection 2, vous devez donc être connecté avec le même certificat que PackageManager. ETA - si vous avez noté cette réponse, pourriez-vous me dire pourquoi? Le code que j'ai posté ci-dessus est testé et fonctionne ...

+6

comment le signer avec le même certificat? – hoffmanc

+0

Je veux également l'implémenter, je veux changer le lanceur par défaut après le premier démarrage. J'ai mis le code au constructeur de PackageManagerService, mais il a toujours échoué. Pouvez-vous me dire si je veux le faire, quelle position dois-je mettre le code? Merci beaucoup! – alexunder

+0

@hoffmanc vous auriez besoin des clés de plate-forme avec lesquelles le système d'exploitation a été construit. À moins que vous ne construisiez et ne signiez votre propre ROM, vous n'y auriez pas accès. – amitav13

0

Ce code fonctionne sur mon périphérique ICS: J'utilise un service qui est sensible à certains appels, l'un d'entre eux s'appelle SET_PREFERRED_LAUNCHER, le mettre dans un bundle votre nouveau défaut package lanceur (de PREFERRED_PACKAGE_KEY) et son activité (PREFERRED_ACTIVITY_KEY)

Method installPackageMethod = null; 
Method deletePackageMethod = null; 
Method setPreferredActivityMethod = null; 
Method replacePreferredActivityMethod = null; 
Object pm = null; 


    @Override 
public void onCreate() { 
    super.onCreate(); 
     if (pm == null) 
     pm = getPackageManager(); 
    try { 
     if (setPreferredActivityMethod == null) 
      setPreferredActivityMethod = pm.getClass().getMethod(
        "addPreferredActivity", IntentFilter.class, int.class, 
        ComponentName[].class, ComponentName.class); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 
} 


private final class ServiceHandler extends Handler { 
    private Context context; 

    public ServiceHandler(Looper looper, Context ctx) { 
     super(looper); 
     context = ctx; 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     Intent intent = (Intent) msg.getData().getParcelable(
       UPDATER_SERVICE_ACTION); 
     int request = intent.getIntExtra(
       REQUEST_KEY, 
       REQUEST_UNKNOWN); 
     Bundle bundle = intent.getExtras(); 

     switch (request) { 
     case INSTALL_APPLICATION: { 
      if (bundle != null) { 
       String appPath = bundle 
         .getString(APP_PATH_KEY); 
       if (appPath != null) { 
        LogUtil.e(TAG, "try to install " + appPath); 

        try { 
         am.installPackage(appPath); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        LogUtil.e(TAG, "install of " + appPath + " done"); 
       } 
      } 
      break; 
     } 
     case UNISTALL_PACKAGE: { 
      if (bundle != null) { 
       String packagename = bundle 
         .getString(PACKAGE_NAME_KEY); 
       if (packagename != null) { 
        LogUtil.e(TAG, "unistall " + packagename); 

        try { 
         deletePackageMethod 
           .invoke(pm, packagename, null, 0); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      break; 
     } 
     case SET_PREFERRED_LAUNCHER: { 
      if (bundle != null) { 
       String package_name = bundle 
         .getString(PREFERRED_PACKAGE_KEY); 
       if (package_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, package is NULL"); 
        return; 
       } 
       String activity_name = bundle 
         .getString(PREFERRED_ACTIVITY_KEY); 
       if (activity_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, activity is NULL"); 
        return; 
       } 

       LogUtil.e(TAG, "setDefaultActivity activity=" 
         + activity_name + " package=" + package_name); 

       IntentFilter filter = new IntentFilter(
         "android.intent.action.MAIN"); 
       filter.addCategory("android.intent.category.HOME"); 
       filter.addCategory("android.intent.category.DEFAULT"); 
       ComponentName[] components = new ComponentName[] { 
         new ComponentName("com.android.launcher", 
           "com.android.launcher2.Launcher"), 
         new ComponentName(package_name, activity_name) }; 
       ComponentName activity = new ComponentName(package_name, 
         activity_name); 
       try { 
        setPreferredActivityMethod.invoke(pm, filter, 
          IntentFilter.MATCH_CATEGORY_EMPTY, components, 
          activity); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     } 

    } 

} 

Rappelez-vous d'ajouter dans votre fichier manifeste cette autorisation:

<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"/> 

Utilisation:

public void setPreferredLauncher(String activity_name,String package_name) 
{ 
    Intent intent = new Intent(UPDATER_SERVICE_ACTION); 
    intent.putExtra(REQUEST_KEY, SET_PREFERRED_LAUNCHER); 
    intent.putExtra(PREFERRED_ACTIVITY_KEY, activity_name); 
    intent.putExtra(PREFERRED_PACKAGE_KEY, package_name); 
    context.startService(intent); 
} 

où:

public static final String _UPDATER_SERVICE_ACTION = "com.android.updaterservice.ACTION"; 
public static final String REQUEST_KEY = "com.android.updaterservice.REQUEST_KEY"; 
public static final String PACKAGE_NAME_KEY = "com.android.updaterservice.PACKAGE_NAME_KEY"; 
public static final String APP_PATH_KEY = "com.android.updaterservice.APP_PATH_KEY"; 
public static final String PREFERRED_ACTIVITY_KEY = "com.android.updaterservice.PREFERRED_ACTIVITY_KEY"; 
public static final String PREFERRED_PACKAGE_KEY = "com.android.updaterservice.PREFERRED_PACKAGE_KEY"; 
public static final String INSTALL_PACKAGE_RESULT = "com.android.updaterservice.INSTALL_PACKAGE_RESULT"; 
public static final String PACKAGE_NAME = "PACKAGE_NAME"; 
public static final String INSTALL_SUCCEEDED = "INSTALL_SUCCEEDED"; 
public static final int REQUEST_UNKNOWN = -1; 
public static final int INSTALL_APPLICATION = 1; 
public static final int UNISTALL_PACKAGE = 2; 
public static final int SET_PREFERRED_LAUNCHER = 3; 
+1

Notez que seules les applications signées avec la même clé de signature que le firmware peuvent détenir l'autorisation 'SET_PREFERRED_APPLICATIONS'. – CommonsWare

+0

Chez am.installPackage() .. qu'est ce que je suis? que déclarer? –

0
startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); 
+0

Cela permet de définir les paramètres et vous permet de définir manuellement le lanceur d'accueil, mais ne le configure pas par programme par défaut dans le programme de lancement. – saiyancoder