How to send data from my TWA webapp to my app?
Asked Answered
P

3

14

With Crosswalk I had a very convenient javascript-to-app interface so I could call a java function from javascript and share data from my webapp to my android app.

How can I achieve this with Custom Tabs (or Trusted Web Activity) ?

There seems to be no way at all. There should be, especially when my app and my game/webapp are from the same author.

For example, I do not trust LocalStorage, especially now with Custom Tabs, it may get cleaned, or the user may uninstall the browser and install another one, so the saved data will be lost and the user will be angry at the app for the loss of the saved data, not even understanding that the data were in the browser, not in the app. So I used to have my webapps call the app to save datas.

Another example, when the Custom Tab uses Firefox instead of Chrome, then speech synthesis won't be available. I can detect it easily in my webapp. But I want my webapp to call the app and send it the words to pronounce. That is what I was doing with Crosswalk since it didn't support speech neither.

I understand that webviews are more appropriate for my use than Custom Tabs, but when the webview can't be used on a device (especially Android <5) then my app doesn't have a lot of other options than opening a Custom Tab instead (or Trusted Web Activity if available). I can't use Crosswalk anymore, it is discontinued and still full of serious bugs. And other solutions such as GeckoView or Alibaba Gcanvas are not ready.

edit:

In this article about Trusted Web Activity https://developers.google.com/web/updates/2017/10/using-twa I read

Nevertheless, you can coordinate with the web content by passing data to and from the page in URLs (e.g. through query parameters, custom HTTP headers, and intent URIs.)

edit:

I've been reading many pages, Intents and deep-linking are still obscure to me though, but here is what I tried.

I added an intent filter for a custom action :

<receiver android:name=".OutgoingReceiver" android:enabled="true">
    <intent-filter>
        <action android:name="custom_tabs_js_interface" />
    </intent-filter>
</receiver>

I created a class for that receiver :

public class OutgoingReceiver extends BroadcastReceiver {

    public static final String CUSTOM_INTENT = "custom_tabs_js_interface";

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received" , Toast.LENGTH_SHORT).show();
    }

and I call it in javascript with

location.href="intent:#Intent;action=custom_tabs_js_interface;end";

I don't even pass data for now, I just try to call it. but nothing happens...

Plethora answered 27/8, 2018 at 15:13 Comment(8)
Why don't you save it on the server?Akee
I considered it. I would quickly end up with a gigantic database. There would be a huge amount of useless datas from users who do not use the apps anymore. Tens of thousands of people may try the game, the game would create a save, then they may never use it again. I do not like the idea of removing datas from users who didn't connect for a month or two, they may eventually come back and be mad because their save was deleted, so I prefer saving on the user's device. It is so much more in the scheme of things to save in the app's memory itself than on my server anyway. Also, there are very ...Plethora
... strict laws on what datas I can save from people, I may break a law without even knowing and get in trouble. And it would only work for saves, not for other things like speech synthesis example and other things I was using my js-interface for. :\Plethora
you said: "webview can't be used on a device (especially Android <5)". why can not?Glennaglennie
Before Android 5 the Webview can't be updated, it is a very old version which causes various serious problems for HTML5 games. WebAudio is totally unusable or very buggy and incredibly slow to decode. HTML5Audio is buggy too. It doesn't understand "let" and crashes. And so on. On my two Android 4.4 tablets I run tests on, webview is just unusable for my games. On Android 5 and after, it can be updated and should be ok, but I read that some users disable it for some reason (why?) and it may not be available at all on some tv box. So there are quite a few cases when webview can't be used.Plethora
I wonder, did you find a good solution to your problem?Bathelda
Sadly, no, I didn't. :(Plethora
There should be a solution to call Java Functions from Javascript in TWAs. I have a PWA which acts as a timer/countdown. Many clients are asking for Alarms & the Countdown to show as Notifications. Hope someone finds a solution soon.Imf
Z
10

Yes broadcast receiver doesn't work for some reason, probably security. But you can use an Activity in place of Broadcast Receiver to do this as below.

Use custom Android Intent Uri with custom host, query parameters, package, scheme and intent action. Invoke this intent uri from your javascript/html code. Example

"intent://myhost?key=value#Intent;scheme=myscheme;package=my.app.package;action=someaction;end"

Also declare an activity in the manifest file with intent filter to handle the specific host, scheme & action. Example

<activity android:name="my.app.package.ReceiverActivity">
    <intent-filter>
        <action android:name="someaction" />

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

        <data
            android:host="myhost"
            android:scheme="myscheme" />
    </intent-filter>

</activity>

Now in the activity, handle the intent and extract the data from query parameters. Do whatever you want with the data and probably finish the activity in case you want to go back to the same screen. Example

public class ReceiverActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String value = getIntent().getData().getQueryParameter("key");
        if (value != null) {
            // value is basically your data
        }

        // in case you want to go back to same screen
        finish();
    }
}

And that is it. You have data for your disposal at an Android Activity. This ReceiverActivity could (preferrably) belong to same TWA app. Now from this Receiver Activity, you can easily send/share the data to any other apps. Hope this helps.

Zephaniah answered 26/4, 2020 at 18:55 Comment(4)
Were you able to make this work without navigating away from the TWA?Bathelda
I actually tried extending LauncherActivity and handling the new intent in the same activity, but it causes a Activity re-creation. LaunchMode apparently doesn't seems helping here.Zephaniah
Was anyone able to solve this? My TWA activity keeps getting destroyed or keeps recreating with the help of different launchModesHokeypokey
Hey! Were you ever able to resolve this, so that the TWA app doesn't stop?Jeniferjeniffer
G
0

You can use a hybrid solution:

  1. Use custom tabs as you want for game.

  2. Your server can call your app when is needed using socket programming or push notifications to get the data you need to save in your app.

Also if sending data to your app is unsuccessful your game can warns user in browser at game.

Glennaglennie answered 7/9, 2018 at 9:43 Comment(1)
I didn't know it was possible for a server to call an app. I thought I could only have the app sending requests to the server. That is interesting. Now I am trying with Intents, if it is a dead-end I will try your idea. Thanks.Plethora
Z
0

Support for older android versions is encouraged as far as reasonably possible. Platform versions distribution (https://developer.android.com/about/dashboards/) at the moment this post was written states that you would lose around 12.7% of devices if you drop support for version 4.

Consider raising your minimum version to Lollipop where WebView was moved to an APK and use it. You will gain time and implementation simplicity since you'll be able to call @JavascriptInterface annotated methods while keeping your users engaged inside your app (https://developer.android.com/guide/webapps/webview_.

Ziagos answered 8/9, 2018 at 18:53 Comment(2)
Thanks for your suggestion, but for now I prefer still having a fallback with CustomTab for situations when the webview can't be used. Also, a personal reason why I do not want to raise the minimum version is that two of my three devices I run tests on are stuck on 4.4.Plethora
I understand. I would suggest you consider then using a message broker; it would require the broker running in your backend but you'll be able to cleanly pass messages among your Javascript and Android side. Take a look at RabbitMq which has Java and Javascript libraries as well. rabbitmq.comZiagos

© 2022 - 2024 — McMap. All rights reserved.