10

I've created a browser application with main activity which response to the following intents:

 <intent-filter> 
       <data android:scheme="http"/>
       <data android:scheme="https"/>
       <category android:name="android.intent.category.DEFAULT"/>
       <category android:name="android.intent.category.BROWSABLE"/>
       <action android:name="android.intent.action.VIEW"/>
 </intent-filter>

On url click from other task (gmail, sms) if i choose my application, the activity is open in the same task as the calling task. When I choose different browser (Mozila firefox, chrome, dolphine) they are opening in different task.

Looking on other browsers manifest, I see that no one using android:launchMode="singleTask".

I don't want to use single task flag since it is not recommended by google and also makes me other prolems.

I tried to understand how does other browsers do it but didn't figure it out.

any ideas? is there other way to open my activity in different task without using singleTask flag?

user3398598
  • 423
  • 1
  • 5
  • 10
  • 1
    maybe you can set a flag on the intent launching the activity: Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP check out the documentation: http://developer.android.com/guide/components/tasks-and-back-stack.html http://developer.android.com/reference/android/content/Intent.html – Guy S May 26 '14 at 08:02
  • no, since the applications that send the activity are not mine (gmail for example) – user3398598 May 26 '14 at 08:32
  • 1
    @user3398598, the suggestion from Guy makes sense: you should combine it with the answer from Emanuel - see my comment there. I understand you have already implemented a workaround, but this approach is more simple imho, just for a reference. – Stan Dec 18 '15 at 22:33

3 Answers3

2

You can check in onCreate if the activity is running in a single task. If not just finish() it and create it again with using FLAG_ACTIVITY_NEW_TASK

This may help you

   ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

    for (RunningTaskInfo task : tasks) {
        if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) 
          // check if it's the only one activity or whatever                               
    }
Emanuel
  • 8,027
  • 2
  • 37
  • 56
  • Thanks for your answer, getRunningTasks is only intended for debugging please see: http://developer.android.com/reference/android/app/ActivityManager.html#getRunningTasks(int) – user3398598 May 26 '14 at 14:54
  • 1
    This is the best way, but it should be simplified: there is no need to check running tasks. It's sufficient to check `getData()` in `onCreate` method and if it's not null, restart new instance of the activity with `FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK` passing `Uri` to it via custom extra, and then `finish()` current instance. I'm sure this is how other browsers work – Stan Dec 18 '15 at 22:28
2

I have found the following description on Android Developers site:

As another example, the Android Browser application declares that the web browser activity should always open in its own task—by specifying the singleTask launch mode in the element. This means that if your application issues an intent to open the Android Browser, its activity is not placed in the same task as your application. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.

As you can see android:launchMode=singleTask is the right choice in your case. You already mentioned that you had issues with this property so maybe let's focus on them.

Update 28.05.2014

Note from Google regarding singleTask launchMode:

The other modes — singleTask and singleInstance — are not appropriate for most applications, since they result in an interaction model that is likely to be unfamiliar to users and is very different from most other applications.

singleTask and singleInstance use case from Google:

Specialized launches (not recommended for general use)

As you can see singleTask may not be recommended for general use but your case is not general, actually it's one of the cases where singleTask fits perfectly. In other words, singleTask is not forbidden, it's just need to be used with caution in order to provide end users common experience with your app.

I hope I made it clear now for you. Feel comfortable with this launch mode in your case.

Damian Petla
  • 8,963
  • 5
  • 44
  • 47
  • I've tried it (put my package ID as the Affinity) but it is not working. I think because my task was not started yet, so the activity will open in the calling task. – user3398598 May 26 '14 at 11:25
  • It should be opened in new task even if your activity was not started. Can you tell how do you determine that your activity is in the same task? – Damian Petla May 26 '14 at 12:58
  • Two indications: FIRST: in task manager I see only one task (the messaging task) and when clicking on it i see my activity. SECOND: running "adb shell dumpsys activity" in "Running Activities" i see one task with two activities: mms and my activity. – user3398598 May 26 '14 at 13:07
  • I've put my package name as the Affinity, is that correct? – user3398598 May 26 '14 at 13:12
  • Yes, it's fine. Did you remember to set allowTaskReparenting along with affinity? Can you also explain why do you need your activity to be in the separate task? Maybe we could come up with another solution for the initial reason. – Damian Petla May 26 '14 at 13:28
  • yes, I set allowTaskReparenting flag. as I wrote in the original question, I want my application act like other browsers, but looking in other browsers manifest it seems that no one is setting android:launchMode="singleTask". – user3398598 May 26 '14 at 13:52
  • Hi Loop, do you have any other ideas? – user3398598 May 28 '14 at 07:03
  • Why don't you describe what is your problem with singleTask? As I mentioned, singleTask is used by Google to do what you need. I don't see other option. Besides, singleTask is not recommended for general use. However, it does not apply to your case so you can use it without any worries. Once again, write about your issue with singleTask. – Damian Petla May 28 '14 at 07:28
  • OK, thanks. But there is still an open question: how all other browsers open in a new task without defining this mode? – user3398598 May 28 '14 at 11:07
  • I don't see a point to guess. Maybe they do some workarounds. Can you provide example and show manifest of this example? Anyway, you know what Google do with Android Browser. Is it not the best example to follow? I would say it is. I think this topic can be closed unless you provide info about your issue with singleTask, if there is any. – Damian Petla May 28 '14 at 11:23
1

You're trying to "bend the rules" a little, and you're not clear enough on what you're trying to avoid by not using android:launchMode="singleTask".

So I would suggest researching into either:

  1. Creating a Service and having that Service listen to the intent filter. Then having this Service open your Activity, and having the Activity's affinity set correctly to match the Service's. This would allow you to get over the issue where affinity is not binding the Activity correctly.

  2. Having a silent Activity starting a new Activity and quiting. The silent Activity would start in a new stack (not in a singletask mode), and would shut itself down upon starting the Activity you actually need.

Vaiden
  • 15,728
  • 7
  • 61
  • 91
  • How service could listen the intent filter? It is possible only with activities – Lester Nov 16 '15 at 23:43
  • The simplest way is using an IntentService - http://developer.android.com/reference/android/app/IntentService.html. The boilerplate way is using a BroadcastReceiver - http://stackoverflow.com/questions/4462037/register-receiver-in-a-service. – Vaiden Nov 17 '15 at 14:26