I'm using React-Native (^0.35.0) for making Android application. There is scenario where I need to check whether internet connectivity is present or not. If there is no internet connectivity then I need show a button which will open device settings (through which user can enable his connectivity).
I'm Using Linking library provided by react-native.
I am trying in followin way:
componentWillMount(){
Linking.canOpenURL('app-settings:')
.then(supported => {
if (!supported) {
console.log('Can\'t handle url: ' + url);
} else {
return Linking.openURL('app-settings:');
}
}).catch(err => console.error('An error occurred', err));
}
then above code gives- console Can't handle url:app-settings:
When I tried following:
componentWillMount(){
Linking.canOpenURL('app-settings:')
.then(supported => {
return Linking.openURL('app-settings:');
}).catch(err => console.error('An error occurred', err));
}
Above code gives- Error: Could not open URL 'app-settings:': No Activity found to handle Intent { act=android.intent.action.VIEW dat=app-settings: flg=0x10000000 }
Is there anything that I am missing here? or Is there is need to change in any other file like AndroidMainfest.xml, MainActivity.java, etc..
Getting to Your Settings There are two ways to get to your phone's settings. You can swipe down on the notification bar at the top of your phone display, then tap on the top right account icon, then tap on Settings. Or you can tap on the “all apps” app tray icon in the bottom middle of your home screen.
I'm new with react-native and not having much insights of java(android). I faced similar problem but I managed to open Android settings by creating the custom react-native module.
Below are the steps which I've taken to achieve this functionality.
1 - Create a folder for module under android/app/src/main/java/com/<projectname>/
. In this case I've created the opensettings
folder.
2 - Under this folder create module file OpenSettingsModule.java
(where we put module functionality) and package file OpenSettingsPackage.java
(where we will register our module).
3 - Put following code in OpenSettingsModule.java
package com.<projectname>.opensettings;
import android.app.Activity;
import android.content.Intent;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
public class OpenSettingsModule extends ReactContextBaseJavaModule {
@Override
public String getName() {
/**
* return the string name of the NativeModule which represents this class in JavaScript
* In JS access this module through React.NativeModules.OpenSettings
*/
return "OpenSettings";
}
@ReactMethod
public void openNetworkSettings(Callback cb) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
cb.invoke(false);
return;
}
try {
currentActivity.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
cb.invoke(true);
} catch (Exception e) {
cb.invoke(e.getMessage());
}
}
/* constructor */
public OpenSettingsModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
4 - We have done with our module which will open android settings by calling openNetworkSettings
function. Now we need to register this module. Add below code in OpenSettingsPackage.java
package com.<projectname>.opensettings;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class OpenSettingsPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new OpenSettingsModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
5 - Provide this package to getPackages
method of the MainApplication.java
.
import com.<projectname>.opensettings.*;
...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new OpenSettingsPackage() /* <---- add here */
);
}
6 - We are done with JAVA part, import NativeModules
in your component, we can now access our module through NativeModules.OpenSettings
. JSX implementation as below.
import { NativeModules } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.openSettings = this.openSettings.bind(this);
}
openSettings() {
NativeModules.OpenSettings.openNetworkSettings(data => {
console.log('call back data', data);
});
}
render() {
return (
<View style={styles.container}>
<Text onPress={this.openSettings}>Open Android Settings</Text>
</View>
);
}
}
7 - reference
https://shift.infinite.red/native-modules-for-react-native-android-ac05dbda800d#.yj9pspfpn http://facebook.github.io/react-native/docs/native-modules-android.html
Note: If there is any better way to achieve the same functionality then please let me know here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With