Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native: Unable to open device settings from my android app

Tags:

react-native

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

like image 727
Varsha Jadhav Avatar asked Jan 16 '17 13:01

Varsha Jadhav


People also ask

Can you please open my phone settings?

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.


1 Answers

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.

like image 116
manish keer Avatar answered Oct 01 '22 21:10

manish keer