GoogleChromeLabs / bubblewrap

Bubblewrap is a Command Line Interface (CLI) that helps developers to create a Project for an Android application that launches an existing Progressive Web App (PWAs) using a Trusted Web Activity.
Apache License 2.0
2.39k stars 162 forks source link

Upgraded Bubblewrap sharetarget functionality no longer appears to work? #451

Closed JohnRSim closed 3 years ago

JohnRSim commented 3 years ago

Describe the bug Upgraded bubblewrap created a new build installed - can no longer share to app - App no longer appears within the apps to share to - is there an update with configuration on shareTarget?

{
  "packageId": "com.fishbowlsolutions.smartr.twa",
  "host": "smartr.fishbowlsolutions.com",
  "name": "Smartr",
  "launcherName": "Smartr",
  "display": "standalone",
  "themeColor": "#000000",
  "navigationColor": "#323232",
  "navigationColorDark": "#323232",
  "navigationDividerColor": "#323232",
  "navigationDividerColorDark": "#323232",
  "backgroundColor": "#0B41B8",
  "enableNotifications": true,
  "startUrl": "/?source=twa",
  "iconUrl": "https://smartr.fishbowlsolutions.com/maskable_icon-512.png",
  "maskableIconUrl": "https://smartr.fishbowlsolutions.com/maskable_icon-512.png",
  "splashScreenFadeOutDuration": 300,
  "signingKey": {
    "path": "C:\\work\\androiid\\keystore.jks",
    "alias": "Smartr"
  },
  "appVersionName": "15",
  "appVersionCode": 15,
  "shortcuts": [
    {
      "name": "Home",
      "shortName": "Home",
      "url": "https://smartr.fishbowlsolutions.com/feed/Home",
      "chosenIconUrl": "https://smartr.fishbowlsolutions.com/icons/home.png"
    },
    {
      "name": "Global Mentoring Program",
      "shortName": "GMP",
      "url": "https://smartr.fishbowlsolutions.com/mentoring/featured",
      "chosenIconUrl": "https://smartr.fishbowlsolutions.com/icons/gmp.png"
    },
    {
      "name": "User Settings",
      "shortName": "Settings",
      "url": "https://smartr.fishbowlsolutions.com/settings",
      "chosenIconUrl": "https://smartr.fishbowlsolutions.com/icons/settings.png"
    }
  ],
  "generatorApp": "bubblewrap-cli",
  "webManifestUrl": "https://smartr.fishbowlsolutions.com/manifest.json",
  "fallbackType": "customtabs",
  "features": {},
  "alphaDependencies": {
    "enabled": false
  },
  "enableSiteSettingsShortcut": true,
  "isChromeOSOnly": false,
  "shareTarget": {
    "action": "https://smartr.fishbowlsolutions.com/_share-target",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "title": "name",
      "text": "description",
      "url": "link",
      "files": [
        {
          "name": "media",
          "accept": [
            "audio/*",
            "image/*",
            "video/*"
          ]
        }
      ]
    }
  },
  "orientation": "any",
  "appVersion": "15"
}

To Reproduce bubblewrap update manifest-twa.json bubblewrap build

Expected behavior Expect to open another app select share link and see TWA app icon in the list to share to.

Screenshots N/A

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Add any other context about the problem here.

andreban commented 3 years ago

Running Bubblewrap with the provided twa-manifest.json does seem to add the application to Android's share sheet for me (bottom left in the screenshot):

Screenshot_20210129-141112

The change on 1.9.0 fixed an issue with plain text shares and shouldn't affect files. Here's what the diff between the AndroidManifest.xml generated via 1.8.2 and 1.9.0 looks like:

119,123c119,120
<                     
<                         <action android:name="android.intent.action.SEND" />
<                     
<                         <action android:name="android.intent.action.SEND_MULTIPLE" />
<                     
---
>                     <action android:name="android.intent.action.SEND" />
>                     <action android:name="android.intent.action.SEND_MULTIPLE" />
126,130c123,129
<                         <data android:mimeType="audio/*" />
<                     
<                         <data android:mimeType="image/*" />
<                     
<                         <data android:mimeType="video/*" />
---
>                         
>                             <data android:mimeType="audio/*" />
>                         
>                             <data android:mimeType="image/*" />
>                         
>                             <data android:mimeType="video/*" />
>                         

There's some formatting differences, due to the templating, but all the necessary items are still there. Could you share what app/src/main/AndroidManifest.xml looks like for you?

JohnRSim commented 3 years ago

Sorry; I had selected Twitter share and thought it was working to share through to the app but it didn't appear - then tried gallery and couldn't see the icon just tried gallery now and all is working.

I must of missed the icon display. Will take a look see what I missed with Twitter target share and text.

Screenshot_20210129-233451_Android System.jpg

JohnRSim commented 3 years ago

Attaching manifest

<!--
    Copyright 2019 Google Inc. All Rights Reserved.

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- The "package" attribute is rewritten by the Gradle build with the value of applicationId.
     It is still required here, as it is used to derive paths, for instance when referring
     to an Activity by ".MyActivity" instead of the full name. If more Activities are added to the
     application, the package attribute will need to reflect the correct path in order to use
     the abbreviated format. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fishbowlsolutions.smartr.twa">

    <application
        android:name="Application"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/appName"

        android:manageSpaceActivity="com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity"

        android:supportsRtl="true"
        android:theme="@android:style/Theme.Translucent.NoTitleBar">

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

            <meta-data
                android:name="web_manifest_url"
                android:value="@string/webManifestUrl" />

        <meta-data
            android:name="twa_generator"
            android:value="@string/generatorApp" />

            <activity android:name="com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity">
            <meta-data
                android:name="android.support.customtabs.trusted.MANAGE_SPACE_URL"
                android:value="@string/launchUrl" />
            </activity>

        <activity android:name="LauncherActivity"
            android:screenOrientation="unspecified"
            android:alwaysRetainTaskState="true"
            android:label="@string/launcherName">
            <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.NAVIGATION_BAR_COLOR"
                android:resource="@color/navigationColor" />

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

            <meta-data
                android:name="androix.browser.trusted.NAVIGATION_BAR_DIVIDER_COLOR"
                android:resource="@color/navigationDividerColor" />

            <meta-data
                android:name="androix.browser.trusted.NAVIGATION_BAR_DIVIDER_COLOR_DARK"
                android:resource="@color/navigationDividerColorDark" />

            <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/backgroundColor"/>

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

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

            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />

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

                <meta-data
                    android:name="android.support.customtabs.trusted.METADATA_SHARE_TARGET"
                    android:resource="@string/shareTarget"/>

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

                <intent-filter>

                        <action android:name="android.intent.action.SEND" />

                        <action android:name="android.intent.action.SEND_MULTIPLE" />

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

                        <data android:mimeType="audio/*" />

                        <data android:mimeType="image/*" />

                        <data android:mimeType="video/*" />

                </intent-filter>

            <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="@string/hostName"/>
            </intent-filter>
        </activity>

        <activity android:name="com.google.androidbrowserhelper.trusted.FocusActivity" />

        <activity android:name="com.google.androidbrowserhelper.trusted.WebViewFallbackActivity"
            android:configChanges="orientation|screenSize" />

        <provider
            android:name="androidx.core.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=".DelegationService"
            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>
JohnRSim commented 3 years ago

@andreban Looking at: https://developers.google.com/web/android/trusted-web-activity/web-share-target and the scrapbook pwa.

Is it only possible to use target share to share content with Media or without based on manifest configuration. ie if you have in your manifest 'files:' then you can't share a link without media to your app and visa versa?..

So the manifest example below I cannot use the twitter app to share text and link to my TWA but can use gallery app to share photos..

Maybe I've missed a parameter looking into it more. Ideally I want to share either links or media to the app. And use both Twitter share and gallery image share target to point to my twa.

  "shareTarget": {
    "action": "https://smartr.fishbowlsolutions.com/_share-target",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "title": "name",
      "text": "description",
      "url": "link",
      "files": [
        {
          "name": "media",
          "accept": [
            "audio/*",
            "image/*",
            "video/*"
          ]
        }
      ]
    }
  },
andreban commented 3 years ago

Reading through the docs / spec, it seems that if param contains title, text or url we should add text/plain to the intent-filter.

andreban commented 3 years ago

So, this section would become something like:

    if(twaManifest.shareTarget?.params?.url 
            || twaManifest.shareTarget?.params?.title 
            || twaManifest.shareTarget?.params?.url) {
          shareTargetIntentFilter.mimeTypes.push('text/plain');
    }
    if (twaManifest.shareTarget?.params?.files) {
      shareTargetIntentFilter.actions.push('android.intent.action.SEND_MULTIPLE');
      for (const file of twaManifest.shareTarget.params.files) {
        file.accept.forEach((accept) => shareTargetIntentFilter.mimeTypes.push(accept));
      }
    }
JohnRSim commented 3 years ago

I see - I also added the old approach late last night- with url_template - haven't had time to test yet. to see if that had any impact.

... although I'm guessing url_template is not probably not tracked in the manifest.. Haven't checked.

"shareTarget": {
    "url_template": "https://smartr.fishbowlsolutions.com/_share-target?oldapi=true&title={title}&text={text}&url={url}",
    "action": "https://smartr.fishbowlsolutions.com/_share-target",
    "method": "POST",
rajorpratyush commented 3 years ago

Not able to receive Text( App doesn't even open ), Media share target works properly.