Add deep linking support to IntentAndroid
Summary: Add a method to handle URLs registered to the app, ```js IntentAndroid.getInitialURL(url => { if (url) { // do stuff } }); ``` Refer - http://developer.android.com/training/app-indexing/deep-linking.html#adding-filters The API cannot be same as the iOS API (i.e. as a constant), as the activity is not availble at the time of module initialization. Moreover, multiple activties can share the same bridge instance, and the activity itself is not a constant. Hence the initialURL can change. Closes https://github.com/facebook/react-native/pull/4320 Reviewed By: svcscm Differential Revision: D2759667 Pulled By: foghina fb-gh-sync-id: b725231ae1401fa5565d444eee5a30d303e263ae
This commit is contained in:
parent
cf94a9ea95
commit
eb188c8d98
|
@ -16,6 +16,26 @@ var invariant = require('invariant');
|
|||
/**
|
||||
* `IntentAndroid` gives you a general interface to handle external links.
|
||||
*
|
||||
* ### Basic Usage
|
||||
*
|
||||
* #### Handling deep links
|
||||
*
|
||||
* If your app was launched from an external url registered to your app you can
|
||||
* access and handle it from any component you want with
|
||||
*
|
||||
* ```
|
||||
* componentDidMount() {
|
||||
* var url = IntentAndroid.getInitialURL(url => {
|
||||
* if (url) {
|
||||
* console.log('Initial url is: ' + url);
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* NOTE: For instructions on how to add support for deep linking,
|
||||
* refer [Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links](http://developer.android.com/training/app-indexing/deep-linking.html#adding-filters).
|
||||
*
|
||||
* #### Opening external links
|
||||
*
|
||||
* To start the corresponding activity for a link (web URL, email, contact etc.), call
|
||||
|
@ -75,6 +95,20 @@ class IntentAndroid {
|
|||
IntentAndroidModule.canOpenURL(url, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the app launch was triggered by an app link with {@code Intent.ACTION_VIEW},
|
||||
* it will give the link url, otherwise it will give `null`
|
||||
*
|
||||
* Refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
|
||||
*/
|
||||
static getInitialURL(callback: Function) {
|
||||
invariant(
|
||||
typeof callback === 'function',
|
||||
'A valid callback function is required'
|
||||
);
|
||||
IntentAndroidModule.getInitialURL(callback);
|
||||
}
|
||||
|
||||
static _validateURL(url: string) {
|
||||
invariant(
|
||||
typeof url === 'string',
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
|
||||
package com.facebook.react.modules.intent;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Intent module. Launch other activities or open URLs.
|
||||
|
@ -33,25 +33,58 @@ public class IntentModule extends ReactContextBaseJavaModule {
|
|||
return "IntentAndroid";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL the activity was started with
|
||||
*
|
||||
* @param callback a callback which is called with the initial URL
|
||||
*/
|
||||
@ReactMethod
|
||||
public void getInitialURL(Callback callback) {
|
||||
try {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
String initialURL = null;
|
||||
|
||||
if (currentActivity != null) {
|
||||
Intent intent = currentActivity.getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri uri = intent.getData();
|
||||
|
||||
if (Intent.ACTION_VIEW.equals(action) && uri != null) {
|
||||
initialURL = uri.toString();
|
||||
}
|
||||
}
|
||||
|
||||
callback.invoke(initialURL);
|
||||
} catch (Exception e) {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
"Could not get the initial URL : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a corresponding external activity for the given URL.
|
||||
*
|
||||
* For example, if the URL is "https://www.facebook.com", the system browser will be opened,
|
||||
* or the "choose application" dialog will be shown.
|
||||
*
|
||||
* @param URL the URL to open
|
||||
* @param url the URL to open
|
||||
*/
|
||||
@ReactMethod
|
||||
public void openURL(String url) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid URL: " + url);
|
||||
}
|
||||
|
||||
try {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
// We need Intent.FLAG_ACTIVITY_NEW_TASK since getReactApplicationContext() returns
|
||||
// the ApplicationContext instead of the Activity context.
|
||||
|
||||
if (currentActivity != null) {
|
||||
currentActivity.startActivity(intent);
|
||||
} else {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getReactApplicationContext().startActivity(intent);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
"Could not open URL '" + url + "': " + e.getMessage());
|
||||
|
@ -61,21 +94,22 @@ public class IntentModule extends ReactContextBaseJavaModule {
|
|||
/**
|
||||
* Determine whether or not an installed app can handle a given URL.
|
||||
*
|
||||
* @param URL the URL to open
|
||||
* @param promise a promise that is always resolved with a boolean argument
|
||||
* @param url the URL to open
|
||||
* @param callback a callback that is always called with a boolean argument
|
||||
*/
|
||||
@ReactMethod
|
||||
public void canOpenURL(String url, Callback callback) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid URL: " + url);
|
||||
}
|
||||
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
// We need Intent.FLAG_ACTIVITY_NEW_TASK since getReactApplicationContext() returns
|
||||
// the ApplicationContext instead of the Activity context.
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
boolean canOpen =
|
||||
intent.resolveActivity(this.getReactApplicationContext().getPackageManager()) != null;
|
||||
intent.resolveActivity(getReactApplicationContext().getPackageManager()) != null;
|
||||
callback.invoke(canOpen);
|
||||
} catch (Exception e) {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
|
|
Loading…
Reference in New Issue