【发布时间】:2025-11-25 16:20:09
【问题描述】:
有没有办法检查设备上是否存在活动?如果我有一个 youtube 视频链接,我想指定它在 YouTube PlayerActivity 中打开。但是,如果由于某种原因他们没有它,我不想崩溃。
有没有办法检查活动是否存在?我认为我无法捕获运行时异常,因为 startActivity() 不会抛出它。
【问题讨论】:
有没有办法检查设备上是否存在活动?如果我有一个 youtube 视频链接,我想指定它在 YouTube PlayerActivity 中打开。但是,如果由于某种原因他们没有它,我不想崩溃。
有没有办法检查活动是否存在?我认为我无法捕获运行时异常,因为 startActivity() 不会抛出它。
【问题讨论】:
您可以使用必要的组件信息创建一个 Intent 对象,然后检查该 Intent 是否可调用。我在 SO 上偶然发现了这个 sn-p,没有指向实际线程的链接。
private boolean isCallable(Intent intent) {
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
【讨论】:
这是最简单的方法:
boolean activityExists = intent.resolveActivityInfo(getPackageManager(), 0) != null;
要首先验证是否存在接收 Intent 的应用,请在 Intent 对象上调用
resolveActivity()。如果结果不为空,则至少有一个应用程序可以处理该意图,并且可以安全地调用startActivity()。如果结果为 null,则不应使用该意图,并且如果可能,应禁用调用该意图的功能。
【讨论】:
intent.resolveActivity(getPackageManager()) 那么返回什么?如果这个方法真的返回了一个不存在的活动,这绝对看起来像一个错误。此外,根据 Google 文档,List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); 的作用完全相同,只是它不只是返回具有最高优先级的活动。
intent.setComponent(new ComponentName("package", "package.activity-name)); 你问它返回什么 - ComponentInfo{"package"/"package.activity-name}。但实际上该活动并不存在,因此调用此意图最终会导致运行时崩溃。
我最终做了:
Intent intent = new Intent();
intent.setClassName( "com.google.android.gsf", "com.google.android.gsf.login.AccountIntroActivity" );
if(getContext().getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
getContext().startActivity( intent );
} else {
getContext().startActivity(new Intent(Settings.ACTION_ADD_ACCOUNT));
}
这可确保存在特定于 google 的添加帐户意图,如果不存在,则使用更通用的 ACTION_ADD_ACCOUNTS。
【讨论】:
我认为我无法赶上运行时 异常
实际上,这是可行的:
try {
startActivity(new Intent(..));
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "Not installed.", LENGTH_SHORT).show();
}
【讨论】:
以下是我检查设备上是否存在Activity 的方法:
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tell//:" + phoneNumber));
PackageManager manager = context.getPackageManager();
List<ResolveInfo> activities = manager.queryIntentActivities(
intent, 0);
if (!manager.hasSystemFeature(
PackageManager.FEATURE_TELEPHONY) || activities == null || activities
.size() < 1) {
Toast.makeText(
context,
"Sorry, there were no apps that worked with that request.",
Toast.LENGTH_SHORT).show();
} else {
context.startActivity(intent);
}
【讨论】: