Mykhailo Gaidai
Mykhailo Gaidai

Reputation: 3160

How to have several BROWSABLE activities in single app?

I have an application with 2 activities, that should respond to android.intent.action.VIEW. They are defined like in manifest

<activity android:name=".FirstActivity">
    <intent_filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="my_callback1"/>
    </intent_filter>
</activity>
<activity android:name=".SecondActivity">
    <intent_filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="my_callback2"/>
    </intent_filter>
</activity>

my_callback1 is launched by default Browser activity. It's a Twitter authorization callback, so it's probably something like this

Browser is redirected to the url my_callback1://callback?token=0123456789abcdef

my_callback2 is launched by custom Linkify filter like that:

Linkify.addLinks(textView, pattern, null, matcher, new Linkify.TransformFilter() {
    @Override
    public String transformUrl(Matcher match, String url) {
    return "my_callback2://".concat(url);
    }
});

And both callbacks are not working, IF android.intent.category.DEFAULT is not added to the intent filter. If DEFAULT is added to any of the intent filter, corresponding callback starts to work normally. If set to none of to both at the same time - none of the callback works(I receive android.content.ActivityNotFoundException)

Upvotes: 2

Views: 4170

Answers (3)

dullb0yj4ck
dullb0yj4ck

Reputation: 39

My answer to this comes bit late for the original asker but this particular question is very much worth answering and was instead misunderstood. I was also struggling with making more than one activity browsable in order to handle redirects from a web page back into different parts of my app. This is basically unsupported in android because in order to make an activity browsable you also have to make it default and that means that you can't have more than one browsable activity. If you mark multiple activities as browsable and default it becomes impossible to create an intent URI that correctly differentiates because component info is ignored in the when the uri is unpacked.

However, you can accept parameters when you get intents from a browser and use them have a new BrowsableActivity launch the activities you originally wanted to launch. The browser has to hit link that looks like:

<a href="intent:#Intent;component=my.app.package/.activity.BrowsableActivity;S.my.app.package.activity.BrowsableActivity.PARAMETER_NAME=activityName;end">

The key is to make a new BrowsableActivity for your app. Set the intent-filter for only that activity to BROWSABLE like this:

<activity android:name="BrowsableActivity">
    <intent_filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent_filter>
</activity>

then in the code for the Activity you unpack your parameter:

   @Override
   protected void onCreate(Bundle savedInstanceState) {
    Intent intent = getIntent()
    String otherActivityName = (String) intent.getSerializableExtra(PARAMETER_NAME);
    if (otherActivityName == firstOne) {
       // create an intent and launch the first activity
    } else {
      // create an intent and launch the other activity
    }
  }

Now you can launch any activity you want from within your browsable activity and if necessary you can pass extra parameters to that activity as well, just by unpacking them from the intent of the BrowsableActivity and passing it on to the others.

Upvotes: 3

Paul
Paul

Reputation: 1947

I just ran across this issue and added DEFAULT to each intent-filter based on one of the comments. That seemed to work for me. So each activity's intent-filter has:

<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

Upvotes: 1

David Wasser
David Wasser

Reputation: 95578

The browser adds android.intent.category.BROWSABLE to the Intents that it launches. So you need to have that category in your filter if you want the Intent resolution to work.

From the documentation for IntentFilter:

Categories match if all of the categories in the Intent match categories given in the filter. Extra categories in the filter that are not in the Intent will not cause the match to fail. Note that unlike the action, an IntentFilter with no categories will only match an Intent that does not have any categories.

Upvotes: 0

Related Questions