Bagaimana cara memeriksa apakah maksud bisa ditangani dari beberapa aktivitas?

115

Saya memiliki metode ini sejauh ini, tetapi ternyata ada sesuatu yang hilang

misalnya saya memiliki file /sdcard/sound.3ga yang mengembalikan false (seperti tidak ada aktivitas yang dapat menangani file jenis ini), Tetapi ketika saya membukanya dari manajer file, itu terbuka dengan pemutar media tanpa masalah

Saya rasa maksud ini belum lengkap dan saya perlu melakukan sesuatu yang lebih untuk memastikan diri saya bahwa variabel handlerExists akan salah HANYA jika tidak ada aktivitas yang dapat menangani maksud ini.

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
sumber

Jawaban:

149

solusi edwardxu bekerja dengan sempurna untuk saya.

Hanya untuk menjelaskan sedikit:

PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent);
} else {
    Log.d(TAG, "No Intent available to handle action");
}
Sparky1
sumber
1
baik, dengan api android 30+, itu tidak selalu berfungsi sekarang)
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
}

Sudahkah Anda mencoba niat ini?

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(yourFileHere));
Mohammad Ersan
sumber
Itu karena Anda lupa: intent.setType ("text / plain");
Felipe
1
Apa 0 bendera di sini?
RyPope
@RyPope artinya <tidak ada bendera>
Mohammad Ersan
Jika kita menggunakan setPackage()maksud tersebut, maka ini akan gagal. Jadi, kita harus pergiIntent.resolveActivity()
CopsOnRoad
ResolActivity () sering kali mengembalikan maksud meskipun tidak ada yang benar-benar bisa menanganinya, jadi tidak berfungsi untuk ini. Ini berhasil untuk saya.
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
sumber
Perhatikan bahwa ini tidak selalu berhasil: resolActivity bisa mengembalikan maksud yang tidak bisa ditangani. Pendekatan queryIntentActivities bekerja lebih baik untuk saya.
Glenn Maynard
baik, dengan api android 30+, itu tidak selalu berfungsi sekarang)
user924
2

Kamu bisa memakai:

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
sumber
Ini tidak berfungsi saat menggunakan setPackage()di maksud.
CopsOnRoad
1

Menggunakan Kotlin Jika Anda perlu melakukan sesuatu saat maksud tidak tersedia,

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

Terapkan metode ini sebagai

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



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

Jika Anda tidak ada hubungannya,

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

Pendekatan lain menggunakan ekstensi kotlin

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

Penggunaan di dalam fragmen

val available = requireContext().isIntentAvailable(this)

Penggunaan di dalam aktivitas

val available = this.isIntentAvailable(this)
Oscar Emilio Perez Martinez
sumber
kamu harus menggunakan PackageManager untuk kesenangan ekstensi Anda daripada Contextdan menghindariPackageManager.MATCH_DEFAULT_ONLY
user924
this.isIntentAvailable(this)tidak perlu bertele-tele. Cukup gunakanisIntentAvailable()
Zun