Determining if an Activity exists on the current d

2019-01-06 17:08发布

Is there a way to check and see if an Activity exists on your device? If I have a youtube video link I want to specify it open in the YouTube PlayerActivity. However, I don't want to crash if for some reason they don't have it.

Is there a way to check and see if the activity exists? I don't think I can catch the runtime exception since startActivity() doesn't throw it.

5条回答
做个烂人
2楼-- · 2019-01-06 17:32

I ended up doing:

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

This ensures that the google-specific Add Account intent exists, and if not, falls back on the general more general ACTION_ADD_ACCOUNTS.

查看更多
贪生不怕死
3楼-- · 2019-01-06 17:34

I don't think I can catch the runtime exception

Actually, this works:

try {
    startActivity(new Intent(..));
} catch (ActivityNotFoundException e) {
    Toast.makeText(this, "Not installed.", LENGTH_SHORT).show();
}
查看更多
等我变得足够好
4楼-- · 2019-01-06 17:41

This is the simplest way to do this:

boolean activityExists = intent.resolveActivityInfo(getPackageManager(), 0) != null;

It is also the one recommended by Google:

To first verify that an app exists to receive the intent, call resolveActivity() on your Intent object. If the result is non-null, there is at least one app that can handle the intent and it's safe to call startActivity(). If the result is null, you should not use the intent and, if possible, you should disable the feature that invokes the intent.

查看更多
The star\"
5楼-- · 2019-01-06 17:45

Here's how I check if an Activity is available on the device:

        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);
        }
查看更多
干净又极端
6楼-- · 2019-01-06 17:49

You could create an Intent object with necessary component info and then check if the intent is callable or not.I stumbled upon this snippet here on SO, don't have the link to the actual thread.

private boolean isCallable(Intent intent) {
        List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, 
            PackageManager.MATCH_DEFAULT_ONLY);
        return list.size() > 0;
}
查看更多
登录 后发表回答