Custom-URL-scheme
Custom-URL-scheme copied to clipboard
[support] use ANDROID_SCHEME and ANDROID_HOST instead of URL_SCHEME
Hello
This plugin is great, really, but... we need a web fallback. To achieve this, I would rather use the variables ANDROID_SCHEME
and ANDROID_HOST
also managed by this plugin.
e.g:
cordova plugin add cordova-plugin-customurlscheme --variable ANDROID_SCHEME=http --variable ANDROID_HOST=mywebsite.com --variable URL_SCHEME=idontcare
It works and is very powerful because if a user shares a link (e.g http://mywebsite.com/blabla/bla) when the link is clicked :
- if the app is installed, then android suggests to launch it
- else the browser is launched and opens the url
Pretty awesome! We've nearly achieved our goal, but...
- minor problem 1: URL_SCHEME is mandatory, why?
- major problem 2:
handleOpenUrl
is not called
@EddyVerbruggen have you any suggestion please?
Hello, have you also tested how it behaves on ios ? Also, have you made any progress since ?
Hello @JerryBels I haven't tested yet on iOS, but I managed to make it work on android.
The solution is to remove Custom-URL-scheme
plugin from your project and do it yourself.
For Android
config.xml Add this:
<config-file parent="/manifest/application/activity[@android:name='MainActivity']" target="AndroidManifest.xml">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="yourwebsite.com" android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
</config-file>
If you set attribute android:autoVerify="true"
on the <intent-filter>
, then you will have to deploy a .well-known/assetlinks.json
. See https://developer.android.com/training/app-links/verify-site-associations
Get the intent value Create a small cordova plugin that exposes a function to get the intent. You will call this function from your javascript, it can return:
- the query string (allowing you to parse it and navigate to the appropriate content)
- or null (e.g if the user simply launched the app himself by tapping the icon)
I can't speak for iOS now, but for android this is how to get the query string:
package com.yourcompany;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.Configuration;
import android.util.Log;
public class YourIntentPluginName extends CordovaPlugin {
private static final String LOG_TAG = "YourIntentPluginName";
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
Log.d(LOG_TAG, "initialize");
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
Log.d(LOG_TAG, "executing action "+action);
switch (action) {
case "getIntent":
callbackContext.success(this.getIntentUri());
break;
default:
callbackContext.error("Invalid action: " + action);
return false;
}
return true;
}
private String getIntentUri() {
// see https://developer.android.com/training/app-links/deep-linking#java
// javadoc:
// see https://developer.android.com/reference/android/app/Activity
// see https://developer.android.com/reference/android/content/Intent.html
Intent intent = this.cordova.getActivity().getIntent();
Log.i(LOG_TAG, "intent data string: "+intent.getDataString());
return intent.getDataString();
}
}
(Would be even better with a try/catch, to call callbackContext.error
if any exception is raised.)
Finally:
- create the js interface file, see https://cordova.apache.org/docs/en/8.x/guide/hybrid/plugins/index.html
- then in plugin.xml:
- declare the js interface with
<js-module>
and<clobbers>
- and the java source file
- declare the js interface with
...
<js-module src="www/YourIntentPluginInterface.js" name="YourIntentPluginInterface">
<clobbers target="window.YourIntentPluginName" />
</js-module>
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="YourIntentPluginName">
<param name="android-package" value="com.yourcompany.YourIntentPluginName"/>
<param name="onload" value="true" />
</feature>
</config-file>
<source-file src="src/android/YourIntentPluginName.java" target-dir="src/com/yourcompany" />
...
In your webapp, you can now call window.YourIntentPluginName.getIntent(successCb, failureCb)
I haven't tested it in production but on a dev environment (using cordova 8.1.2 and cordova-android 7.1.4) it works like a charm.
Send an email with a link: http://yourwebsite.com/... Click on it from the device, if your app is installed then android suggests you to launch the app, if not, then android directly starts the browser with specified url.
For iOS
You need to follow Universal Links documentation: https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html
Procedure includes:
- deployment of a json file on the website (similar to android's
.well-known/assetlinks.json
I suppose) - configuration of App Capabilities (Associated Domains section), I hope this can be achieved from config.xml
- native code
I won't have the time now but if anyone has feedback on this you're welcome to share!