Android 如何检查是否可以从某些活动中处理意图?
到目前为止,我已经有了这个方法,但它似乎遗漏了什么 例如,我有一个返回false的文件/sdcard/sound.3ga(好像没有任何活动可以处理这种类型的文件),但是当我从文件管理器打开它时,它会毫无问题地用媒体播放器打开 我认为这个意图并不完整,我需要做更多的事情来确保handlerExists变量只有在没有活动可以处理这个意图的情况下才会为falseAndroid 如何检查是否可以从某些活动中处理意图?,android,android-intent,mime-types,file-type,intentfilter,Android,Android Intent,Mime Types,File Type,Intentfilter,到目前为止,我已经有了这个方法,但它似乎遗漏了什么 例如,我有一个返回false的文件/sdcard/sound.3ga(好像没有任何活动可以处理这种类型的文件),但是当我从文件管理器打开它时,它会毫无问题地用媒体播放器打开 我认为这个意图并不完整,我需要做更多的事情来确保handlerExists变量只有在没有活动可以处理这个意图的情况下才会为false PackageManager pm = getPackageManager(); Intent intent = new Intent(an
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;
爱德华·徐的解决方案对我来说非常有效 我想澄清一下:
PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
} else {
Log.d(TAG, "No Intent available to handle action");
}
您可以使用:
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;
}
公共静态布尔值可用(上下文ctx、意图){
final PackageManager mgr=ctx.getPackageManager();
列表=
查询活动经理(意向、,
PackageManager.MATCH_(仅限默认值);
返回列表.size()>0;
}
如果在意图不可用时需要执行某些操作,请使用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()
}
如果你无事可做
Intent(SAMPLE_INTENT).also { barcodeReaderIntent ->
barcodeReaderIntent.resolveActivity(packageManager)?.also {
barcodeReaderIntent.putExtra(EXTRA_CODE_128, false)
startActivityForResult(barcodeReaderIntent, BARCODE_REQUEST_CODE)
}
}
使用kotlin扩展的另一种方法
fun Context.isIntentAvailable(intent: Intent): Boolean {
val resolveInfo: List<*> = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
return resolveInfo.isNotEmpty()
}
活动内部的用法
val available = this.isIntentAvailable(this)
解决此问题的明确答案
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
对于一个在2021年寻找类似东西的人来说,这是一个小的更新:)因为Android 11不需要调用包管理器,所以需要额外的努力。 那么,为什么不在try catch中包装startActivity()?或者更好-使用Rx漂亮的错误处理:
....
.flatMapCompletable {
doSomethingThrowable()
.onErrorResumeNext { completableCallbackIfNotResolvable() }
}
.subscribe()
这是因为您忘记了:intent.setType(“text/plain”);这里的0标志是什么?@RyPope这意味着如果我们在intent上使用
setPackage()
,那么这将失败。因此,我们应该选择Intent.resolveActivity()
resolveActivity()通常会返回一个Intent,即使实际上没有任何东西可以处理它,所以它对此不起作用。这对我来说是可行的。在意图上使用setPackage()
时,这不起作用。请注意,这并不总是起作用:resolveActivity可以返回无法处理的意图。QueryInputActivities方法对我更有效。好吧,使用android api 30+,它现在并不总是有效)好吧,使用android api 30+,它现在并不总是有效)如果目标是api 30+请检查以下内容:您应该使用PackageManager
来获得扩展乐趣,而不是Context
,并避免使用PackageManager.MATCH\u DEFAULT\u仅匹配此项。Isintentavable(此)
是不必要的冗长。只需使用isIntentAvailable()
你所说的“如果你没有什么事要做”是什么意思以及下面的代码。下面的代码听起来好像是为了说明意图是否可用,但也许我错了。
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)
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
....
.flatMapCompletable {
doSomethingThrowable()
.onErrorResumeNext { completableCallbackIfNotResolvable() }
}
.subscribe()