intent.resolveActivity != null but launching the intent throws an ActivityNotFound exception
Asked Answered
M

2

25

I post this question here for educational purposes, since I couldn't find answers anywhere and eventually found the root cause the old way, i.e. by myself.

Here's the problematic code :

// initially getting the intent from polling the PackageManager about activities resolving Search intent.

ComponentName componentName = intent.resolveActivity(pm);

if (componentName != null) {
    context.startActivity(intent);
}

despite the check i get an ActivityNotFound exception.

EDIT: apparently the point wasn't obvious to everyone so : how come there's an activity resolving the intent, yet trying to launch it throws an ActivityNotFound exception - two facts apparently contradictory ?

Multilateral answered 18/3, 2014 at 12:20 Comment(0)
M
35

From what i could see, intent.resolveActivity() will return true if there is ANY activity resolving this intent. Even if this activity is not exported (which makes it unusable for all practical purposes in case it's not from your package). Android's API doesn't care to mention that, so you have to figure it out by yourself, and make sure that the activity you're trying to launch is indeed exported.

ActivityInfo activityInfo = intent.resolveActivityInfo(pm, intent.getFlags());
if (activityInfo.exported) {
    doSomething();
}

EDIT: the point of this question is that ResolveActivity will return a componentName even if activityInfo.exported==false AND it's not from your own package - which makes it unlaunchable, and surprised me cause the intent was resolved and yet unlaunchable.

Multilateral answered 18/3, 2014 at 12:20 Comment(6)
I'm confused. To me, it appears that Intent.resolveActivity only has one parameter and returns a ComponentName.Penalty
@MooingDuck the method used in the answer is resolveActivityInfo() not resolveActivity()Jean
Your solution is great, but wouldn't it be easier just to wrap code that starts the activity in try block and catch exception if there is no browser to handle intent, and maybe inform the user that there is no web browser installed or that the app is in restricted mode?Piperine
Great solution, just needs a null check as activityInfo can be null.Germayne
@Markonionini You could do that, but it's generally considered better to save exceptions for truly exceptional behavior. thefinestartist.com/effective-java/57Scuppernong
Thanks! It has been working until API 29. Currently when opening URL in API 30 emulator it returns intent.resolveActivityInfo(pm, intent.getFlags()) == null and intent.resolveActivity(pm) == null. See #62536356 for more info. Or use #5883156.Distillate
M
3

ActivityNotFound exception is thrown when a call to startActivity(Intent) or one of its variants fails because an Activity can not be found to execute the given Intent. For example, if you’re trying to send an email, but there is no app on your device that could process ACTION_SEND intent action, ActivityNotFound will be thrown.

A way to avoid the exception is to do the following:

final ComponentName componentName = intent.resolveActivity(pm);
if (componentName != null) {
  try {
    context.startActivity(intent);    
  } catch (ActivityNotFoundException ex) {
    // Notify the user?
  }
}
Miguel answered 18/3, 2014 at 12:39 Comment(4)
I know that, that was not my point :) I wanted to draw the attention to the fact that resolveActivity returns a componentName even if exported==false AND it's not from your own package - which makes it unlaunchable. For my particular use, which i didnt include here, i simply filtered the results i got from the pm manager when looking for specific intents with the if(exported) check.Multilateral
Well, there is no way of knowing what your point is, if you leave it out of your question. Glad you figured it out.Miguel
I added it to the answer - i'll add it to the question. Thanks for your input.Multilateral
@Miguel The original question contained the point if the edit history doesn't lie. You should realize that it's a little bit strange if ActivityNotFoundException occurs if componentName isn't null.Alcaic

© 2022 - 2024 — McMap. All rights reserved.