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:
Satyajit Sahoo
2015-12-15 06:26:51 -08:00
committed by facebook-github-bot-5
parent cf94a9ea95
commit eb188c8d98
2 changed files with 78 additions and 10 deletions

View File

@@ -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.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getReactApplicationContext().startActivity(intent);
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(