¿Cómo comprobar si se puede manejar una intención a partir de alguna actividad?


115

Tengo este método hasta ahora, pero me pareció que faltaba algo

por ejemplo, tengo un archivo /sdcard/sound.3ga que devuelve falso (como si no hubiera actividad que pueda manejar este tipo de archivo), pero cuando lo abro desde el administrador de archivos se abre con el reproductor multimedia sin problema

Creo que esta intención no está completa y necesito algo más para asegurarme de que la variable handlerExists será falsa SOLO si no hay actividad que pueda manejar esta intención

PackageManager pm = getPackageManager();
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(uriString)).toString());
String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
intent.setDataAndType(Uri.fromFile(new File(uriString)),mimetype);
boolean handlerExists = intent.resolveActivity(pm) != null;

Respuestas:


149

La solución de edwardxu funciona perfectamente para mí.

Solo para aclarar un poco:

PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent);
} else {
    Log.d(TAG, "No Intent available to handle action");
}

1
bueno, con Android api 30+, no siempre funciona ahora)
user924


86
PackageManager manager = context.getPackageManager();
List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
if (infos.size() > 0) {
    //Then there is an Application(s) can handle your intent
} else {
    //No Application can handle your intent
}

¿Has probado esta intención?

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(yourFileHere));

Es porque olvidó: intent.setType ("text / plain");
Felipe

1
¿Qué es la bandera 0 aquí?
RyPope

@RyPope significa <sin banderas>
Mohammad Ersan

Si usamos setPackage()en la intención, esto fallará. Entonces, deberíamos ir porIntent.resolveActivity()
CopsOnRoad

resolveActivity () a menudo devuelve un intent incluso si no hay nada que pueda manejarlo, por lo que no funciona para esto. Esto funciona para mí.
Glenn Maynard

51
if (intent.resolveActivity(getPackageManager()) == null) {
    // No Activity found that can handle this intent. 
}
else{
    // There is an activity which can handle this intent. 
}

Tenga en cuenta que esto no siempre funciona: resolveActivity puede devolver una intención que no se puede manejar. El enfoque queryIntentActivities funciona mejor para mí.
Glenn Maynard

bueno, con Android api 30+, no siempre funciona ahora)
user924

2

Puedes usar:

public static boolean isAvailable(Context ctx, Intent intent) {
   final PackageManager mgr = ctx.getPackageManager();
   List<ResolveInfo> list =
      mgr.queryIntentActivities(intent, 
         PackageManager.MATCH_DEFAULT_ONLY);
   return list.size() > 0;
}

Esto no funciona cuando se usa setPackage()en la intención.
CopsOnRoad

1

Uso de Kotlin Si necesita hacer algo cuando la intención no está disponible,

fun isIntentAvailable(
                context: Context,
                action: String?
            ): Boolean {
                val packageManager = context.packageManager
                val intent = Intent(action)
                val resolveInfo: List<*> = packageManager.queryIntentActivities(
                    intent,
                    PackageManager.MATCH_DEFAULT_ONLY
                )
                return resolveInfo.isNotEmpty()
            }

Implemente este método como

private const val SAMPLE_INTENT = "com.realwear.barcodereader.intent.action.SCAN_BARCODE"



 if(isIntentAvailable(this,SAMPLE_INTENT)){
  //Do Stuff
 }

Si no tienes nada que hacer,

Intent(SAMPLE_INTENT).also { barcodeReaderIntent ->
            barcodeReaderIntent.resolveActivity(packageManager)?.also {
                barcodeReaderIntent.putExtra(EXTRA_CODE_128, false)
                startActivityForResult(barcodeReaderIntent, BARCODE_REQUEST_CODE)
            }
    }

0

Otro enfoque usando la extensión de kotlin

 fun Context.isIntentAvailable(intent: Intent): Boolean {
    val resolveInfo: List<*> = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    return resolveInfo.isNotEmpty()
 }

Uso dentro del fragmento

val available = requireContext().isIntentAvailable(this)

Uso dentro de la actividad

val available = this.isIntentAvailable(this)

debe usar PackageManagerpara su extensión diversión en lugar de Contexty evitarPackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)es innecesariamente detallado. Solo useisIntentAvailable()
Zun
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.