How can I use NFC to redirect to or open my Progressive Web App?

前端 未结 2 1834
死守一世寂寞
死守一世寂寞 2020-12-30 18:05

I\'ve got a progressive web app, app.example.com created using Chrome\'s \"Add to Home Screen\" button on Android.

I have an NFC tag that ordinarily op

相关标签:
2条回答
  • 2020-12-30 18:12

    Can confirm, Android 8, links on other websites or from other apps open the PWA just fine, but the NFC intent opens Chrome. Here is another workaround that doesn't require you to install a native helper APK:

    Create a simple redirect HTML file pwa.html and serve it from a different domain, let's say other.example.com:

    <html>
        <body><a id="link"></a></body>
        <script type="text/javascript">
            var a = document.getElementById('link');
            // set the target link as desired, may add routes and params etc.
            a.href = "https://app.example.com/...";
            a.click();
        </script>
    </html>
    

    Then, instead of having the NFC tag point to https://app.example.com, you would program it to point to your redirect HTML https://other.example.com/pwa.html. It's not perfect and really just a workaround, but simpler than building and installing a separate APK.

    0 讨论(0)
  • 2020-12-30 18:28

    Add a helper application as a work-around:

    package com.something;
    
    import android.content.Intent;
    import android.net.Uri;
    import android.nfc.NfcAdapter;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        private void handleNfcIntent(@Nullable Intent intent) {
            if (intent != null && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
                //clear the intent so it doesn't come back
                intent.setAction("");
                Uri uri = intent.getData();
                if (uri != null) {
                    Intent uriOnlyIntent = new Intent(Intent.ACTION_VIEW, uri);
                    //call the progressive web app registered to view the uri
                    startActivity(uriOnlyIntent);
                }
            }
        }
    
        @Override
        protected void onNewIntent(final Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            //https://stackoverflow.com/a/36942185 provided the insight for handling this way
            //always called after onNewIntent and onCreate allowing a tag reward for a closed app
            handleNfcIntent(getIntent());
    
        }
    }
    

    Your AndroidManifest.xml listens for your target url:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.something">
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
                <intent-filter>
                    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <data android:host="something.com" android:scheme="https" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    Now when you scan your tag, the NFC Intent will be handled by the installed app which forwards to the View Intent which your Progressive Web App is registered.

    For me, this only worked in Android 8, not Android 6 since apparently opening a PWA by clicking on a link in Chrome is also not supported.

    An unfortunate work-around so I'm hoping to see a better answer.

    0 讨论(0)
提交回复
热议问题