特定のアクティビティからインテントを処理できるかどうかを確認するにはどうすればよいですか?


115

今のところこの方法がありますが、何かが足りないように思いました

たとえば、falseを返すファイル/sdcard/sound.3gaがあります(このタイプのファイルを処理できるアクティビティがないなど)が、ファイルマネージャから開くと、メディアプレーヤーで問題なく開きます。

このインテントは完全ではないので、このインテントを処理できるアクティビティがない場合にのみ、handlerExists変数がfalseになることを確認するために、さらに何かをする必要があります。

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;

回答:


149

edwardxuのソリューションは私にとって完璧に機能します。

少し明確にするために:

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

1
まあ、android api 30+を使用すると、常に機能するとは限りません)
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
}

この意図を試しましたか?

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

それはあなたが忘れていたからです:intent.setType( "text / plain");
フェリペ

1
ここの0フラグとは何ですか?
RyPope 2017年

@RyPopeは<フラグなし>を意味します
Mohammad Ersan

setPackage()インテントで使用している場合、これは失敗します。だから、我々は行くべきですIntent.resolveActivity()
CopsOnRoad 2018

resolveActivity()は、実際に処理できるものが何もない場合でもインテントを返すことが多いため、この場合は機能しません。これでうまくいきます。
グレンメイナード

51
if (intent.resolveActivity(getPackageManager()) == null) {
    // No Activity found that can handle this intent. 
}
else{
    // There is an activity which can handle this intent. 
}

これが常に機能するとは限らないことに注意してください。resolveActivityは、処理できないインテントを返す可能性があります。queryIntentActivitiesアプローチは私にとってはうまく機能します。
グレンメイナード

まあ、android api 30+を使用すると、常に機能するとは限りません)
user924

2

以下を使用できます。

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

setPackage()インテントで使用する場合、これは機能しません。
CopsOnRoad 2018

1

Kotlinの使用インテントが利用できないときに何かする必要がある場合は、

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

このメソッドを次のように実装します

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



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

何もしなければ

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

0

Kotlin拡張機能を使用した別のアプローチ

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

フラグメント内での使用

val available = requireContext().isIntentAvailable(this)

アクティビティ内での使用

val available = this.isIntentAvailable(this)

あなたは使用する必要がありPackageManager、あなたの拡張の楽しみの代わりのためContextと回避PackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)不必要に冗長です。そのまま使用isIntentAvailable()
Zun
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.