Bazı faaliyetlerden bir niyetin ele alınabileceği nasıl kontrol edilir?


116

Şimdiye kadar bu yönteme sahibim ama bir şey eksik gibi geldi

Örneğin, yanlış döndüren bir /sdcard/sound.3ga dosyam var (bu tür bir dosyayı işleyebilecek herhangi bir etkinlik yok gibi), ancak dosya yöneticisinden açtığımda, medya oynatıcıda sorunsuz bir şekilde açılıyor

Bu niyetin tam olmadığını düşünüyorum ve kendimi handlerExists değişkeninin YALNIZCA bu amacı karşılayabilecek bir aktivite yoksa yanlış olacağından emin olmak için daha fazla bir şeye ihtiyacım var

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;

Yanıtlar:


150

edwardxu'nun çözümü benim için mükemmel çalışıyor.

Biraz açıklığa kavuşturmak için:

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

1
iyi, android api 30+ ile artık her zaman çalışmıyor)
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
}

Bu niyeti denedin mi?

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

Çünkü unutmuşsunuzdur: intent.setType ("metin / düz");
Felipe

1
Buradaki 0 ​​bayrağı nedir?
RyPope

@RyPope <bayrak yok demektir>
Mohammad Ersan

Eğer setPackage()niyet üzerinde kullanıyorsak , o zaman bu başarısız olur. Öyleyse gitmeliyizIntent.resolveActivity()
CopsOnRoad

resolActivity (), gerçekten halledebilecek hiçbir şey olmasa bile genellikle bir amaç döndürür, bu nedenle bunun için çalışmaz. Bu benim için çalışıyor.
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. 
}

Bunun her zaman işe yaramayacağını unutmayın: resolActivity, işlenemeyen bir amaç döndürebilir. QueryIntentActivities yaklaşımı benim için daha iyi çalışıyor.
Glenn Maynard

iyi, android api 30+ ile artık her zaman çalışmıyor)
user924

2

Kullanabilirsiniz:

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

Bu setPackage(), amaç üzerinde kullanıldığında işe yaramaz .
CopsOnRoad

1

Kotlin'i kullanmak Niyet olmadığında bir şeyler yapmanız gerekiyorsa,

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

Bu yöntemi şu şekilde uygulayın:

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



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

Yapacak bir şeyin yoksa

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

0

Kotlin uzantısını kullanan başka bir yaklaşım

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

Parça içi kullanım

val available = requireContext().isIntentAvailable(this)

Aktivite içi kullanım

val available = this.isIntentAvailable(this)

PackageManageryerine uzantı eğlencesi için kullanmalı Contextve kaçınmalısınızPackageManager.MATCH_DEFAULT_ONLY
user924

this.isIntentAvailable(this)gereksiz bir şekilde ayrıntılıdır. Sadece kullanınisIntentAvailable()
Zun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.