├── android
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── wahdatjan
│ │ └── intents
│ │ ├── IntentModulePackage.java
│ │ └── IntentModule.java
└── build.gradle
├── package.json
├── LICENSE.txt
├── src
└── index.js
└── README.md
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 |
4 | def safeExtGet(prop, fallback) {
5 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
6 | }
7 |
8 | android {
9 | compileSdkVersion 28
10 | buildToolsVersion "28.0.3"
11 |
12 | defaultConfig {
13 | minSdkVersion 16
14 | targetSdkVersion 28
15 | versionCode 1
16 | versionName "1.0.0"
17 | }
18 | lintOptions {
19 | abortOnError false
20 | }
21 | }
22 |
23 | buildscript {
24 | repositories {
25 | jcenter()
26 | google()
27 | }
28 |
29 | dependencies {
30 | classpath 'com.android.tools.build:gradle:3.3.2'
31 |
32 | }
33 | }
34 |
35 | repositories {
36 | mavenCentral()
37 | }
38 |
39 |
40 | dependencies {
41 | implementation 'com.facebook.react:react-native:+'
42 |
43 | }
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/android/src/main/java/com/wahdatjan/intents/IntentModulePackage.java:
--------------------------------------------------------------------------------
1 | package com.wahdatjan.intents;
2 |
3 | import com.facebook.react.ReactPackage;
4 | import com.facebook.react.bridge.NativeModule;
5 | import com.facebook.react.bridge.ReactApplicationContext;
6 | import com.facebook.react.uimanager.ViewManager;
7 |
8 | import java.util.ArrayList;
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | import javax.annotation.Nonnull;
13 |
14 | public class IntentModulePackage implements ReactPackage {
15 | @Nonnull
16 | @Override
17 | public List createNativeModules(@Nonnull ReactApplicationContext reactContext) {
18 | List modules = new ArrayList<>();
19 | modules.add(new IntentModule(reactContext));
20 | return modules;
21 | }
22 |
23 | @Nonnull
24 | @Override
25 | public List createViewManagers(@Nonnull ReactApplicationContext reactContext) {
26 | return Collections.emptyList();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-common-intents",
3 | "version": "0.3.0",
4 | "description": "A react-native module in which you will use find all of the common intents for only android platform",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/wahdatjan/react-native-common-intents.git"
12 | },
13 | "keywords": [
14 | "react",
15 | "react-native",
16 | "intents",
17 | "common intents",
18 | "image",
19 | "image picker",
20 | "android",
21 | "open web page",
22 | "wifi settings",
23 | "bluetooth settings",
24 | "native",
25 | "dial phone number",
26 | "dial phone intent",
27 | "alarm intent",
28 | "timer intent"
29 | ],
30 | "author": "wahdatjan =0.40.0",
34 | "react": ">=15.4.0"
35 | },
36 | "nativePackage": true
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Wahdat Jan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import {NativeModules, Platform} from 'react-native';
2 |
3 | const CommonIntents = NativeModules.RNIntents;
4 |
5 |
6 | const noIOS = () => console.warn('Native Common intents cannot be used for iOS.');
7 |
8 | const iosOS = {
9 | ImagePicker: noIOS,
10 | openWebPage: noIOS,
11 | openSettings:noIOS,
12 | openDateSettings: noIOS,
13 | openWifiSettings: noIOS,
14 | openBluetoothSettings: noIOS,
15 | openAirplaneModeSettings: noIOS,
16 | performWebSearch: noIOS,
17 | dialNumber : noIOS,
18 | startTimer : noIOS,
19 | createNote : noIOS
20 | };
21 |
22 | const Intents = Platform.OS === 'ios' ? iosOS : {
23 |
24 | ImagePicker : CommonIntents.ImagePick,
25 | openWeb: url => {
26 | if(url==null || url==""){
27 | throw new Error('Please enter right url');
28 | }
29 | CommonIntents.openWebPage(url);
30 | },
31 | openSettings: CommonIntents.openSettings,
32 | openDateSettings : CommonIntents.openDateSettings,
33 | openWifiSettings : CommonIntents.openWifiSettings,
34 | openBluetoothSettings : CommonIntents.openBluetoothSettings,
35 | openAirplaneModeSettings : CommonIntents.openAirplaneModeSettings,
36 | dialNumber : phoneno => {
37 | if(phoneno=="" || phoneno==null){
38 | throw new Error("Please enter phone number");
39 | }
40 | CommonIntents.dialNumber(phoneno);
41 | },
42 |
43 | startTimer : CommonIntents.startTimer,
44 | createAlarm : (message,hour,minutes) => {
45 | if(message==""){
46 | throw new Error("Message cannot be put as an empty");
47 | }
48 | CommonIntents.createAlarm(message,hour,minutes);
49 | },
50 | performWebSearch : query => {
51 | if(query== ""){
52 | throw new Error("Please Enter Text to search");
53 | }
54 | CommonIntents.performWebSearch(query);
55 | },
56 | createNote : (subject,text) => {
57 | if(subject == "" || text==""){
58 | throw new Error("You need to pass parameters");
59 | }
60 | CommonIntents.createNote(subject,text);
61 | }
62 |
63 | }
64 | export default Intents;
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-common-intents
2 | 
3 |
4 |
5 | React Native Android Module's Android Common intents actions like for
6 | ##### Image picker from Gallery
7 | ##### Open date settings
8 | ##### Open settings page
9 | ##### Open wifi settings
10 | ##### Open Bluetooth settings
11 | ##### Open airplanemode settings
12 | ##### Open browser with input url
13 | ##### Make web search by entering text
14 | ##### Create alarm
15 | ##### Create timer
16 | ##### dial phone number
17 | ##### Create note
18 |
19 | ## How this Module is useful ?
20 | lets say you want to pick image from gallery and want to upload it, you want user to open wifi settings , date settings etc directly from your app , you want to load a web url in browser or you want to make some web search all these things can be achieved with this library as shown below.
21 |
22 |
23 |
24 | # Installation
25 | `npm install react-native-common-intents --save`
26 | or
27 | `yarn add react-native-common-intents`
28 |
29 | #### Add it to your android project
30 |
31 | Automatic link:
32 |
33 | react-native link react-native-common-intents
34 |
35 | Manual link:
36 |
37 | - in `android/app/build.gradle`
38 |
39 | ```
40 | - dependencies {
41 | implementation "com.facebook.react:react-native:+" // From node_modules
42 |
43 | + implementation project(':react-native-common-intents') // <------ add this line to your build.gradle file
44 | }
45 |
46 |
47 |
48 | - in `android/settings.gradle`
49 | ```
50 |
51 | include ':app'
52 | // <------ add below two lines to your settings.gradle------>
53 | + include ':react-native-common-intents' //
54 | + project(':react-native-common-intents').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-common-intents/android')//
55 |
56 | ```
57 | - in `MainApplication.java`
58 |
59 | ```
60 | @Override
61 | protected List getPackages() {
62 | return Arrays.asList(
63 | new MainReactPackage(),
64 | new IntentModulePackage() // <------ add this line to your MainApplication class
65 | );
66 | }
67 | ```
68 |
69 |
70 | ## Permissions
71 |
72 | ###### Add this to your `AndroidManifest.xml`
73 | ```
74 | ...
75 |
76 |
77 |
78 |
79 | ...
80 | ```
81 |
82 | ## Import Library
83 |
84 | `import RNIntents from 'react-native-common-intents';`
85 |
86 |
87 | ## Example/ Image Picker
88 |
89 | RNIntents.ImagePicker Module has two arguments first one will give you the **url** of the
90 | image that you will choose from gallery and 2nd argument will give you the **error** which may occur
91 | ```
92 | RNIntents.ImagePicker(url => {
93 | console.log("image uri",url);
94 | },(err) => {
95 | console.log("eeeoe",err);
96 | });
97 |
98 |
99 | ```
100 |
101 | ## Example/ open Web Page
102 |
103 | ```
104 | RNIntents.openWeb("https://google.com");
105 | ```
106 |
107 | ## Example/ Perform Web Search
108 |
109 | ```
110 | RNIntents.performWebSearch("Winter is coming");
111 | ```
112 |
113 | ## Example/ Open Settings Page
114 |
115 | ```
116 | RNIntents.openSettings();
117 | ```
118 | ## Example/ Open DateSettings
119 |
120 | ```
121 | RNIntents.openDateSettings();
122 | ```
123 |
124 | ## Example/ Open WifiSettings
125 |
126 | ```
127 | RNIntents.openWifiSettings();
128 | ```
129 | ## Example/ open AirplaneModeSettings
130 |
131 | ```
132 | RNIntents.openAirplaneModeSettings();
133 | ```
134 |
135 | ## Example/ open BluetoothSettings
136 |
137 | ```
138 | RNIntents.openBluetoothSettings();
139 | ```
140 |
141 | ## Example/ Dial Phone Number
142 |
143 | ```
144 | RNIntents.dialNumber("9086090860");
145 | ```
146 |
147 |
148 | ## Example/ Start Timer
149 | ###### you can start a timer in background without opening app or with opening app based
150 | on the boolean value passed as true or false
151 |
152 | It takes 3 parameters
153 | Message as string , seconds as int , boolean value
154 |
155 | ```
156 | RNIntents.startTimer(String message, int seconds,boolean value)
157 | ```
158 |
159 |
160 | ## Example/ Create alarm
161 |
162 |
163 | ### It takes 3 parameters
164 | #### Message as string , hours as int , minutes as int
165 | ```
166 | RNIntents.createAlarm(String message, int hour, int minutes);
167 | ```
168 | ## Example/ Create note
169 |
170 |
171 | ### It takes 2 parameters
172 | #### subject as string , text as string
173 | ```
174 | RNIntents.createNote(subject,text);
175 | ```
176 |
177 |
178 | ## Example
179 |
180 |
181 | ```diff
182 |
183 | import React, {Component} from 'react';
184 | import {Platform, StyleSheet, Text, View, Button} from 'react-native';
185 | import RNIntents from 'react-native-common-intents';
186 |
187 |
188 |
189 | export default class App extends Component {
190 | render() {
191 | return (
192 |
193 | React-native-common-intents
194 |
232 | );
233 | }
234 | }
235 |
236 | const styles = StyleSheet.create({
237 | container: {
238 | flex: 1,
239 | justifyContent: 'center',
240 | alignItems: 'center',
241 | backgroundColor: '#F5FCFF',
242 | },
243 | welcome: {
244 | fontSize: 20,
245 | textAlign: 'center',
246 | margin: 10,
247 | },
248 | instructions: {
249 | textAlign: 'center',
250 | color: '#333333',
251 | marginBottom: 5,
252 | },
253 | });
254 |
255 | ```
256 |
--------------------------------------------------------------------------------
/android/src/main/java/com/wahdatjan/intents/IntentModule.java:
--------------------------------------------------------------------------------
1 | package com.wahdatjan.intents;
2 |
3 | import android.app.Activity;
4 | import android.provider.AlarmClock;
5 | import android.app.SearchManager;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.provider.Settings;
10 | import android.util.Log;
11 |
12 | import com.facebook.react.bridge.ActivityEventListener;
13 | import com.facebook.react.bridge.Callback;
14 | import com.facebook.react.bridge.ReactApplicationContext;
15 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
16 | import com.facebook.react.bridge.ReactMethod;
17 | import com.facebook.react.bridge.ReadableMap;
18 |
19 | import javax.annotation.Nonnull;
20 |
21 | public class IntentModule extends ReactContextBaseJavaModule implements ActivityEventListener {
22 |
23 | private static final int PICK_IMAGE = 1;
24 | private static final int GALERY_INTENT = 2;
25 |
26 |
27 | private Callback pickerSuccessCallback;
28 | private Callback pickerCancelCallback;
29 |
30 | ReactApplicationContext context = getReactApplicationContext();
31 |
32 | public IntentModule(@Nonnull ReactApplicationContext reactContext) {
33 | super(reactContext);
34 | context.addActivityEventListener(this);
35 | }
36 |
37 | @Nonnull
38 | @Override
39 | public String getName() {
40 | return "RNIntents";
41 | }
42 |
43 |
44 |
45 |
46 |
47 | @ReactMethod
48 | public void ImagePick(Callback successCallback, Callback cancelCallback) {
49 | Activity currentActivity = getCurrentActivity();
50 |
51 | if (currentActivity == null) {
52 | cancelCallback.invoke("Activity doesn't exist");
53 | return;
54 | }
55 | pickerSuccessCallback = successCallback;
56 | pickerCancelCallback = cancelCallback;
57 |
58 | try{
59 | if (Build.VERSION.SDK_INT <19){
60 |
61 | Intent galleryIntent = new Intent();
62 | galleryIntent.setType("image/*");
63 | galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
64 |
65 | final Intent chooserIntent = Intent.createChooser(galleryIntent,"Pick an Image");
66 | currentActivity.startActivityForResult(chooserIntent,PICK_IMAGE);
67 |
68 | }
69 |
70 | else {
71 | Intent intent = new Intent(android.content.Intent.ACTION_OPEN_DOCUMENT);
72 | intent.addCategory(Intent.CATEGORY_OPENABLE);
73 | intent.setType("image/*");
74 | currentActivity.startActivityForResult(intent, GALERY_INTENT);
75 | }
76 | } catch (Exception e) {
77 | cancelCallback.invoke(e);
78 | }
79 |
80 |
81 | }
82 | @Override
83 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
84 |
85 | if (pickerSuccessCallback !=null){
86 | if (resultCode == Activity.RESULT_CANCELED){
87 | pickerCancelCallback.invoke("Image Picker was cancelled");
88 | } else if (resultCode == Activity.RESULT_OK){
89 | Uri uri = data.getData();
90 | Log.d("Tagg",""+uri);
91 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
92 |
93 | try {
94 | getReactApplicationContext().getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
95 | }
96 | catch (SecurityException e){
97 | e.printStackTrace();
98 | }
99 | }
100 |
101 |
102 | if (uri == null){
103 | pickerCancelCallback.invoke("No image data found");
104 | }
105 | else {
106 | try {
107 | pickerSuccessCallback.invoke(uri.toString());
108 | }catch (Exception e){
109 | pickerCancelCallback.invoke("No Image Data Found");
110 | }
111 |
112 | }
113 | }
114 | }
115 | }
116 |
117 | @Override
118 | public void onNewIntent(Intent intent) {
119 |
120 | }
121 |
122 | @ReactMethod
123 | public void openWebPage(String url){
124 | Uri webPage = Uri.parse(url);
125 | Intent intent = new Intent(Intent.ACTION_VIEW, webPage);
126 | if (intent.resolveActivity(context.getPackageManager()) != null) {
127 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
128 | context.startActivity(intent);
129 | }
130 | }
131 |
132 | @ReactMethod
133 | public void openSettings(){
134 | Intent intent = new Intent(Settings.ACTION_SETTINGS);
135 | if (intent.resolveActivity(context.getPackageManager()) != null) {
136 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
137 | context.startActivity(intent);
138 | }
139 | }
140 | @ReactMethod
141 | public void openDateSettings(){
142 | Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
143 | if (intent.resolveActivity(context.getPackageManager()) != null) {
144 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
145 | context.startActivity(intent);
146 | }
147 | }
148 |
149 | @ReactMethod
150 | public void createNote(String subject, String text) {
151 | Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE)
152 | .putExtra(NoteIntents.EXTRA_NAME, subject)
153 | .putExtra(NoteIntents.EXTRA_TEXT, text);
154 | if (intent.resolveActivity(getPackageManager()) != null) {
155 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
156 | startActivity(intent);
157 | }
158 | }
159 | @ReactMethod
160 | public void openWifiSettings(){
161 | Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
162 | if (intent.resolveActivity(context.getPackageManager()) != null) {
163 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
164 | context.startActivity(intent);
165 | }
166 | }
167 |
168 | @ReactMethod
169 | public void openBluetoothSettings(){
170 | Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
171 | if (intent.resolveActivity(context.getPackageManager()) != null) {
172 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
173 | context.startActivity(intent);
174 | }
175 | }
176 |
177 | @ReactMethod
178 | public void openAirplaneModeSettings(){
179 | Intent intent = new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
180 | if (intent.resolveActivity(context.getPackageManager()) != null) {
181 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
182 | context.startActivity(intent);
183 | }
184 | }
185 |
186 | @ReactMethod
187 | public void performWebSearch(String query){
188 | Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
189 |
190 | if (intent.resolveActivity(context.getPackageManager()) != null) {
191 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
192 | intent.putExtra(SearchManager.QUERY, query);
193 | context.startActivity(intent);
194 | }
195 | }
196 |
197 | @ReactMethod
198 | public void dialNumber(String number){
199 | Intent intent = new Intent(Intent.ACTION_DIAL);
200 | intent.setData(Uri.parse("tel:" +number));
201 | if (intent.resolveActivity(context.getPackageManager()) !=null){
202 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
203 | getReactApplicationContext().startActivity(intent);
204 | }
205 | }
206 |
207 | @ReactMethod
208 | public void startTimer(String message, int seconds,boolean value) {
209 | Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
210 | .putExtra(AlarmClock.EXTRA_MESSAGE, message)
211 | .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
212 | .putExtra(AlarmClock.EXTRA_SKIP_UI, value);
213 | if (intent.resolveActivity(context.getPackageManager()) != null) {
214 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
215 | context.startActivity(intent);
216 | }
217 |
218 |
219 | }
220 |
221 | @ReactMethod
222 | public void createAlarm(String message, int hour, int minutes) {
223 | Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
224 | .putExtra(AlarmClock.EXTRA_MESSAGE, message)
225 | .putExtra(AlarmClock.EXTRA_HOUR, hour)
226 | .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
227 | if (intent.resolveActivity(context.getPackageManager()) != null) {
228 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
229 | context.startActivity(intent);
230 | }
231 | }
232 | }
233 |
--------------------------------------------------------------------------------