capacitor-plugins icon indicating copy to clipboard operation
capacitor-plugins copied to clipboard

[Feature] Deep linking for Chromebook Android (App appUrlOpen)

Open thmclellan opened this issue 1 year ago • 0 comments

Feature Request

Capacitor's App plugin's deep linking with appUrlOpen events works well for standard Android, but it seems the addListener appURLOpen event is never triggered when the Android app is running on Chromebook. This was causing issues for some deep linking flows where our user authenticates through OAuth using a Browser.open() flow, which on completion returns the user to the app through an app link (com.domain.app://etc).

The root cause is that Android Chromebook app links trigger an intent of org.chromium.arc.intent.action.VIEW instead of the standard Intent.ACTION_VIEW. This causes the AppPlugin's handleOnNewIntent function to ignore the intent, see AppPlugin.java L126: https://github.com/ionic-team/capacitor-plugins/blob/0ccb9c48af9740a24f1f084e9417d5d5e2201311/app/android/src/main/java/com/capacitorjs/plugins/app/AppPlugin.java#L126)

There's some great background and a MainActivity.java workaround for this at https://github.com/facebook/react-native/issues/20301.

Possible Solutions

  1. Capacitor App plugin could be extended to handle org.chromium.arc.intent.action.VIEW intents
  2. Override MainActivity onNewIntent() and getIntent() to convert org.chromium.arc.intent.action.VIEW intents into standard ACTION_VIEW intents

Current Workaround

We've done option 2 with the below overrides in our app's MainActivity.java and it's working well. It would be nice to see either of the above options in a future Capacitor update. In any case, I wanted to share this workaround for anyone else trying to do deep linking for Android Chromebook users.

    @Override
    public Intent getIntent() {
        Intent intent = super.getIntent();
        if (intent!=null && intent.getAction().equals("org.chromium.arc.intent.action.VIEW")) {
            return new Intent(intent).setAction(Intent.ACTION_VIEW);
        }
        return intent;
    }

    @Override
    public void onNewIntent(Intent intent) {
        if (intent!=null && intent.getAction().equals("org.chromium.arc.intent.action.VIEW")) {
            super.onNewIntent(new Intent(intent).setAction(Intent.ACTION_VIEW));
        } else {
            super.onNewIntent(intent);
        }
    }

Additional Details

These results are on a Lenovo Chromebook Duet, Chrome OS 120, Android version 11 and Capacitor Android 5.0.7.

thmclellan avatar Mar 25 '24 23:03 thmclellan