darryncampbell / darryncampbell-cordova-plugin-intent

General purpose intent shim layer for cordova appliations on Android. Handles various techniques for sending and receiving intents.
MIT License
86 stars 130 forks source link

Inconsistent task behaviour when sharing intents to app #117

Closed nero120 closed 4 years ago

nero120 commented 4 years ago

Hi there, first of all thank you for this incredibly useful plugin! I've spent hours trying to figure this problem out and I've not managed to get to the bottom of it, so I'm opening this issue as hopefully you may know the answer. I'm not sure if this is due to the behaviour of the plugin or android itself as I'm not an android dev, and even reading the android dev docs hasn't cleared it up for me!

So my scenario is sharing a url from a browser (e.g. Brave) to my app where I experience two inconsistent behaviours. If I am in Brave:

  1. I open the app menu and click the share button, the share sheet appears and I see my app. I select my app and it opens as a new activity in the current task (i.e. in the Brave app window).
  2. I am viewing a web page, I highlight a url shown as text within the page content and the context menu appears. I click "Share", the share sheet appears and I see my app. I select my app and it opens as a new task or opens the existing task that my app was already running in the background (i.e. in my app's own window).

The inconsistencies between the two are causing navigation issues for my app and I can't find a way of making them consistent. I would like it so that when sharing to my app, either it always opens as a new activity in the current task or it always opens a separate task.

For context, my app's main activity launchMode is set to singleTask, but I've also tried singleTop and singleInstance but see no difference in behaviour in either case. My app is registered for the following intents:

<intent-filter android:label="@string/intent_label">
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
</intent-filter>

I've also checked the intent data being shared in both cases hoping that Brave was controlling this by the flags set in the intent, but this doesn't seem to be the case as the flags are identical in both cases. For reference, the intent data for both scenarios are as follows:

1:

{
    "clipItems": [
        {
            "uri": "content://com.brave.browser.FileProvider/BlockedFile_357257258343574",
            "type": "application/octet-stream",
            "extension": "bin"
        }
    ],
    "type": "text/plain",
    "extras": {
        "android.intent.extra.SUBJECT": "DuckDuckGo — Privacy, simplified.",
        "android.intent.extra.TEXT": "https://www.duckduckgo.com/",
        "org.chromium.chrome.extra.TASK_ID": 13273,
        "share_screenshot_as_stream": "content://com.brave.browser.FileProvider/BlockedFile_357257258343574"
    },
    "action": "android.intent.action.SEND",
    "flags": 318767105,
    "component": "ComponentInfo{com.xBrowserSync.android/com.xBrowserSync.android.MainActivity}"
}

2:

{
    "clipItems": [
        {
            "text": "https://www.duckduckgo.com/"
        }
    ],
    "type": "text/plain",
    "extras": {
        "android.intent.extra.TEXT": "https://www.duckduckgo.com/"
    },
    "action": "android.intent.action.SEND",
    "flags": 318767105,
    "component": "ComponentInfo{com.xBrowserSync.android/com.xBrowserSync.android.MainActivity}"
}

Currently, my app picks up the intent data using window.plugins.intentShim.getIntent in either onDeviceReady or onResume, and then decides what to do with the intent. I considered running window.plugins.intentShim.startActivity at this point to force the app to reopen in a new task but then decided against it as the experience would not be great for the user plus I'd still need to understand which context the app was opening in, hence the problem above.

If possible, can you tell me:

  1. Why is this happening and what is responsible for this behaviour - is it Brave, android itself or something about the plugin?
  2. If I can resolve this behaviour to be consistent, how best to accomplish this?

I understand this may be stretching more into the android dev sphere than your plugin but if you're willing I could really use the help. Many thanks! 🙇

darryncampbell commented 4 years ago

Those flags correspond to the following:

FLAG_GRANT_READ_URI_PERMISSION
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_FORWARD_RESULT
FLAG_ACTIVITY_PREVIOUS_IS_TOP

Have you tried specifying the launchMode as standard? If you specify singleTop you would need to receive the Intents via the onIntent() method, not through getIntent()

Why is this happening and what is responsible for this behaviour - is it Brave, android itself or something about the plugin?

I honestly don't know I'm afraid, you have done the hard work and there is no difference in the Intent being sent by Brave. The plugin does not change the launchMode (Android manifest changes are at https://github.com/darryncampbell/darryncampbell-cordova-plugin-intent/blob/master/plugin.xml). I did try downloading your app and testing the scenarios you describe (though I didn't create a sync ID) - both cases looked consistent to me on a Pixel 4, Android 10.

nero120 commented 4 years ago

@darryncampbell thanks so much for the response. Yes, it's the same when I use standard for launchMode. I did notice something interesting though based on your response, you said when you tried my app the experience was consistent. I didn't think to check with sharing from Chrome browser and in fact the experience is consistent when sharing both from the app menu and context menu, the apps open in separate tasks.

So, I can only think that it is indeed something to do with how Brave is initiating the sharing or sending the intent, though my android knowledge is insufficient to explain what.

Thanks again for your help!