Як перевірити, чи можна керувати наміром із якоїсь діяльності?


115

Цей метод у мене є поки що, але він придумав, що чогось не вистачає

наприклад, у мене є файл /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;

Відповіді:


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 ("текст / звичайна");
Феліпе

1
Який тут прапор 0?
RyPope

@RyPope це означає <no flags>
Мохаммед Ерсан

Якщо ми використовуємо setPackage()за наміром, то це не вдасться. Отже, нам слід продовжитиIntent.resolveActivity()
CopsOnRoad

resolutionActivity () часто повертає наміри, навіть якщо немає нічого, що насправді може впоратися з цим, тому він не працює для цього. Це справді працює для мене.
Глен Мейнард

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

Зауважте, що це не завжди працює: resolutionActivity може повернути наміри, з якими неможливо обробити. Підхід 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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.