Don't insta-crash when network permission is missing
Summary: public Rename the `ConnectivityModule` to `NetInfoModule` (there's no need to name things differently in two places). Add exception handling to the module in case the network permission is missing. When the permission is missing, throw an actionable error from all calls to `NetInfo`: http://imgur.com/zVIMxOV Without this change, the app immediately crashes on startup: `getCurrentConnectionType` is called from `Activity.onResume`. Reviewed By: andreicoman11, bestander Differential Revision: D2749230 fb-gh-sync-id: 1b752d21a8f28ffeaf60a3322cb76f869dc70a14
This commit is contained in:
parent
4b800e6ce1
commit
f168fc335e
|
@ -1,4 +1,11 @@
|
||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
package com.facebook.react.modules.netinfo;
|
package com.facebook.react.modules.netinfo;
|
||||||
|
|
||||||
|
@ -10,6 +17,7 @@ import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.support.v4.net.ConnectivityManagerCompat;
|
import android.support.v4.net.ConnectivityManagerCompat;
|
||||||
|
|
||||||
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.react.bridge.Callback;
|
import com.facebook.react.bridge.Callback;
|
||||||
import com.facebook.react.bridge.LifecycleEventListener;
|
import com.facebook.react.bridge.LifecycleEventListener;
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
@ -17,25 +25,30 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
import com.facebook.react.bridge.WritableNativeMap;
|
import com.facebook.react.bridge.WritableNativeMap;
|
||||||
|
import com.facebook.react.common.ReactConstants;
|
||||||
|
|
||||||
import static com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
|
import static com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module that monitors and provides information about the connectivity state of the device.
|
* Module that monitors and provides information about the connectivity state of the device.
|
||||||
*/
|
*/
|
||||||
public class ConnectivityModule extends ReactContextBaseJavaModule
|
public class NetInfoModule extends ReactContextBaseJavaModule
|
||||||
implements LifecycleEventListener {
|
implements LifecycleEventListener {
|
||||||
|
|
||||||
private static final String CONNECTION_TYPE_NONE = "NONE";
|
private static final String CONNECTION_TYPE_NONE = "NONE";
|
||||||
private static final String CONNECTION_TYPE_UNKNOWN = "UNKNOWN";
|
private static final String CONNECTION_TYPE_UNKNOWN = "UNKNOWN";
|
||||||
|
private static final String MISSING_PERMISSION_MESSAGE =
|
||||||
|
"To use NetInfo on Android, add the following to your AndroidManifest.xml:\n" +
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />";
|
||||||
|
|
||||||
private final ConnectivityManager mConnectivityManager;
|
private final ConnectivityManager mConnectivityManager;
|
||||||
private final ConnectivityManagerCompat mConnectivityManagerCompat;
|
private final ConnectivityManagerCompat mConnectivityManagerCompat;
|
||||||
private final ConnectivityBroadcastReceiver mConnectivityBroadcastReceiver;
|
private final ConnectivityBroadcastReceiver mConnectivityBroadcastReceiver;
|
||||||
|
private boolean mNoNetworkPermission = false;
|
||||||
|
|
||||||
private String mConnectivity = "";
|
private String mConnectivity = "";
|
||||||
|
|
||||||
public ConnectivityModule(ReactApplicationContext reactContext) {
|
public NetInfoModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
mConnectivityManager =
|
mConnectivityManager =
|
||||||
(ConnectivityManager) reactContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
(ConnectivityManager) reactContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
@ -69,11 +82,23 @@ public class ConnectivityModule extends ReactContextBaseJavaModule
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void getCurrentConnectivity(Callback successCallback, Callback errorCallback) {
|
public void getCurrentConnectivity(Callback successCallback, Callback errorCallback) {
|
||||||
|
if (mNoNetworkPermission) {
|
||||||
|
if (errorCallback == null) {
|
||||||
|
FLog.e(ReactConstants.TAG, MISSING_PERMISSION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
errorCallback.invoke(MISSING_PERMISSION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
successCallback.invoke(createConnectivityEventMap());
|
successCallback.invoke(createConnectivityEventMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void isConnectionMetered(Callback successCallback) {
|
public void isConnectionMetered(Callback successCallback) {
|
||||||
|
if (mNoNetworkPermission) {
|
||||||
|
FLog.e(ReactConstants.TAG, MISSING_PERMISSION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
successCallback.invoke(mConnectivityManagerCompat.isActiveNetworkMetered(mConnectivityManager));
|
successCallback.invoke(mConnectivityManagerCompat.isActiveNetworkMetered(mConnectivityManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +123,21 @@ public class ConnectivityModule extends ReactContextBaseJavaModule
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCurrentConnectionType() {
|
private String getCurrentConnectionType() {
|
||||||
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
|
try {
|
||||||
if (networkInfo == null || !networkInfo.isConnected()) {
|
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
|
||||||
return CONNECTION_TYPE_NONE;
|
if (networkInfo == null || !networkInfo.isConnected()) {
|
||||||
} else if (ConnectivityManager.isNetworkTypeValid(networkInfo.getType())) {
|
return CONNECTION_TYPE_NONE;
|
||||||
return networkInfo.getTypeName().toUpperCase();
|
} else if (ConnectivityManager.isNetworkTypeValid(networkInfo.getType())) {
|
||||||
} else {
|
return networkInfo.getTypeName().toUpperCase();
|
||||||
|
} else {
|
||||||
|
return CONNECTION_TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
mNoNetworkPermission = true;
|
||||||
return CONNECTION_TYPE_UNKNOWN;
|
return CONNECTION_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendConnectivityChangedEvent() {
|
private void sendConnectivityChangedEvent() {
|
||||||
getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class)
|
getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class)
|
||||||
.emit("networkStatusDidChange", createConnectivityEventMap());
|
.emit("networkStatusDidChange", createConnectivityEventMap());
|
|
@ -20,7 +20,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.modules.fresco.FrescoModule;
|
import com.facebook.react.modules.fresco.FrescoModule;
|
||||||
import com.facebook.react.modules.intent.IntentModule;
|
import com.facebook.react.modules.intent.IntentModule;
|
||||||
import com.facebook.react.modules.location.LocationModule;
|
import com.facebook.react.modules.location.LocationModule;
|
||||||
import com.facebook.react.modules.netinfo.ConnectivityModule;
|
import com.facebook.react.modules.netinfo.NetInfoModule;
|
||||||
import com.facebook.react.modules.network.NetworkingModule;
|
import com.facebook.react.modules.network.NetworkingModule;
|
||||||
import com.facebook.react.modules.storage.AsyncStorageModule;
|
import com.facebook.react.modules.storage.AsyncStorageModule;
|
||||||
import com.facebook.react.modules.toast.ToastModule;
|
import com.facebook.react.modules.toast.ToastModule;
|
||||||
|
@ -57,7 +57,7 @@ public class MainReactPackage implements ReactPackage {
|
||||||
new IntentModule(reactContext),
|
new IntentModule(reactContext),
|
||||||
new LocationModule(reactContext),
|
new LocationModule(reactContext),
|
||||||
new NetworkingModule(reactContext),
|
new NetworkingModule(reactContext),
|
||||||
new ConnectivityModule(reactContext),
|
new NetInfoModule(reactContext),
|
||||||
new WebSocketModule(reactContext),
|
new WebSocketModule(reactContext),
|
||||||
new ToastModule(reactContext));
|
new ToastModule(reactContext));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue