Wie kann ich überprüfen, ob eine Absicht aus einer Aktivität heraus verarbeitet werden kann?


115

Ich habe diese Methode bisher, aber es kam auf, als ob etwas fehlt

Zum Beispiel habe ich eine Datei /sdcard/sound.3ga, die false zurückgibt (als ob es keine Aktivität gibt, die diesen Dateityp verarbeiten kann). Wenn ich sie jedoch über den Dateimanager öffne, wird sie problemlos mit dem Media Player geöffnet

Ich denke, diese Absicht ist nicht vollständig und ich muss etwas mehr tun, um selbst sicherzustellen, dass die Variable handlerExists NUR dann falsch ist, wenn es keine Aktivität gibt, die diese Absicht verarbeiten kann

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;

Antworten:


149

Die Lösung von edwardxu funktioniert perfekt für mich.

Nur um ein bisschen zu klären:

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

1
Nun, mit Android API 30+ funktioniert es jetzt nicht immer.)
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
}

Haben Sie diese Absicht versucht?

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

Es ist, weil Sie vergessen haben: intent.setType ("text / plain");
Felipe

1
Was ist die 0-Flagge hier?
RyPope

@ RyPope bedeutet <keine Flaggen>
Mohammad Ersan

Wenn wir setPackage()die Absicht verwenden, schlägt dies fehl. Also sollten wir uns fürIntent.resolveActivity()
CopsOnRoad

resolveActivity () gibt häufig eine Absicht zurück, auch wenn nichts tatsächlich damit umgehen kann. Daher funktioniert dies nicht. Das funktioniert bei mir.
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. 
}

Beachten Sie, dass dies nicht immer funktioniert: resolveActivity kann eine Absicht zurückgeben, die nicht verarbeitet werden kann. Der queryIntentActivities-Ansatz funktioniert für mich besser.
Glenn Maynard

Nun, mit Android API 30+ funktioniert es jetzt nicht immer.)
user924

2

Sie können verwenden:

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

Dies funktioniert nicht, wenn setPackage()die Absicht verwendet wird.
CopsOnRoad

1

Verwenden von Kotlin Wenn Sie etwas tun müssen, wenn keine Absicht verfügbar ist,

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

Implementieren Sie diese Methode als

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



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

Wenn Sie nichts zu tun haben,

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

0

Ein anderer Ansatz mit Kotlin-Erweiterung

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

Verwendung innerhalb des Fragments

val available = requireContext().isIntentAvailable(this)

Verwendung innerhalb der Aktivität

val available = this.isIntentAvailable(this)

Sie sollten PackageManagerfür Ihre Erweiterung Spaß anstelle von Contextund vermeidenPackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)ist unnötig ausführlich. Verwenden Sie einfachisIntentAvailable()
Zun
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.