จะตรวจสอบได้อย่างไรว่าเจตนาสามารถจัดการได้จากกิจกรรมบางอย่าง?


116

ฉันมีวิธีนี้แล้ว แต่มันก็เหมือนมีบางอย่างหายไป

ตัวอย่างเช่นฉันมีไฟล์ /sdcard/sound.3ga ที่ส่งคืนเท็จ (เช่นไม่มีกิจกรรมใดที่สามารถจัดการไฟล์ประเภทนี้ได้) แต่เมื่อฉันเปิดจากตัวจัดการไฟล์มันจะเปิดขึ้นพร้อมกับเครื่องเล่นสื่อโดยไม่มีปัญหา

ฉันคิดว่าเจตนานี้ยังไม่สมบูรณ์และฉันต้องทำอะไรเพิ่มเติมเพื่อให้ตัวเองแน่ใจว่าตัวแปร handlerExists จะเป็นเท็จเท่านั้นหากไม่มีกิจกรรมที่สามารถจัดการกับเจตนานี้ได้

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;

คำตอบ:


150

โซลูชันของ 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");
Felipe

1
ค่าสถานะ 0 ที่นี่คืออะไร?
RyPope

@RyPope มันหมายถึง <ไม่มีธง>
Mohammad Ersan

หากเราใช้setPackage()ตามเจตนาสิ่งนี้จะล้มเหลว ดังนั้นเราควรไปIntent.resolveActivity()
CopsOnRoad

fixActivity () มักจะส่งคืนความตั้งใจแม้ว่าจะไม่มีอะไรที่สามารถจัดการได้จริงดังนั้นจึงไม่ได้ผลสำหรับสิ่งนี้ สิ่งนี้ได้ผลสำหรับฉัน
Glenn Maynard

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

โปรดทราบว่าวิธีนี้ไม่ได้ผลเสมอไป: การแก้ปัญหาสามารถส่งคืนความตั้งใจที่ไม่สามารถจัดการได้ วิธีการ queryIntentActivities ทำงานได้ดีขึ้นสำหรับฉัน
Glenn Maynard

ดีกับ 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

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.