Borrar y configurar la aplicación de inicio predeterminada

¿Cómo es que Nova maneja esto? Literalmente trato de hacer exactamente lo mismo: proporcionar a los usuarios un botón para presionar para borrar y seleccionar su nuevo iniciador predeterminado.

Puedo obtener el nombre de la aplicación predeterminada y mostrarla:

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 el Intent i es

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

Luego invoco el 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 seleccionador aparece y funciona correctamente, pero en realidad no establece ni borra ningún valor. Mientras lo depura, parece como si me faltaran algunos extras? Cuando llamo al método makePrefered , obtengo 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 ingresar y ver qué se envía junto con ese paquete?
  2. ¿Cómo puedo borrar la aplicación preferida? No me digas que no puedes, he visto suficientes de esas respuestas. Nova lo hace y lo hace exactamente de la manera que me gustaría.

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

Cuando un componente con

   

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

Para aprovechar esto, crea una actividad vacía con el componente hogareño como este.

        

Cuando desee establecer su nuevo valor predeterminado, habilite este componente, luego llame a la intención de inicio y luego deshabilite nuevamente su componente de inicio falso.

 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 instaló una nueva aplicación para el hogar, por lo que se borra el valor predeterminado, lo que le permite configurar el suyo sin permisos especiales.

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

La solución de r2DoesInc no funciona en mi dispositivo de prueba 4.2.2.
Mi solución: desactivar y luego volver a habilitar FakeHome 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); 

Utilizo el siguiente código en Android 4.1.2 con una aplicación en modo de quiosco firmada por una plataforma en una tableta industrial. Utiliza el PackageManager.addPreferredActivity() desuso, pero la ventaja es que funciona sin la interacción del usuario. Incluso funciona después de que se haya elegido el iniciador estándar de Android 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 filters = new ArrayList<>(); List 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 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; }