React-Native:无法从我的Android应用程序打开设备设置

时间:2017-01-16 13:41:01

标签: react-native

我使用React-Native(^ 0.35.0)制作Android应用程序。在某种情况下,我需要检查是否存在互联网连接。如果没有互联网连接,那么我需要显示一个按钮,该按钮将打开设备设置(用户可通过该设置启用连接)。

我使用react-native提供的链接库。

我正在尝试以下方式:

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

然后上面的代码给出 - 控制台无法处理网址:app-settings:

当我尝试跟随时:

componentWillMount(){
    Linking.canOpenURL('app-settings:')
      .then(supported => {
        return Linking.openURL('app-settings:');
      }).catch(err => console.error('An error occurred', err));
    }

以上代码给出 - 错误:无法打开网址' app-settings:':找不到处理Intent的活动{act = android.intent.action.VIEW dat = app-settings :flg = 0x10000000}

这里有什么我想念的吗?或是否需要更改任何其他文件,如 AndroidMainfest.xml MainActivity.java 等。

2 个答案:

答案 0 :(得分:20)

我是反应原生的新手,没有太多的java(android)见解。我遇到了类似的问题,但我设法通过创建自定义react-native模块来打开Android设置。

以下是我为实现此功能而采取的步骤。

1 - 为android/app/src/main/java/com/<projectname>/下的模块创建一个文件夹。在这种情况下,我创建了opensettings文件夹。

2 - 在此文件夹下创建模块文件OpenSettingsModule.java(我们放置模块功能)和包文件OpenSettingsPackage.java(我们将在其中注册我们的模块)。

3 - 将以下代码放入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 - 我们已经完成了我们的模块,它将通过调用openNetworkSettings函数来打开android设置。现在我们需要注册这个模块。在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 - 将此套餐提供给getPackages的{​​{1}}方法。

MainApplication.java

6 - 我们已完成JAVA部分,在您的组件中导入import com.<projectname>.opensettings.*; ... @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new OpenSettingsPackage() /* <---- add here */ ); } ,我们现在可以通过NativeModules访问我们的模块。 JSX实现如下。

NativeModules.OpenSettings

7 - 参考

https://shift.infinite.red/native-modules-for-react-native-android-ac05dbda800d#.yj9pspfpn http://facebook.github.io/react-native/docs/native-modules-android.html

注意:如果有更好的方法可以实现相同的功能,请在此告诉我。

答案 1 :(得分:6)

我使用了相同的步骤来打开设备网络运营商设置。上述步骤非常有用。

这是我的代码。

         if(response){
               $localStorage.LoggedInuser = response;
              // $window.location.reload();
               $state.go('index');

            }else{
                $scope.error_message = "Invalid username or password.";
            }   

您需要做的只是将常量(如ACTION_NETWORK_OPERATOR_SETTINGS)放在上面的代码中,并创建自己的函数,就像上面创建的函数一样,即openNetworkSettings。其他步骤4,5和6是相同的。

以下是常量列表: https://developer.android.com/reference/android/provider/Settings.html