Obtener una aplicación preferida / predeterminada en Android

Estoy tratando de obtener la aplicación predeterminada / preferida para una Intent dada. Por ejemplo, cuando el usuario instala un segundo navegador web, intenta abrir una URL, obtendrá un diálogo similar al siguiente:

Selector de navegador predeterminado

Si el usuario selecciona la opción Usar por defecto para esta acción , el cuadro de diálogo ya no se abre cuando se pulsa una URL.

Estoy trabajando en una aplicación que debería ser consciente de lo que es esta aplicación / acción predeterminada o preferida . ¿Cómo hago esto? Estoy usando actualmente el código abajo, pero getPreferredPackage no devuelve nada:

 Intent i = (new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com")); PackageManager pm = context.getPackageManager(); final List<ResolveInfo> list = pm.queryIntentActivities(i, 0); IntentFilter ifilter = new IntentFilter(i.getAction()); if (i.getCategories() != null) { for(String category : i.getCategories()) { ifilter.addCategory(category); } } List<IntentFilter> filters = new ArrayList<IntentFilter>(); filters.add(ifilter); List<ComponentName> preferredActivities = new ArrayList<ComponentName>(); pm.getPreferredActivities(filters, preferredActivities, null); for (ComponentName activity : preferredActivities) { for (ResolveInfo rinfo : list) { if (rinfo.activityInfo.applicationInfo.packageName.equals(activity.getPackageName())) { try { final PackageInfo pi = pm.getPackageInfo(activity.getPackageName(), 0); Toast.makeText(context, pm.getApplicationLabel(pi.applicationInfo), Toast.LENGTH_SHORT).show(); } } catch (NameNotFoundException e) { e.printStackTrace(); } } } 

¿Qué estoy haciendo mal? ¿Es esto el enfoque correcto?

Bueno, la solución resultó ser mucho más simple de lo que lo hice (aunque esto es muy poco documentado). El siguiente código es mi solución:

 Intent i = (new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com")); PackageManager pm = context.getPackageManager(); final ResolveInfo mInfo = pm.resolveActivity(i, 0); Toast.makeText(context, pm.getApplicationLabel(mInfo.activityInfo.applicationInfo), Toast.LENGTH_LONG).show(); 

El método launchUrlInDefaultBrowser continuación inicia una URL sin mostrar ninguna consulta de selección para el usuario. En primer lugar, trata de encontrar la aplicación predeterminada del navegador del usuario y de lanzar la URL con ella. En segundo lugar, si no había una aplicación predeterminada, lista todas las actividades capaces para lanzar la URL y recoge la primera. En caso de iniciarse una actividad, el método devuelve verdadero; De lo contrario, false.

 boolean launchUrlInDefaultBrowser(Context context, String url) { final Intent browserIntent = new Intent(Intent.ACTION_VIEW); browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); browserIntent.setData(Uri.parse(url)); // 1: Try to find the default browser and launch the URL with it final ResolveInfo defaultResolution = context.getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY); if (defaultResolution != null) { final ActivityInfo activity = defaultResolution.activityInfo; if (!activity.name.equals("com.android.internal.app.ResolverActivity")) { browserIntent.setClassName(activity.applicationInfo.packageName, activity.name); context.startActivity(launchIntent); return true; } } // 2: Try to find anything that we can launch the URL with. Pick up the first one that can. final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY); if (!resolveInfoList.isEmpty()) { browserIntent.setClassName(resolveInfoList.get(0).activityInfo.packageName, resolveInfoList.get(0).activityInfo.name); context.startActivity(browserIntent); return true; } return false; } 

Tenga cuidado, los OEM pueden tener su propia implementación ResolverActivity. Por ejemplo Huawei tiene com.huawei.android.internal.app.HwResolverActivity.

En Kitkat AOSP, getPreferredPackages () siempre devuelve la lista vacía. Código fuente como abajo

 public List<PackageInfo> getPreferredPackages(int flags) { return new ArrayList<PackageInfo>(); } 
  • Diferencia entre el comando "install" de adb y el comando "pm install"?
  • Quitar actividad como iniciador predeterminado
  • Cómo cambiar el tema de otro recurso de la aplicación en android?
  • Habilitar degradación al instalar apk con la intención de Android 4.2+
  • Cómo deshabilitar mediante programación aplicaciones sin root?
  • No se pueden obtener filtros de intenciones de un paquete
  • ¿Cómo usar el instalador de paquetes predeterminado (Android) al intentar instalar un APK desde otra aplicación?
  • Método de reflexión de Android M freeStorageAndNotify excepción
  • Cómo establecer mediante programación un bloqueo o un pin para una aplicación
  • Obtener el nombre de la aplicación activa en Android
  • ¿Qué es InstallerPackageName cuando la aplicación está en fase de "publicación pendiente" y se utiliza / revisa por los evaluadores / probadores (Google Play Store)?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.