Reputation: 1704
Steps to reproduce:
val url = "https://mylink.com"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
val resolveInfo = context.packageManager.resolveActivity(intent, 0)
if (resolveInfo != null) {
startActivity(intent)
} else {
// error handling because no browser is installed
}
My app crashes with:
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=https://mylink.com.... cmp=com.mxtech.videoplayer.ad/com.mxtech.videoplayer.ActivityWebBrowser } from ProcessRecord{64f9702 20760:com.myapp/u0a65} (pid=20760, uid=10065) not exported from uid 10139
at android.os.Parcel.createException + 1966(Parcel.java:1966)
at android.os.Parcel.readException + 1934(Parcel.java:1934)
at android.os.Parcel.readException + 1884(Parcel.java:1884)
at android.app.IActivityManager$Stub$Proxy.startActivity + 3618(IActivityManager.java:3618)
at android.app.Instrumentation.execStartActivity + 1673(Instrumentation.java:1673)
at android.app.Activity.startActivityForResult + 4689(Activity.java:4689)
at androidx.fragment.app.FragmentActivity.startActivityForResult + 767(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult + 4647(Activity.java:4647)
at androidx.fragment.app.FragmentActivity.startActivityForResult + 754(FragmentActivity.java:754)
at android.app.Activity.startActivity + 5008(Activity.java:5008)
at android.app.Activity.startActivity + 4976(Activity.java:4976)
at com.myapp.MyActivity.someFunction
I only see this issue if all browsers are uninstalled/disabled. It appears that MX Player installs itself as a browser in this situation, but can't handle opening links from my app.
Upvotes: 7
Views: 1934
Reputation: 3711
Your intent is an implicit intent, so it does not specify the app component to start, somehow only an app that can start is MX Player, and that app, actual the com.mxtech.videoplayer.ad/com.mxtech.videoplayer.ActivityWebBrowser
do not expose to outside, that why an error occurred
To cover this case, I think we should handle the case no browser installed by the way open a Webview, inside the app
try {
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(your_link));
startActivity(myIntent);
} catch (ActivityNotFoundException e | SecurityException e) {
// open a Webview
}
Upvotes: 0
Reputation: 556
You can check the Activity to view the URL is resolved and exported with something like this:
private fun openUrl(url: String?) {
if (url == null) return
val intent = Intent(Intent.ACTION_VIEW)
intent.addCategory(Intent.CATEGORY_DEFAULT)
intent.data = Uri.parse(url)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
activity?.let {
val activityInfo = intent.resolveActivityInfo(it.packageManager, intent.flags)
if (activityInfo != null && activityInfo.exported) {
ActivityCompat.startActivity(it, intent, null)
}
}
}
Upvotes: 10