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;
Lukap
quelle

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