tabris-js
tabris-js copied to clipboard
ActionSheet or app.launch() issue on Android 11/12
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();
Anything in logcat in the prod build?
Also, app.launch returns a promise, so you can add a .catch clause which may reveal an error
Thanks, I'll try this and get back to you with any findings.
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.
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.
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>
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.
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
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.
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.
Thanks @mpost :+1: I'll give these a try and get back to you to confirm. I really appreciate your help.
We're using the 3.9 nightly and I can confirm this is resolved now. Thank you!
@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
I just had to use the nightly build and no changes were no needed to the config.xml or AndroidManifest.xml :+1:
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.
Can you build pinned to an older version that worked?
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.
I was referring to one of the nightly builds (which is what your last successful build would have used)