Làm thế nào để kiểm tra xem một ý định có thể được xử lý từ một số hoạt động hay không?


115

Tôi có phương pháp này cho đến nay, nhưng nó xuất hiện như thiếu một cái gì đó

ví dụ: tôi có một tệp /sdcard/sound.3ga trả về false (giống như không có hoạt động nào có thể xử lý loại tệp này), nhưng khi tôi mở nó từ trình quản lý tệp, nó sẽ mở bằng trình phát đa phương tiện mà không có vấn đề gì

Tôi nghĩ rằng ý định này chưa hoàn thành và tôi cần phải làm gì đó thêm để tự đảm bảo rằng biến handlerExists sẽ CHỈ là sai nếu không có hoạt động nào có thể xử lý ý định này

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;

Câu trả lời:


149

Giải pháp của edwardxu hoạt động hoàn hảo đối với tôi.

Chỉ cần làm rõ một chút:

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

1
tốt, với android api 30+, nó không phải lúc nào cũng hoạt động)
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
}

Bạn đã thử ý định này chưa?

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

Đó là do bạn quên: Ý định.setType ("văn bản / đồng bằng");
Felipe

1
Cờ 0 ở đây là gì?
RyPope

@RyPope có nghĩa là <không có cờ>
Mohammad Ersan

Nếu chúng ta đang sử dụng setPackage()với mục đích, thì điều này sẽ không thành công. Vì vậy, chúng ta nên tiếp tụcIntent.resolveActivity()
CopsOnRoad 13/02/18

giải quyết () thường trả về một ý định ngay cả khi không có gì thực sự có thể xử lý nó, vì vậy nó không hoạt động cho điều này. Điều này làm việc cho tôi.
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. 
}

Lưu ý rằng điều này không phải lúc nào cũng hoạt động: giải quyếtActivity có thể trả về một ý định không thể xử lý được. Phương pháp queryIntentActiilities hoạt động tốt hơn đối với tôi.
Glenn Maynard

tốt, với android api 30+, nó không phải lúc nào cũng hoạt động)
user924

2

Bạn có thể dùng:

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

Điều này không hoạt động khi sử dụng setPackage()với mục đích.
CopsOnRoad

1

Sử dụng Kotlin Nếu bạn cần làm gì đó khi không có ý định,

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

Triển khai phương pháp này với tư cách

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



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

Nếu bạn không có gì để làm,

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

0

Một cách tiếp cận khác sử dụng tiện ích mở rộng kotlin

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

Sử dụng bên trong phân mảnh

val available = requireContext().isIntentAvailable(this)

Sử dụng bên trong hoạt động

val available = this.isIntentAvailable(this)

bạn nên sử dụng PackageManagerđể tiện ích mở rộng của mình thú vị thay vì Contextvà tránhPackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)dài dòng một cách không cần thiết. Chỉ cần sử dụngisIntentAvailable()
Zun
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.