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;
Lukap
la source

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");
}
Sparky1
la source
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));
Mohammad Ersan
la source
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. 
}
Edwardaa
la source
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;
}
CONvid19
la source
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)
            }
    }
Varun Chandran
la source
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)
Oscar Emilio Perez Martinez
la source
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