Some custom OS by manufacturers has implemented customized features or hidden features in settings.(example: ColorOS, MIUI, FlymeOS, EMUI) I've tried to open some activities of those system APP. I used context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null
to check if those activities exist.
Even if those activities exist, but when I startActivity(intent);
, sometimes it causes a security exception because the manifest of that activity has declared exported=false
, or it uses some strange permission(Example: <uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE" />
) Additionally, those security variables are not always same on different firmware version, so I need to check them manually. I understand I can use try{} catch{}
to handle startActivity();
and display an error toast when starting it failed.
However, in my APP I would like to list many clickable buttons link to those activities. If I list many buttons and most of them result in showing an error toast when click, this is not definitely a good idea. Instead of showing all the buttons, I need to hide those button points to activities that can not be started even if they exist. If I call startActivity()
with try{} catch{}
to check it one by one, the user will see many activities being launched and I don't want this to happen.
How can I check if the activity of a third-party app can be started, but without actually calling startActivity()
?
The resolveActivityInfo()
method instead of resolveActivity()
to get an ActivityInfo
object. This object extends ComponentInfo
which has an exported
property you can use to see if the Activity is exported.
ActivityInfo info = intent.resolveActivityInfo(context.getPackageManager(),
PackageManager.MATCH_DEFAULT_ONLY);
boolean show = info != null && info.exported;