130 votes

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

J'ai utilisé cette méthode jusqu'à présent, mais il semble qu'il manque quelque chose.

Par exemple, j'ai un fichier /sdcard/sound.3ga qui renvoie un message faux (comme si aucune activité ne pouvait gérer ce type de fichier), mais lorsque je l'ouvre à partir du 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 que je dois ajouter quelque chose pour m'assurer que la variable handlerExists sera fausse UNIQUEMENT s'il n'y a pas d'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;

1voto

Varun Chandran Points 352

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()
}

Mettez en œuvre cette méthode comme

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

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

Si vous n'avez rien à faire,

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

1voto

Dimskiy Points 111

Petite mise à jour pour ceux qui cherchent quelque chose de similaire en 2021 :) Depuis Android 11, il n'est pas souhaité d'appeler le gestionnaire de paquets, donc des efforts supplémentaires sont nécessaires. Alors pourquoi ne pas simplement envelopper startActivity() dans un try-catch ? Ou encore mieux - utiliser Rx belle gestion des erreurs :

....
.flatMapCompletable { 
      doSomethingThrowable()
          .onErrorResumeNext { completableCallbackIfNotResolvable() }
}
.subscribe()

1voto

Mariusz Wiazowski Points 508

Voici une autre solution Kotlin. Elle fonctionne parfaitement même pour Android 30+ . Incluez d'abord ceci dans votre manifeste d'application :

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="choose-scheme-goes-here" />
    </intent>
</queries>

Vous pouvez ensuite vérifier si une intention peut être traitée avec cette fonction :

private fun isIntentAvailable(intent: Intent): Boolean {
    val manager = requireContext().packageManager
    val info = manager.queryIntentActivities(intent, 0)
    return info.size > 0
}

0voto

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 d'un fragment

val available = requireContext().isIntentAvailable(this)

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

val available = this.isIntentAvailable(this)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X