13

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..

3
  • this has been answered before: stackoverflow.com/a/39229693/515114 Commented Jan 16, 2017 at 15:29
  • @funkysoul: Not cleared in above link where should I exactly add that Native Code which you mentioned in above link. and How to integrate it in my component? Commented Jan 17, 2017 at 5:14
  • you need to write native code that can be called through the react native module. this module might help you in a way (only android) github.com/javorosas/react-native-open-wifi Commented Jan 17, 2017 at 10:40

2 Answers 2

26

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I've noticed when I was running that, the compiler would return OpenSettingsPackage.java:23: error: method does not override or implement a method from a supertype where I ended up removing the @Override.
I am getting this error:- TypeError: Cannot read property 'openNetworkSettings' of undefined
Please remove @Override if you are getting error OpenSettingsPackage.java:23: error: method does not override or implement a method from a supertype
8

I have used the same steps for opening device network operator settings. The steps above are quite helpful.

Here is my code.

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());
    }
  }


  /*This is for open location Settings*/
  @ReactMethod
  public void openLocationSettings(Callback cb) {
    Activity currentActivity = getCurrentActivity();

    if (currentActivity == null) {
      cb.invoke(false);
      return;
    }

    try {
      currentActivity.startActivity(new Intent(android.provider.Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
      cb.invoke(true);
    } catch (Exception e) {
      cb.invoke(e.getMessage());
    }
  }

  /* constructor */
  public OpenSettingsModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }
}

All you need to do is just put the constant(like ACTION_NETWORK_OPERATOR_SETTINGS) in above code and create your own function like one which is created above i.e. openNetworkSettings. Other steps 4, 5 and 6 are same.

Here are the list of constants: https://developer.android.com/reference/android/provider/Settings.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.