首先:RN与android端通信,使用RCTDeviceEventEmitter,RN先获取android6.0权限,然后给android发送请求获取Mac,android端收到后返回Mac给rn。
步骤如下:可参照rn官网对于ToastAndroid的方式:http://facebook.github.io/react-native/docs/native-modules-android.html
1.Java端写获取获取Mac的方法
继承ReactContextBaseJavaMoudle,实现getName方法,这里返回的string就是你的moudle名字,类比RN中的ToastAndroid。
写RN调用的获取mac的方法,使用@ReactNative注解,表示这个native方法,在这个方法里面实现你获取Mac的方法,并且将Mac地址通 过 RCTDeviceEventEmitter返回给RN。
代码如下:
package com.boxinspect_jinshan;
/**
* Created by shibo on 2018/5/17.
*/
import android.widget.Toast;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.net.NetworkInterface;
import java.util.Enumeration;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.core.DeviceEventManagerModule;
public class GetMacMoudle extends ReactContextBaseJavaModule {
ReactApplicationContext reactContext;
public GetMacMoudle(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext=reactContext;
}
@Override
public String getName() {
return "GetMacMoudle";
}
@ReactMethod
public void getMac() {
// Toast.makeText(getReactApplicationContext(), getPhoneMacAddress(getReactApplicationContext()), Toast.LENGTH_LONG).show();
//给rn发送信息
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("nativeCallRn", getPhoneMacAddress(getReactApplicationContext()));
}
private static final String marshmallowMacAddress = "02:00:00:00:00:00";
public static String getPhoneMacAddress(Context context) {
WifiManager wifiMan = (WifiManager)context.getSystemService(Context.WIFI_SERVICE) ;
WifiInfo wifiInf = wifiMan.getConnectionInfo();
if(wifiInf !=null && marshmallowMacAddress.equals(wifiInf.getMacAddress())){
return getAndroid6MacAddress();
}
else {
if (wifiInf != null && wifiInf.getMacAddress() != null) {
return wifiInf.getMacAddress();
} else {
return "";
}
}
}
public static String getAndroid6MacAddress() {
String str = "";
String macSerial = "";
try {
Process pp = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address ");
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
for (; null != str;) {
str = input.readLine();
if (str != null) {
macSerial = str.trim();// 去空格
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
if (macSerial == null || "".equals(macSerial)) {
try {
return loadFileAsString("/sys/class/net/eth0/address").toUpperCase().substring(0, 17);
} catch (Exception e) {
e.printStackTrace();
}
//N
//针对android7.0获取mac
if (TextUtils.isEmpty(macSerial)) {
Log.e("到7.0这里了","====");
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iF = interfaces.nextElement();
byte[] addr = iF.getHardwareAddress();
if (addr == null || addr.length == 0) {
continue;
}
StringBuilder buf = new StringBuilder();
for (byte b : addr) {
buf.append(String.format("%02X:", b));
}
if (buf.length() > 0) {
buf.deleteCharAt(buf.length() - 1);
}
String mac = buf.toString();
// Trace.d(LOG_TAG, "interfaceName=" + iF.getName() + ", mac=" + mac);
if (iF.getName().equalsIgnoreCase("wlan0")) {
macSerial=mac;
break;
}
}
} catch (Exception e) {
// Log.d(LOG_TAG, "SocketException e=" + e.getMessage());
e.printStackTrace();
}
}
//stop
}
return macSerial;
}
public static String loadFileAsString(String fileName) throws Exception {
FileReader reader = new FileReader(fileName);
String text = loadReaderAsString(reader);
reader.close();
return text;
}
public static String loadReaderAsString(Reader reader) throws Exception {
StringBuilder builder = new StringBuilder();
char[] buffer = new char[4096];
int readLength = reader.read(buffer);
while (readLength >= 0) {
builder.append(buffer, 0, readLength);
readLength = reader.read(buffer);
}
return builder.toString();
}
}
2.Java端实现一个ReactPackage
继承ReactPackage,重写createNativeMoudle,将刚才写的GetMacMoudle加入到这个package里面。注意:在网上的其他文章里面,他们重写了
createJSMoudles方法,但是再这个版本中,这个方法不能再实现了,否则报错。
代码如下:
package com.boxinspect_jinshan;
/**
* Created by shibo on 2018/5/17.
*/
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 GetMacReactPackage implements ReactPackage{
public GetMacMoudle module;
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
module=new GetMacMoudle(reactContext);
modules.add(module);
return modules;
}
// @Override
// public List<Class<? extends JavaScriptModule>> createJSModules() {
// return Collections.emptyList();
//}
}
3.Java中将这个Package加入到Application里面
去MainApplication里面,在getPackages()方法里面把这个package加入到数组里面
代码如下:
package com.boxinspect_jinshan;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
public static ReactPackage reactPackage;
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
,getReactPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
//
public static ReactPackage getReactPackage(){
if(reactPackage==null){
reactPackage=new GetMacReactPackage();
}
return reactPackage;
}
}
4.调用
import { NativeModules } from 'react-native';
export default NativeModules.GetMacMoudle;
import GetMacMoudle from './GetMacUtil'
请求mac:
先去获取6.0权限(我这是实际项目所有有获取mac不需要的权限),获取成功了去调用android:
async getPermission() {
//获取读取设备信息,拍照,mac地址等的
const granteds = await PermissionsAndroid.requestMultiple([PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
PermissionsAndroid.PERMISSIONS.CAMERA]
)
if (granteds[PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE] == PermissionsAndroid.RESULTS.GRANTED &&
granteds[PermissionsAndroid.PERMISSIONS.CAMERA] == PermissionsAndroid.RESULTS.GRANTED) {
GetMacMoudle.getMac();
console.log("已经获取到权限");
Alert.alert("获取到权限");
} else {
console.log("没有获取到权限");
Alert.alert("没有获取到权限");
}
}
写对于android返回数据的回调:
componentDidMount() {
DeviceEventEmitter.addListener('nativeCallRn', (msg) => {
console.log("收到来自android的信息" + msg);
this.setState((prevState) => ({mac: msg}));
})
}