0

We are developing PWA application to submit it to Play Store. We used TWA, followed all concepts but somehow we cant manage to hide the URL BAR.

Digital asset links are configured and tested. We have connected website with TWA, we have successfully tested mapping editor, we have added intent filter, association with assetlinks.json was successfully tested

Android Manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="eu.clubforceone.mobile">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/appName"
        android:supportsRtl="true"
        android:theme="@style/Theme.LauncherActivity">

        <meta-data
            android:name="asset_statements"
            android:resource="@string/assetStatements" />

        <activity
            android:name="android.support.customtabs.trusted.LauncherActivity"
            android:label="@string/appName">
            <tools:validation testUrl="https://login.clubforce.eu" />

            <meta-data
                android:name="android.support.customtabs.trusted.DEFAULT_URL"
                android:value="@string/launchUrl" />

            <meta-data
                android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR"
                android:resource="@color/colorPrimary" />

            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_IMAGE_DRAWABLE"
                android:resource="@drawable/splash" />

            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_SCREEN_BACKGROUND_COLOR"
                android:resource="@color/whiteColor" />

            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_SCREEN_FADE_OUT_DURATION"
                android:value="300" />

            <meta-data
                android:name="android.support.customtabs.trusted.FILE_PROVIDER_AUTHORITY"
                android:value="@string/providerAuthority" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />

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

                <data
                    android:scheme="https"
                    android:host="login.clubforce.eu" />
            </intent-filter>
        </activity>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="@string/providerAuthority"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

        <service
            android:name="android.support.customtabs.trusted.TrustedWebActivityService"
            android:enabled="@bool/enableNotification"
            android:exported="@bool/enableNotification">

            <intent-filter>
                <action android:name="android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

    </application>
</manifest>

build.gradle module app

apply plugin: 'com.android.application'

def twaManifest = [
        applicationId: 'eu.clubforceone.mobile',
        hostName: 'login.clubforce.eu', // The domain being opened in the TWA.
        launchUrl: '/', // The start path for the TWA. Must be relative to the domain.
        name: 'Clubforce', // The name shown on the Android Launcher.
        themeColor: '#283795', // The color used for the status bar.
        backgroundColor: '#F6F6F6', // The color used for the splash screen background.
        whiteColor: '#FFFFFF', // The color used for the splash screen background.
        enableNotifications: false // Set to true to enable notification delegation
]

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "eu.clubforceone.mobile"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 20003
        versionName '2.2'
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // The name for the application on the Android Launcher
        resValue "string", "appName", twaManifest.name

        // The URL that will be used when launching the TWA from the Android Launcher
        resValue "string", "launchUrl", "https://" + twaManifest.hostName + twaManifest.launchUrl

        // The hostname is used when building the intent-filter, so the TWA is able to
        // handle Intents to open https://svgomg.firebaseapp.com.
        resValue "string", "hostName", twaManifest.hostName

        // This variable below expresses the relationship between the app and the site,
        // as documented in the TWA documentation at
        // https://developers.google.com/web/updates/2017/10/using-twa#set_up_digital_asset_links_in_an_android_app
        // and is injected into the AndroidManifest.xml
        resValue "string", "assetStatements",
                '[{ \\"relation\\": [\\"delegate_permission/common.handle_all_urls\\"],' +
                        '\\"target\\": {\\"namespace\\": \\"web\\", \\"site\\": \\"https://' +
                        twaManifest.hostName + '\\"}}]'

        // This attribute sets the status bar color for the TWA. It can be either set here or in
        // `res/values/colors.xml`. Setting in both places is an error and the app will not
        // compile. If not set, the status bar color defaults to #FFFFFF - white.
        resValue "color", "colorPrimary", twaManifest.themeColor

        // Sets the color for the background used for the splash screen when launching the
        // Trusted Web Activity.
        resValue "color", "backgroundColor", twaManifest.backgroundColor

        // used only for specific situation where white color is needed
        resValue "color", "whiteColor", twaManifest.whiteColor


        // Defines a provider authority fot the Splash Screen
        resValue "string", "providerAuthority", twaManifest.applicationId + '.fileprovider'

        // The enableNotification resource is used to enable or disable the
        // TrustedWebActivityService, by changing the android:enabled and android:exported
        // attributes
        resValue "bool", "enableNotification", twaManifest.enableNotifications.toString()
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    productFlavors {
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.github.GoogleChrome.custom-tabs-client:customtabs:91b4a1270b511ce70245d3440e6267762c5f1c6b'
}

assetLinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "eu.clubforceone.mobile",
    "sha256_cert_fingerprints":
    ["CD:D5:D1:54:AC:8F:17:0B:8A:E6:5D:0F:C2:07:1D:FC:D7:2C:16:EE:66:A4:D9:F6:DA:1C:57:12:1B:57:A5:F9"]
  }
}]

I just have no idea what to do...

This is my result from running "keytool -list -printcert -jarfile app-release.apk"

Signer #1:

Signature:

Owner: deleted for privacy reason
Issuer: deleted for privacy reason
Serial number: 6beb859e
Valid from: Sun Apr 01 14:33:45 CEST 2018 until: Thu Aug 17 14:33:45 CEST 2045
Certificate fingerprints:
     MD5:  29:FC:96:6C:FC:D0:E4:69:BC:BC:B1:95:01:DA:6D:2D
     SHA1: 00:7E:76:27:F9:5E:51:83:6A:77:70:57:90:A1:B7:56:66:66:A3:99
     SHA256: CD:D5:D1:54:AC:8F:17:0B:8A:E6:5D:0F:C2:07:1D:FC:D7:2C:16:EE:66:A4:D9:F6:DA:1C:57:12:1B:57:A5:F9
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 06 A2 63 AE E8 BD 9A 56   00 66 4E 8B 9C 09 EA 13  ..c....V.fN.....
0010: 20 C8 E5 4E                                         ..N
]
]

3 Answers3

0

You could use PWA2APK to simplify the procedure: PWA2APK

Gary Vernon Grubb
  • 9,695
  • 1
  • 24
  • 27
  • Gary do you know anything about this https://stackoverflow.com/questions/65092260/problems-when-updating-pwa-app-built-with-pwa2apk-on-google-play – uber Dec 01 '20 at 14:33
0

The 'package_name' field in the 'assetlinks.json' file needs to point to the application package-name (which is the same as the applicationId).

Here's what the assetlinks.json file should look like:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "eu.clubforceone.mobile",
    "sha256_cert_fingerprints":
    ["CD:D5:D1:54:AC:8F:17:0B:8A:E6:5D:0F:C2:07:1D:FC:D7:2C:16:EE:66:A4:D9:F6:DA:1C:57:12:1B:57:A5:F9"]
  }
}]
andreban
  • 4,621
  • 1
  • 20
  • 49
  • Thanks and sorry. It was my typo, package name is correctly configured, i have edited my post – user7618449 Aug 17 '19 at 09:15
  • I saw you updated https://login.clubforce.eu/.well-known/assetlinks.json too. Can you force-close Chrome and re-open the TWA? Can you run the following command for your APK and post the result: `keytool -list -printcert -jarfile app.apk`` – andreban Aug 17 '19 at 09:20
  • A couple of follow-up questions: I noticed the initial URL is https://login.clubforce.eu. Does the domain change once the user logs in? If that's the case, you need to validate the other domain too. – andreban Aug 17 '19 at 10:20
  • Nope. The initial is login.clubforce.eu. If there is no cookie than user is redirected to login.clubforce.eu/login. If user logs in then he will get home view which is located on login.clubforce.eu. Only connections done to other domains are some of the javascript assets, like jquery cdn. – user7618449 Aug 17 '19 at 10:34
  • Gotcha. The config looks right, but I may be missing something. Would you be able to share the APK? – andreban Aug 17 '19 at 12:16
  • Is it possible to send you APK privately? – user7618449 Aug 19 '19 at 12:16
  • Could DM a link to me on Twitter? (@andreban) – andreban Aug 20 '19 at 08:19
0

If you're letting the Play store manage your signatures, check that your assetlinks.json contains the SHA215 from your Play store settings rather than the one generated by keytool. As described in this other answer.

That said, I'm in the same situation as you. I also can't remove the URL bar from my TWA app.

  • I'd be happy to take a look at the APK and help figure out what's wrong. – andreban Aug 18 '19 at 15:04
  • Thanks for the kind offer, @andreban. I've put the APK here: thelocal.com/app/release.apk and you can reach me direct at tech@thelocal.com. – Carpet Münchner Aug 19 '19 at 09:31
  • Update to above: There was an error in my assetlinks.json, the finger print mistakenly included the "SHA-256: " prefix. I removed that, and now our app works without showing the URL bar. – Carpet Münchner Aug 19 '19 at 12:37