Comment vérifier si une intention peut être gérée à partir d'une activité?


115

J'ai cette méthode jusqu'à présent, mais il est apparu comme s'il manquait quelque chose

par exemple, j'ai un fichier /sdcard/sound.3ga qui renvoie false (comme s'il n'y a pas d'activité qui puisse gérer ce type de fichier), mais quand je l'ouvre depuis le gestionnaire de fichiers, il s'ouvre avec le lecteur multimédia sans problème

Je pense que cette intention n'est pas complète et je dois faire quelque chose de plus pour m'assurer que la variable handlerExists sera fausse UNIQUEMENT s'il n'y a aucune activité qui peut gérer cette intention

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;

Réponses:


149

La solution d'edwardxu fonctionne parfaitement pour moi.

Juste pour clarifier un peu:

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

1
eh bien, avec l'api Android 30+, cela ne fonctionne pas toujours maintenant)
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
}

Avez-vous essayé cette intention?

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

C'est parce que vous avez oublié: intent.setType ("text / plain");
Felipe

1
Quel est le drapeau 0 ici?
RyPope

@RyPope ça veut dire <pas de drapeaux>
Mohammad Ersan

Si nous utilisons setPackage()l'intention, cela échouera. Donc, nous devrions aller pourIntent.resolveActivity()
CopsOnRoad

ResolutionActivity () renvoie souvent une intention même s'il n'y a rien qui puisse réellement la gérer, donc cela ne fonctionne pas pour cela. Cela fonctionne pour moi.
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. 
}

Notez que cela ne fonctionne pas toujours: résoudreActivity peut renvoyer un intent qui ne peut pas être géré. L'approche queryIntentActivities fonctionne mieux pour moi.
Glenn Maynard

eh bien, avec l'api Android 30+, cela ne fonctionne pas toujours maintenant)
user924

2

Vous pouvez utiliser:

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;
}

Cela ne fonctionne pas lors de l'utilisation setPackage()de l'intention.
CopsOnRoad

1

Utilisation de Kotlin Si vous devez faire quelque chose lorsque l'intention n'est pas 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()
            }

Implémentez cette méthode comme

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



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

Si tu n'as rien à faire,

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

0

Une autre approche utilisant l'extension kotlin

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

Utilisation à l'intérieur du fragment

val available = requireContext().isIntentAvailable(this)

Utilisation à l'intérieur de l'activité

val available = this.isIntentAvailable(this)

vous devriez utiliser PackageManagerpour votre plaisir d'extension au lieu de Contextet éviterPackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)est inutilement verbeux. Il suffit d'utiliserisIntentAvailable()
Zun
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.