最近在学习react-native和QT

react-native 原生开发2 Module开发

NULL jackton 433℃ 0评论

1、原生模块java  AMapLocationReactModule.java

    package com.xiaobu.amap;

import android.util.Log;
import java.util.HashMap;
import java.util.Map;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import com.amap.api.location.CoordinateConverter;
import com.amap.api.location.DPoint;
import com.amap.api.location.CoordinateConverter.CoordType;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationClientOption.AMapLocationMode;
import com.amap.api.location.AMapLocationListener;

import javax.annotation.Nullable;


public class AMapLocationReactModule extends ReactContextBaseJavaModule implements AMapLocationListener{

 //声明AMapLocationClient类对象
 private final AMapLocationClient mLocationClient;

 //声明定位回调监听器
 private AMapLocationListener mLocationListener = this; // new AMapLocationListener();

 private final ReactApplicationContext mReactContext;


 private boolean needMars = false;
 private boolean needDetail = false;

 private void sendEvent(String eventName,
 @Nullable WritableMap params) {
 if (mReactContext != null) {
 mReactContext
 .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
 .emit(eventName, params);
 }
 }


 public AMapLocationReactModule(ReactApplicationContext reactContext) {
 super(reactContext);
 //初始化定位
 this.mLocationClient = new AMapLocationClient(reactContext);
 //设置定位回调监听
 this.mLocationClient.setLocationListener(mLocationListener);
 mReactContext = reactContext;
 }

 @Override
 public String getName() {
 return "AMapLocation";
 }

 @Override
 public Map<String, Object> getConstants() {
 final Map<String, Object> constants = new HashMap<>();
 // constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
 // constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
 return constants;
 }

 // 开启位置监听
 @ReactMethod
 public void startLocation(@Nullable ReadableMap options) {
 this.mLocationClient.startLocation();
 AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
 // 默认值
 needMars = false;
 needDetail = false;
 if (options != null) {
 if (options.hasKey("needMars")) {
 needMars = options.getBoolean("needMars");
 }
 if (options.hasKey("needDetail")) {
 needDetail = options.getBoolean("needDetail");
 }
 if (options.hasKey("accuracy")) {
 //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
 switch(options.getString("accuracy")) {
 case "BatterySaving":
 mLocationOption.setLocationMode(AMapLocationMode.Battery_Saving);
 break;
 case "DeviceSensors":
 mLocationOption.setLocationMode(AMapLocationMode.Device_Sensors);
 break;
 case "HighAccuracy":
 mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
 break;
 default:
 break;
 }
 }
 if (options.hasKey("needAddress")) {
 //设置是否返回地址信息(默认返回地址信息)
 mLocationOption.setNeedAddress(options.getBoolean("needAddress"));
 }
 if (options.hasKey("onceLocation")) {
 //设置是否只定位一次,默认为false
 mLocationOption.setOnceLocation(options.getBoolean("onceLocation"));
 }
 if (options.hasKey("wifiActiveScan")) {
 //设置是否强制刷新WIFI,默认为强制刷新
 //模式为仅设备模式(Device_Sensors)时无效
 mLocationOption.setWifiActiveScan(options.getBoolean("wifiActiveScan"));
 }
 if (options.hasKey("mockEnable")) {
 //设置是否允许模拟位置,默认为false,不允许模拟位置
 //模式为低功耗模式(Battery_Saving)时无效
 mLocationOption.setMockEnable(options.getBoolean("mockEnable"));
 }
 if (options.hasKey("interval")) {
 //设置定位间隔,单位毫秒,默认为2000ms
 mLocationOption.setInterval(options.getInt("interval"));
 }
 if (options.hasKey("killProcess")) {
 //设置退出时是否杀死service
 //默认值:false, 不杀死
 //模式为仅设备模式(Device_Sensors)时无效
 mLocationOption.setKillProcess(options.getBoolean("killProcess"));
 }

 if (options.hasKey("httpTimeOut")) {
 //设置联网超时时间
 //默认值:30000毫秒
 //模式为仅设备模式(Device_Sensors)时无效
 mLocationOption.setHttpTimeOut(options.getInt("httpTimeOut"));
 }
 }

 //给定位客户端对象设置定位参数
 this.mLocationClient.setLocationOption(mLocationOption);
 //启动定位
 this.mLocationClient.startLocation();
 }

 // 停止位置监听
 @ReactMethod
 public void stopLocation() {
 this.mLocationClient.stopLocation();
 }

 // 坐标转换

 /*
 @Override
 protected void onDestroy() {
 super.onDestroy();
 if (null != this.mLocationClient) {
 this.mLocationClient.onDestroy();
 this.mLocationClient = null;
 }
 }
 */


 // 获得定位结果
 @Override
 public void onLocationChanged(AMapLocation amapLocation) {
 if (amapLocation != null) {
 sendEvent("onLocationChangedAMAPLOCATION", amapLocationToObject(amapLocation));
 }
 }


 private WritableMap amapLocationToObject(AMapLocation amapLocation) {
 WritableMap map = Arguments.createMap();
 Integer errorCode = amapLocation.getErrorCode();
 if (errorCode > 0) {
 map.putInt("errorCode", errorCode);
 map.putString("errorInfo", amapLocation.getErrorInfo());
 } else {
 Double latitude = amapLocation.getLatitude();
 Double longitude = amapLocation.getLongitude();
 if (!needMars) {

 try {
 CoordinateConverter converter = new CoordinateConverter(mReactContext);
 //返回true代表当前位置在大陆、港澳地区,反之不在。
 boolean isAMapDataAvailable = converter.isAMapDataAvailable(latitude,longitude);
 if (isAMapDataAvailable) {
 // 在中国境内,火星了
 double[] deltas = delta(latitude, longitude);
 latitude = latitude - deltas[0];
 longitude = longitude - deltas[1];
 }
 } catch (Exception ex) {
 return null;
 }
 }

 map.putInt("locationType", amapLocation.getLocationType());
 map.putDouble("latitude", latitude);
 map.putDouble("longitude", longitude);


 if (needDetail) {
 // GPS Only
 map.putDouble("accuracy", amapLocation.getAccuracy());
 map.putInt("satellites", amapLocation.getSatellites());
 map.putDouble("altitude", amapLocation.getAltitude());
 map.putDouble("speed", amapLocation.getSpeed());
 map.putDouble("bearing", amapLocation.getBearing());

 map.putString("address", amapLocation.getAddress());
 map.putString("adCode", amapLocation.getAdCode());
 map.putString("country", amapLocation.getCountry());
 map.putString("province", amapLocation.getProvince());
 map.putString("poiName", amapLocation.getPoiName());
 map.putString("provider", amapLocation.getProvider());
 map.putString("locationDetail", amapLocation.getLocationDetail());
 map.putString("street", amapLocation.getStreet());
 map.putString("streetNum", amapLocation.getStreetNum());
 map.putString("city", amapLocation.getCity());
 map.putString("cityCode", amapLocation.getCityCode());
 map.putString("country", amapLocation.getCountry());
 map.putString("district", amapLocation.getDistrict());
 // map.putString("aoiName", amapLocation.getAOIName());
 }

 }
 return map;
 }

 // Utils
 public static double transformLat(double x, double y) {
 double ret =
 -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
 ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
 ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0;
 ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0;
 return ret;
 }

 public static double transformLon(double x, double y) {
 double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
 ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
 ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0;
 ret +=
 (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0;
 return ret;
 }
 /**
 *
 * @param lat纬度
 * @param lng经度
 * @return delta[0] 是纬度差,delta[1]是经度差
 */
 public static double[] delta(double lat,double lng){
 double[] delta = new double[2];
 double a = 6378245.0;
 double ee = 0.00669342162296594323;
 double dLat = transformLat(lng-105.0, lat-35.0);
 double dLng = transformLon(lng-105.0, lat-35.0);
 double radLat = lat / 180.0 * Math.PI;
 double magic = Math.sin(radLat);
 magic = 1 - ee*magic*magic;
 double sqrtMagic = Math.sqrt(magic);
 delta[0] = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI);
 delta[1] = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);
 return delta;
 }

}

2、package管理导出 AMapLocationReactPackage.java

   package com.xiaobu.amap;

import android.app.Activity;

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.Arrays;
import java.util.Collections;
import java.util.List;


public class AMapLocationReactPackage implements ReactPackage {
 
 @Override
 public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
 return Arrays.<NativeModule>asList(new AMapLocationReactModule(reactContext));
 }

 @Override
 public List<Class<? extends JavaScriptModule>> createJSModules() {
 return Collections.emptyList();
 }

 @Override
 public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
 return Arrays.<ViewManager>asList(new GaoDeMapViewManager());
 }
}

3、原生调用js

    import {NativeModules, DeviceEventEmitter} from 'react-native';

const AMapLocation = NativeModules.AMapLocation;
const onLocationChanged = 'onLocationChangedAMAPLOCATION';


export default class ALocation {

 static startLocation(options) {
 AMapLocation.startLocation(options);
 }

 static stopLocation() {
 AMapLocation.stopLocation();
 }

 static addEventListener(handler) {

 const listener = DeviceEventEmitter.addListener(
 onLocationChanged,
 handler,
 );
 return listener;
 }
}

转载请注明:Coding » react-native 原生开发2 Module开发

喜欢 (0)

您必须 登录 才能发表评论!