Open source IntentAndroid
Summary: Move the code to the github folder, add more docs and improve the example. We might want to merge this with `LinkingIOS` later (it has the same functionality plus support for deep links) but want to see how people use the `IntentAndroid` API first (and what other methods we should add) to have more data points. public Reviewed By: lexs Differential Revision: D2646936 fb-gh-sync-id: 751f35784d387efcd031f9b458821cdfde048a54
This commit is contained in:
parent
d5209a0829
commit
ab7b3b2dea
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
IntentAndroid,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableNativeFeedback,
|
||||
View,
|
||||
} = React;
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
|
||||
var OpenURLButton = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
url: React.PropTypes.string,
|
||||
},
|
||||
|
||||
handleClick: function() {
|
||||
IntentAndroid.canOpenURL(this.props.url, (supported) => {
|
||||
if (supported) {
|
||||
IntentAndroid.openURL(this.props.url);
|
||||
} else {
|
||||
console.log('Don\'t know how to open URI: ' + this.props.url);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<TouchableNativeFeedback
|
||||
onPress={this.handleClick}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.text}>Open {this.props.url}</Text>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var IntentAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'IntentAndroid',
|
||||
description: 'Shows how to use Android Intents to open URLs.',
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerBlock title="Open external URLs">
|
||||
<OpenURLButton url={'https://www.facebook.com'} />
|
||||
<OpenURLButton url={'http://www.facebook.com'} />
|
||||
<OpenURLButton url={'http://facebook.com'} />
|
||||
<OpenURLButton url={'geo:37.484847,-122.148386'} />
|
||||
</UIExplorerBlock>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
padding: 10,
|
||||
paddingTop: 30,
|
||||
},
|
||||
button: {
|
||||
padding: 10,
|
||||
backgroundColor: '#3B5998',
|
||||
marginBottom: 10,
|
||||
},
|
||||
text: {
|
||||
color: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = IntentAndroidExample;
|
|
@ -38,6 +38,7 @@ var COMPONENTS = [
|
|||
var APIS = [
|
||||
require('./AccessibilityAndroidExample.android'),
|
||||
require('./BorderExample'),
|
||||
require('./IntentAndroidExample.android'),
|
||||
require('./LayoutEventsExample'),
|
||||
require('./LayoutExample'),
|
||||
require('./PanResponderExample'),
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule IntentAndroid
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var IntentAndroidModule = require('NativeModules').IntentAndroid;
|
||||
var invariant = require('invariant');
|
||||
|
||||
/**
|
||||
* `IntentAndroid` gives you a general interface to handle external links.
|
||||
*
|
||||
* #### Opening external links
|
||||
*
|
||||
* To start the corresponding activity for a link (web URL, email, contact etc.), call
|
||||
*
|
||||
* ```
|
||||
* IntentAndroid.openURL(url)
|
||||
* ```
|
||||
*
|
||||
* If you want to check if any installed app can handle a given URL beforehand you can call
|
||||
* ```
|
||||
* IntentAndroid.canOpenURL(url, (supported) => {
|
||||
* if (!supported) {
|
||||
* console.log('Can\'t handle url: ' + url);
|
||||
* } else {
|
||||
* IntentAndroid.openURL(url);
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
class IntentAndroid {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386"), a contact,
|
||||
* or any other URL that can be opened with {@code Intent.ACTION_VIEW}.
|
||||
*
|
||||
* NOTE: This method will fail if the system doesn't know how to open the specified URL.
|
||||
* If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first.
|
||||
*
|
||||
* NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
|
||||
*/
|
||||
static openURL(url: string) {
|
||||
this._validateURL(url);
|
||||
IntentAndroidModule.openURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not an installed app can handle a given URL.
|
||||
*
|
||||
* You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386"), a contact,
|
||||
* or any other URL that can be opened with {@code Intent.ACTION_VIEW}.
|
||||
*
|
||||
* NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
|
||||
*
|
||||
* @param URL the URL to open
|
||||
*/
|
||||
static canOpenURL(url: string, callback: Function) {
|
||||
this._validateURL(url);
|
||||
invariant(
|
||||
typeof callback === 'function',
|
||||
'A valid callback function is required'
|
||||
);
|
||||
IntentAndroidModule.canOpenURL(url, callback);
|
||||
}
|
||||
|
||||
static _validateURL(url: string) {
|
||||
invariant(
|
||||
typeof url === 'string',
|
||||
'Invalid URL: should be a string. Was: ' + url
|
||||
);
|
||||
invariant(
|
||||
url,
|
||||
'Invalid URL: cannot be empty'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IntentAndroid;
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule IntentAndroid
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
openURI: function(url) {
|
||||
console.error('IntentAndroid is not supported on iOS');
|
||||
},
|
||||
};
|
|
@ -23,7 +23,7 @@ var _initialURL = RCTLinkingManager &&
|
|||
var DEVICE_NOTIF_EVENT = 'openURL';
|
||||
|
||||
/**
|
||||
* `LinkingIOS` gives you a general interface to interact with both, incoming
|
||||
* `LinkingIOS` gives you a general interface to interact with both incoming
|
||||
* and outgoing app links.
|
||||
*
|
||||
* ### Basic Usage
|
||||
|
@ -65,13 +65,13 @@ var DEVICE_NOTIF_EVENT = 'openURL';
|
|||
*
|
||||
* #### Triggering App links
|
||||
*
|
||||
* To trigger an app link (browser, email or custom schemas) you call
|
||||
* To trigger an app link (browser, email or custom schemas), call
|
||||
*
|
||||
* ```
|
||||
* LinkingIOS.openURL(url)
|
||||
* ```
|
||||
*
|
||||
* If you want to check if any installed app can handle a given url beforehand you can call
|
||||
* If you want to check if any installed app can handle a given URL beforehand you can call
|
||||
* ```
|
||||
* LinkingIOS.canOpenURL(url, (supported) => {
|
||||
* if (!supported) {
|
||||
|
@ -127,7 +127,7 @@ class LinkingIOS {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not an installed app can handle a given `url`
|
||||
* Determine whether or not an installed app can handle a given URL.
|
||||
* The callback function will be called with `bool supported` as the only argument
|
||||
*
|
||||
* NOTE: As of iOS 9, your app needs to provide a `LSApplicationQueriesSchemes` key
|
||||
|
|
|
@ -66,6 +66,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
|
|||
Dimensions: require('Dimensions'),
|
||||
Easing: require('Easing'),
|
||||
ImagePickerIOS: require('ImagePickerIOS'),
|
||||
IntentAndroid: require('IntentAndroid'),
|
||||
InteractionManager: require('InteractionManager'),
|
||||
LayoutAnimation: require('LayoutAnimation'),
|
||||
LinkingIOS: require('LinkingIOS'),
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.intent;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.facebook.react.bridge.Callback;
|
||||
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.
|
||||
*/
|
||||
public class IntentModule extends ReactContextBaseJavaModule {
|
||||
|
||||
public IntentModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IntentAndroid";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ReactMethod
|
||||
public void openURL(String url) {
|
||||
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);
|
||||
getReactApplicationContext().startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
"Could not open URL '" + url + "': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@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;
|
||||
callback.invoke(canOpen);
|
||||
} catch (Exception e) {
|
||||
throw new JSApplicationIllegalArgumentException(
|
||||
"Could not check if URL '" + url + "' can be opened: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ import com.facebook.react.bridge.JavaScriptModule;
|
|||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.modules.fresco.FrescoModule;
|
||||
import com.facebook.react.modules.intent.IntentModule;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import com.facebook.react.modules.storage.AsyncStorageModule;
|
||||
import com.facebook.react.modules.toast.ToastModule;
|
||||
|
@ -47,6 +48,7 @@ public class MainReactPackage implements ReactPackage {
|
|||
return Arrays.<NativeModule>asList(
|
||||
new AsyncStorageModule(reactContext),
|
||||
new FrescoModule(reactContext),
|
||||
new IntentModule(reactContext),
|
||||
new NetworkingModule(reactContext),
|
||||
new WebSocketModule(reactContext),
|
||||
new ToastModule(reactContext));
|
||||
|
|
Loading…
Reference in New Issue