tabris-js icon indicating copy to clipboard operation
tabris-js copied to clipboard

ActionSheet or app.launch() issue on Android 11/12

Open violuke opened this issue 4 years ago • 18 comments

Problem description

  • Android App released with Tabris 3.7.2 (not 3.8 because the cloud build is broken).
  • We're receiving reports that Google Maps/Waze is not opening when people use the buttons on an ActionSheet using Android devices.
  • No reports of issues on iOS (built on 3.8 as cloud build works).
  • When we test using the Tabris.js development app (which is using 3.7.1 I think) this work perfectly on both iOS and Android 10 and Android 11 (we have not Android 12 test device yet).
  • Multiple users have been reporting this issue on Android 11 and 12 with our released app.
  • Our own cloud built app doesn't open Google Maps/Waze on our Android 11 Samsung A40. Nothing appears to happen at all when using the action button, but with the Tabris.js development app, it works perfectly so it's hard to get further insight in errors. The ActionSheet does hide when an action button is touched.
  • The Tabris.js test app built with 3.7.2 or ideally 3.8 would be useful here for test.

Expected behavior

Google Maps or Waze should be launched

Environment

  • Tabris.js version: 3.7.1, 3.7.2 and 3.8 (see above)
  • Device/OS: Works on Honor Android 10. Doesn't work on Samsung A40 Android 11. Reports from Android 12 Samsung devices too. No known issues with iOS.

Code snippet

        let lat = 51.507351;
        let lon = -0.127758;

        let actions = [
            {title: 'Google Maps'},
        ];

        if (device.platform == "iOS") {
            actions.push({title: 'Apple Maps'});
        }

        actions.push({title: 'Waze'});

        actions.push({title: 'Cancel', style: 'cancel'});

        let lat_lon = encodeURIComponent(lat + "," + lon);

        new ActionSheet({
                title: 'Which map app would you like to use?',
                actions: actions
            })
            .onSelect(function(action){
                switch (String(action.action)) {
                    case 'Google Maps':
                        app.launch("https://www.google.com/maps/dir/?api=1&travelmode=driving&dir_action=navigate&destination=" + lat_lon);
                        break;
                    case 'Apple Maps':
                        app.launch("http://maps.apple.com/?dirflg=d&daddr=" + lat_lon);
                        break;
                    case 'Waze':
                        app.launch("https://waze.com/ul?ll=" + lat_lon + "&navigate=yes");
                        break;
                }
            })
            .open();

violuke avatar Dec 02 '21 10:12 violuke

Anything in logcat in the prod build?

cookieguru avatar Dec 02 '21 10:12 cookieguru

Also, app.launch returns a promise, so you can add a .catch clause which may reveal an error

cookieguru avatar Dec 02 '21 11:12 cookieguru

Thanks, I'll try this and get back to you with any findings.

violuke avatar Dec 02 '21 12:12 violuke

With the .catch we're getting Error: No receiver found. I'm not really sure what this means or how to resolve it, to be honest, so any help would be much appreciated. (Or another alternative solution to launching these URLs/apps). Cheers.

violuke avatar Dec 02 '21 12:12 violuke

I might be wrong, but I think the issue might have been caused by us having changed android-targetSdkVersion from 29 to 30. This would also explain why Android 10 seems to be ok, but Android 11 & 12 are not (or at least it would be a big coincidence).

We now have a broken app in production and we cannot release an update with SDK 29 as Google doesn't allow submitting apps targeting SDK 29 anymore (since November).

The current broken app released to production was built on 3.7.2, but the prior version of our app (which didn't have this issue) was also on 3.7.2. The changes in the app are completely unrelated to this area of the code, with the only change in the broken release being the SDK update from 29 to 30.

It looks to me like this is an issue with Tabris itself, so any help would be much appreciated. Thank you.

violuke avatar Dec 02 '21 14:12 violuke

When targeting Android 11+ the system requires to declare the share target in its manifest. This was a platform change in Android 11. See https://developer.android.com/training/package-visibility

More details indos can be found here: https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9.

So for example you would need to declare <queries> in your AndroidManifest.xml:

<manifest package="com.example">
    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>
    ...
</manifest>

mpost avatar Dec 03 '21 08:12 mpost

To simplify the usage of the launch api on Android the tabris framework could also just attempt to launch the given url without checking first if there would be a receiver. Then any thrown exception could be returned as an error promise.

mpost avatar Dec 03 '21 09:12 mpost

Thanks, I've been through quite a few attempts here, but I'm struggling to get this into the AndroidManifest.xml file in the right way.

I think I'm right in saying that I should be doing this via the config.xml file?

I've been trying things along the lines of:

  <platform name="android">
        <preference name="android-targetSdkVersion" value="30"/>

        <!-- Required for opening Waze/Google Maps, see https://github.com/eclipsesource/tabris-js/issues/2202 -->
        <edit-file target="AndroidManifest.xml" parent="/manifest/application/manifest" mode="merge">
            <queries>
                <intent>
                    <action android:name="android.intent.action.MAIN" />
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <category android:name="android.intent.category.LAUNCHER" />
                    <data android:scheme="https" />
                </intent>
            </queries>
        </edit-file>

...

The cloud build on Tabris succeeds, but the resulting app has the same issue. Any help here would be much appreciated. Thanks

violuke avatar Dec 03 '21 12:12 violuke

Sorry if I'm being stupid here, I've only ever built an app using Tabris, so I'm not hugely familiar with Cordova or AndroidManifest.xml. Any help would be much appreciated.

Is this not something that should be in the base Tabris config too? Such that the app.launch() function will continue to be usable in the next release of the Tabris.js developer app? I presume it's only working in that app as you've not yet released an update targeting SDK version 30?

Thanks again, any help would be much appreciated as we've got a bug currently in our live app.

violuke avatar Dec 07 '21 11:12 violuke

You are right that you have to build the app to let the settings take effect.

In order to hit the correct filter target you have to make sure to match the receivers <intent-filter>. Eg to view a website you should use:

<manifest ..> 
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="http" />
        </intent>
    </queries>
</manifest> 

The correct way to make the changes in the AndroidManifest.xml is outlined in: https://cordova.apache.org/docs/en/latest/plugin_ref/spec.html#edit-config.

So for you this would be (untested)

<edit-config file="AndroidManifest.xml" target="/manifest/queries" mode="merge">
    <intent>
         <action android:name="android.intent.action.VIEW" />
         <data android:scheme="http" />
   </intent>
</edit-config>

This would allow you to eg. tabris.app.launch('http://google.com').


We have now removed the internal check for a possible receiver as mentioned in the comment above. This is now available in the 3.9 'nightly'. For versions below you can follow the solution outlined above.

mpost avatar Dec 08 '21 14:12 mpost

Thanks @mpost :+1: I'll give these a try and get back to you to confirm. I really appreciate your help.

violuke avatar Dec 09 '21 08:12 violuke

We're using the 3.9 nightly and I can confirm this is resolved now. Thank you!

violuke avatar Dec 09 '21 17:12 violuke

@violuke was the fix to use the nightly build (and thus the new native code) or was it necessary to add entries to AndroidManifest.xml? If the latter I'd like to update the docs

cookieguru avatar Dec 09 '21 19:12 cookieguru

I just had to use the nightly build and no changes were no needed to the config.xml or AndroidManifest.xml :+1:

violuke avatar Dec 13 '21 12:12 violuke

We're now unable to build a 3.9.x nightly app as we also depend on 3.8.0 tabris-decorators and this causes the build command to fail (it didn't used to) with conflicting dependencies.

I've tried many permutations of how to add this to the config.xml and been unable to do so in a way that works. Currently, I have the following:

    <config-file parent="application/activity/intent-filter" target="AndroidManifest.xml">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" />
        <data android:scheme="https" />
    </config-file>

This builds ok, but I get the same error when trying to launch another app.

Based on Cordova docs, I have also tried

<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />

But again this hasn't solved the problem. Can you please help? Or help us use 3.9 with decorators again. Thank you.

violuke avatar Sep 20 '22 19:09 violuke

Can you build pinned to an older version that worked?

cookieguru avatar Sep 21 '22 01:09 cookieguru

I've tried 3.8.0 and that doesn't work. I couldn't get it to pin to 3.7.x, I'm sorry, I cannot remember the reason.

I have now resolved our use-case by replacing these calls with the use of https://github.com/dpa99c/phonegap-launch-navigator as we only need (at this stage) to launch navigation apps (and building with 3.8.0). When will 3.9 be released? This would resolve this properly, I think.

violuke avatar Sep 21 '22 08:09 violuke

I was referring to one of the nightly builds (which is what your last successful build would have used)

cookieguru avatar Sep 21 '22 08:09 cookieguru