Borrar y configurar la aplicación home predeterminada


¿Cómo demonios Nova logra esto? Estoy literalmente tratando de hacer exactamente lo mismo: proporcionar a los usuarios un botón para presionar para borrar y elegir su nuevo lanzador predeterminado.

Puedo obtener el nombre predeterminado de la aplicación y mostrarlo:

       private String getPrefered(Intent i) {
       PackageManager pm = this.getActivity().getPackageManager();
       final ResolveInfo mInfo = pm.resolveActivity(i, 0);
       return (String) pm.getApplicationLabel(mInfo.activityInfo.applicationInfo);
   }

Donde Intent i está

Intent home = new Intent("android.intent.action.MAIN");
        home.addCategory("android.intent.category.HOME");

Entonces llamo al sistema ResolveActivity,

private void makePrefered() {
       Intent selector = new Intent("android.intent.action.MAIN");
       selector.addCategory("android.intent.category.HOME");                          
       selector.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity"));
       startActivity(selector);
   }

El selector aparece y funciona correctamente, pero en realidad no establece ni borra ningún valor. Mientras lo depuro, parece como si estuviera faltan algunos extras? Cuando llamo al método makePrefered, recibo el siguiente mensaje de registro,

I/ActivityManager(  602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] cmp=android/com.android.internal.app.ResolverActivity u=0} from pid 22641

Cuando uso la implementación Nova veo todo esto sin embargo,

    I/PackageManager(  602): Result set changed, dropping preferred activity for Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 (has extras) } type null
I/ActivityManager(  602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=android/com.android.internal.app.ResolverActivity (has extras) u=0} from pid 22905
I/ActivityManager(  602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.mycolorscreen.canvas/.Launcher (has extras) u=0} from pid 22905
  1. ¿Cómo puedo entrar ahí y ver lo que se envía junto con ese paquete?
  2. ¿Cómo puedo borrar la aplicación preferida? No me digas que no puedes, ya he visto suficientes respuestas. Nova lo hace y lo hace exactamente de la manera que me gustaría.
Author: Null, 2012-11-01

3 answers

El código para hacer esto es en realidad solo un trabajo muy inteligente.

Cuando un componente con

        <category android:name="android.intent.category.HOME" />

Está habilitado, generalmente desde una instalación de una nueva aplicación home, la aplicación home predeterminada se borra.

Para aprovechar esto creando una actividad vacía con el componente home como este.

<activity
            android:name="com.t3hh4xx0r.haxlauncher.FakeHome"
            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>     

Cuando desee establecer su nuevo valor predeterminado, habilite este componente y, a continuación, llame a la intent de inicio y luego desactivar su componente de hogar falso nuevo.

public static void makePrefered(Context c) {
       PackageManager p = c.getPackageManager();
       ComponentName cN = new ComponentName(c, FakeHome.class);
       p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

       Intent selector = new Intent(Intent.ACTION_MAIN);
       selector.addCategory(Intent.CATEGORY_HOME);            
       c.startActivity(selector);

       p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
   }

El resultado final es que el sistema cree que se ha instalado una nueva aplicación de inicio, por lo que el valor predeterminado está desactivado, lo que le permite configurar la suya sin permisos especiales.

Gracias a Kevin de TeslaCoil y NovaLauncher por la información sobre cómo se hace esto!

 45
Author: r2DoesInc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 13:34:16

La solución de R2DoesInc no funciona en mi dispositivo de prueba 4.2.2.
Mi solución: Desactivar y volver a habilitar la HomeActivity de mi aplicación, no tiene que crear FakeHome

PackageManager p = getPackageManager();
ComponentName cN = new ComponentName(this, HomeActivity.class);
p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
 3
Author: Bruce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-15 08:36:45

Utilizo el siguiente código en Android 4.1.2 con una aplicación de modo quiosco firmada por la plataforma en una tableta industrial. Utiliza el PackageManager.addPreferredActivity() obsoleto, pero la ventaja es que funciona sin interacción del usuario. Incluso funciona después de que el lanzador estándar de Android haya sido elegido con la opción "siempre".

// Requires permission SET_PREFERRED_APPLICATIONS.
public static boolean setPreferredHomeActivity (Context context, String packageName, String className) {
   ComponentName oldPreferredActivity = getPreferredHomeActivity(context);
   if (oldPreferredActivity != null && packageName.equals(oldPreferredActivity.getPackageName()) && className.equals(oldPreferredActivity.getClassName())) {
      return false; }
   if (oldPreferredActivity != null) {
      context.getPackageManager().clearPackagePreferredActivities(oldPreferredActivity.getPackageName()); }
   IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
   filter.addCategory(Intent.CATEGORY_HOME);
   filter.addCategory(Intent.CATEGORY_DEFAULT);
   ComponentName[] currentHomeActivities = getActivitiesListByActionAndCategory(context, Intent.ACTION_MAIN, Intent.CATEGORY_HOME);
   ComponentName newPreferredActivity = new ComponentName(packageName, className);
   context.getPackageManager().addPreferredActivity(filter, IntentFilter.MATCH_CATEGORY_EMPTY, currentHomeActivities, newPreferredActivity);
   return true; }

private static ComponentName getPreferredHomeActivity (Context context) {
   ArrayList<IntentFilter> filters = new ArrayList<>();
   List<ComponentName> componentNames = new ArrayList<>();
   context.getPackageManager().getPreferredActivities(filters, componentNames, null);
   for (int i = 0; i < filters.size(); i++) {
      IntentFilter filter = filters.get(i);
      if (filter.hasAction(Intent.ACTION_MAIN) && filter.hasCategory(Intent.CATEGORY_HOME)) {
         return componentNames.get(i); }}
   return null; }

private static ComponentName[] getActivitiesListByActionAndCategory (Context context, String action, String category) {
   Intent queryIntent = new Intent(action);
   queryIntent.addCategory(category);
   List<ResolveInfo> resInfos = context.getPackageManager().queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY);
   ComponentName[] componentNames = new ComponentName[resInfos.size()];
   for (int i = 0; i < resInfos.size(); i++) {
      ActivityInfo activityInfo = resInfos.get(i).activityInfo;
      componentNames[i] = new ComponentName(activityInfo.packageName, activityInfo.name); }
   return componentNames; }
 3
Author: Christian d'Heureuse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-22 00:24:41