前言

地图、定位对于移动开发来说不可或缺,下面尝试封装高德地图作为 React-Native组件。我只写了android部分,ios如有需求请移驾我公司大神发布的组件https://github.com/react-native-component/react-native-smart-amap

账号与Key的申请

注册成为高德开发者需要分三步:
第一步,注册高德开发者;第二步,去控制台创建应用;第三步,获取Key。
具体步骤:
1、注册高德开发者
2、创建应用
3、获取API key
申请地址:http://lbs.amap.com/

配置AndroidManifest.xml

//地图包、搜索包需要的基础权限

<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />  
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />    
<!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

设置高德Key

gradle文件中添加

defaultConfig {
        minSdkVersion 19
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        manifestPlaceholders = [
                AMAP_KEY:"你的 Appkey"
        ]
    }

在application标签中加入:

<meta-data
        android:name="com.amap.api.v2.apikey"
        android:value="${AMAP_KEY}"/>

Android部分

使用AS创建Library项目,右键点击项目并选择Open Module Settings,选中Dependencies,点击下面等➕号选择Library dependency,搜索AMap添加导入就可以使用sdk了。

dependencies {
...
    compile 'com.amap.api:map2d:2.9.1'
    compile 'com.amap.api:location:3.1.0'
    compile 'com.amap.api:search:3.5.0'
}
原生UI

AMap动画比较卡,期间还造成定位不准确,建议不使用动画,定位后加图标,Poi搜索都在回调事件中处理,以下是RCTAMapView代码,定位功能,poi搜索功能,看个人需求也可以封装到原生模块中

public class RCTAMapView extends FrameLayout implements LocationSource, AMapLocationListener,
        PoiSearch.OnPoiSearchListener, AMap.OnCameraChangeListener {
        ...
        //定义一堆成员变量
        ...
/**
     * 初始化View
     * @param context
     */
    public RCTAMapView(ThemedReactContext context) {
        super(context);
        this.CONTEXT = context;
        CenterView = new ImageView(context);//空间中间显示到图标
        Resources resources =context.getCurrentActivity().getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        this.density = dm.density;
//        SCROLL_BY_PX=(int)(SCROLL_BY_PX*density+0.5);

        PARAM = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    }

    /**
     * 初始化控件,定位位置
     */
    private void init() {
        mSensorHelper = new SensorEventHelper(CONTEXT);
        if (mSensorHelper != null) {
            mSensorHelper.registerSensorListener();
        }
        MAPVIEW = new MapView(CONTEXT);
        MAPVIEW.setLayoutParams(PARAM);
        this.addView(MAPVIEW);
        MAPVIEW.onCreate(CONTEXT.getCurrentActivity().getIntent().getExtras());


        CenterView.setLayoutParams(new ViewGroup.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
//        CenterView.setImageResource(R.drawable.poi_marker);
        CenterView.setImageResource(getSplashId(CENTERMARKER));
        this.addView(CenterView, 1);

        setUpMap();

        poiSearch = new PoiSearch(CONTEXT, query);
    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {

        AMAP = MAPVIEW.getMap();
        AMAP.setMapType(AMap.MAP_TYPE_NORMAL);// 矢量地图模式

        mUiSettings = AMAP.getUiSettings();//实例化UiSettings类
        mUiSettings.setZoomControlsEnabled(ZOOMCONTROLS);//显示缩放按钮
        mUiSettings.setZoomPosition(ZOOM_POSITION_RIGHT_CENTER);//缩放按钮  右边界中部:ZOOM_POSITION_RIGHT_CENTER 右下:ZOOM_POSITION_RIGHT_BUTTOM。
        mUiSettings.setLogoPosition(LOGO_POSITION_BOTTOM_RIGHT);//Logo的位置 左下:LOGO_POSITION_BOTTOM_LEFT 底部居中:LOGO_POSITION_BOTTOM_CENTER 右下:LOGO_POSITION_BOTTOM_RIGHT
        mUiSettings.setCompassEnabled(COMPASSENABLE);//指南针
        mUiSettings.setZoomGesturesEnabled(ZOOMGESTURES);//手势缩放
        mUiSettings.setScaleControlsEnabled(SCALECONTROLS);//比例尺

        changeCamera(
                CameraUpdateFactory.newCameraPosition(new CameraPosition(
                        latLng, ZOOMLEVEL, 30, 0)));//创建view时候传入之前定位到当前坐标位置把地图中心移动过去

        mFirstFix = true;
        addLocationMarker(latLng, RADIUS, mLocMarker);


        AMAP.setLocationSource(this);// 设置定位监听
        AMAP.setOnCameraChangeListener(this);// 对amap添加移动地图事件监听器
        mUiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
        AMAP.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false

    }
     /**
     * Activity onResume后调用view的onAttachedToWindow
     */
    @Override
    protected void onAttachedToWindow() {
        init();
        super.onAttachedToWindow();
    }
        /**
     * Activity onResume后调用view的onAttachedToWindow
     */
    @Override
    protected void onAttachedToWindow() {
        init();
        super.onAttachedToWindow();
    }
     /**
     * view生命周期onDetachedFromWindow
     */
    @Override
    protected void onDetachedFromWindow() {
        this.removeView(MAPVIEW);
        MAPVIEW.onDestroy();
        super.onDetachedFromWindow();
    }

    /**
     * 对应onResume、对应onPause
     *
     * @param hasWindowFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {

        super.onWindowFocusChanged(hasWindowFocus);

        if (hasWindowFocus) {
//            对应onResume
            MAPVIEW.onResume();
        } else {
            //对应onPause
            MAPVIEW.onPause();

        }

    }

重写onLayout处理中心点图标位置

@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
/**
 * 处理中心点控件位置
 */
        HEIGHT = getHeight();//在这里才可以拿到控件到高低
        WIDTH = getWidth();
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) CenterView.getLayoutParams();

        viewWidth = CenterView.getMeasuredWidth();
        viewHeight = CenterView.getMeasuredHeight();


        params.setMargins(WIDTH / 2 - viewWidth / 2, HEIGHT / 2 - viewHeight, 0, 0);
        CenterView.setLayoutParams(params);
//        CenterView.invalidate();

        super.onLayout(changed, left, top, right, bottom);

    }

发起定位,发起poi搜索以及回调方法:

/**
     * 定位到设备定位位置
     */
    public void startLocation() {
        startTime = System.currentTimeMillis();
        Log.i("Test", "startTime:" + startTime);
        if (mlocationClient == null) {
            Log.i("Test", "mlocationClient = null");
            mlocationClient = new AMapLocationClient(CONTEXT);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            mLocationOption.setOnceLocation(ONCELOCATION);
//            mLocationOption.setOnceLocationLatest(true);
            mLocationOption.setLocationCacheEnable(true);//定位缓存策略
//            mLocationOption.setInterval(10);
//            mLocationOption.setInterval(3*60*1000);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);

            // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
            // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后,在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除

        }
        mlocationClient.startLocation();
    }
    public void poiSearch(String keyWord, String cityCode, int currentPage) {
        query = new PoiSearch.Query(keyWord, QUERYTYPE, cityCode);
//keyWord表示搜索字符串,
//第二个参数表示POI搜索类型,二者选填其一,
//POI搜索类型共分为以下20种:汽车服务|汽车销售|
//汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|
//住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|
//金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
//cityCode表示POI搜索区域,可以是城市编码也可以是城市名称,也可以传空字符串,空字符串代表全国在全国范围内进行搜索

        query.setPageSize(PAGESIZE);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);//设置查询页码

        poiSearch.setQuery(query);
        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();
    }

    public void poiSearchRound(LatLonPoint latlng, String cityCode, int currentPage) {
        if (cityCode == null || "".equals(
                cityCode)) {
            cityCode = DEFAULTCITY;
        }
        query = new PoiSearch.Query("", QUERYTYPE, cityCode);

        query.setPageSize(PAGESIZE);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);//设置查询页码

        poiSearch.setQuery(query);
        poiSearch.setOnPoiSearchListener(this);

        poiSearch.setBound(new PoiSearch.SearchBound(latlng, 1000));//设置周边搜索的中心点以及半径
        poiSearch.searchPOIAsyn();
    }


    private void addCircle(LatLng latlng, float RADIUS) {
        CircleOptions options = new CircleOptions();
        options.strokeWidth(1f);
        options.fillColor(FILL_COLOR);
        options.strokeColor(STROKE_COLOR);
        options.center(latlng);
        options.radius(RADIUS);
        mCircle = AMAP.addCircle(options);

/*        ObjectAnimator radiusAnim = ObjectAnimator.ofFloat(mCircle, "radius", radius,0.0f,radius);
        radiusAnim.setDuration(1000);
        radiusAnim.setRepeatCount(ValueAnimator.INFINITE);//无限循环
//        translationYAnim.setRepeatMode(ValueAnimator.INFINITE);
        radiusAnim.start();*/

    }

    private void addMarker(LatLng latlng) {
        if (mLocMarker != null) {
            return;
        }
//        Bitmap bMap = BitmapFactory.decodeResource(this.getResources(),
//                R.drawable.navi_map_gps_locked);
        Bitmap bMap = BitmapFactory.decodeResource(this.getResources(),
                getSplashId(LOCATIONMARKER));
        BitmapDescriptor des = BitmapDescriptorFactory.fromBitmap(bMap);

//      BitmapDescriptor des = BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps_locked);
        MarkerOptions options = new MarkerOptions();
        options.icon(des);
        options.anchor(0.5f, 0.5f);
        options.position(latlng);
        // 将Marker设置为贴地显示,可以双指下拉看效果

        mLocMarker = AMAP.addMarker(options);
    }


    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
//        startLocation();
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    /**
     * poi搜索回调
     * @param result
     * @param rCode
     */
    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        List<PoiItem> poiItems = new ArrayList<>();
        if (rCode == 1000) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                if (result.getQuery().equals(query)) {// 是否是同一条
                    poiResult = result;
                    // 取得搜索到的poiitems有多少页
                    poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始
                  /*  List<SuggestionCity> suggestionCities = poiResult
                            .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息*/
                   /* if (poiItems != null && poiItems.size() > 0) {
                        for (PoiItem poi : poiItems) {
                            //event发送

                            Log.i("Test", "PoiItem:" + poi.getCityName() + "," + poi.getAdName() + "," + poi.getTitle() + "," + poi.getSnippet() + "," + poi.getLatLonPoint().getLongitude());
                        }
                    }*/
                }
            }
        }
//        onEvChangeListener.getPoiItem(poiItems);
        sendPoi2RN(poiItems);

    }

    /**
     * 获得对应module 发送数据到RN
     *
     * @param poiItems
     */
    private void sendPoi2RN(List<PoiItem> poiItems) {
        WritableMap event = Arguments.createMap();
        WritableArray array = Arguments.createArray();
        for (PoiItem poi : poiItems) {
            WritableMap data = Arguments.createMap();
            data.putString("uid", poi.getPoiId());
            data.putString("name", poi.getTitle());
            data.putString("type", poi.getTypeDes());
            data.putDouble("Longitude", poi.getLatLonPoint().getLongitude());
            data.putDouble("Latitude", poi.getLatLonPoint().getLatitude());
            data.putString("address", poi.getSnippet());
            data.putString("tel", poi.getTel());
            data.putInt("distance", poi.getDistance());
            array.pushMap(data);
        }
        event.putArray("searchResultList", array);

        CONTEXT.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("PoiEvent", event);
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }
/**
     * 定位回调
     * @param amapLocation
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {

        if (!ISFIRSTMOVE) {
            ISFIRSTMOVE = true;
        }

        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    && amapLocation.getErrorCode() == 0) {

                location = new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude());
//                Log.i("TEST", "getLatitude:"+amapLocation.getLatitude()+"getLongitude:"+amapLocation.getLongitude());
                DEFAULTCITY = amapLocation.getCity();
                if (!mFirstFix) {
                    mFirstFix = true;
                    addLocationMarker(location, RADIUS, mLocMarker);
//                    首次定位到点location
//                    AMAP.moveCamera(CameraUpdateFactory.newLatLngZoom(location, ZOOMLEVEL));
                } else {
                    mCircle.setCenter(location);
                    mCircle.setRadius(RADIUS);
                    mLocMarker.setPosition(location);
                }
                //移动镜头定位到点location
                /*AMAP.moveCamera(CameraUpdateFactory.newLatLngZoom(location, ZOOMLEVEL));*/

                changeCamera(
                        CameraUpdateFactory.newCameraPosition(new CameraPosition(
                                location, ZOOMLEVEL, 30, 0)));
              /*  animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(
                        location, ZOOMLEVEL, 30, 0)),null);*/
                changeCamera(CameraUpdateFactory.scrollBy(0, -SCROLL_BY_PX));
            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Log.i("TEST", errText);

            }
        }

    }

RCTAMapManager代码如下:

public class RCTAMapManager extends ViewGroupManager<RCTAMapView> {
    public static final LatLng SHANGHAI = new LatLng(31.238068, 121.501654);// 上海市经纬度
    @Override
    public String getName() {
        return "RCTAMapView";
    }


    @Override
    protected RCTAMapView createViewInstance(ThemedReactContext reactContext) {
//        SDKInitializer.initialize(reactContext.getApplicationContext());
        RCTAMapView map=new RCTAMapView(reactContext);
//        map.startLocation();
        return map;
    }

    @ReactProp(name = "LatLng")
    public void setLatLng(RCTAMapView view,ReadableMap Map) {

        if (Map == null) {
            view.setLatLng(SHANGHAI);
            return;
        }
        view.setLatLng(new LatLng(Map.getDouble("latitude"),Map.getDouble("longitude")));

    }

    /**
     * 查询poi每页显示多少行
     * @param view
     * @param pagesize
     */
    @ReactProp(name = "PAGESIZE",defaultInt = 10)
    public void setPAGESIZE(RCTAMapView view,int pagesize) {
            view.setPAGESIZE(pagesize);

    }

    /**
     * 定位光圈半径
     * @param view
     * @param RADIUS
     */
    @ReactProp(name = "RADIUS",defaultInt = 10)
    public void setRADIUS(RCTAMapView view,int RADIUS) {
            view.setRADIUS(RADIUS);

    }

    /**
     * 定位光圈半径
     * @param view
     * @param ZOOMLEVEL
     */
    @ReactProp(name = "ZOOMLEVEL",defaultInt = 18)
    public void setZOOMLEVEL(RCTAMapView view,int ZOOMLEVEL) {
            view.setZOOMLEVEL(ZOOMLEVEL);

    }

    /**
     * poi查询类型
     * //POI搜索类型共分为以下20种:汽车服务|汽车销售|
     //汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|
     //住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|
     //金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
     * @param view
     * @param QUERYTYPE
     */
    @ReactProp(name = "QUERYTYPE")
    public void setQUERYTYPE(RCTAMapView view,String QUERYTYPE) {
        if(QUERYTYPE!=null) {
            view.setQUERYTYPE(QUERYTYPE);
        }

    }

    /**
     * uisetting 初始化地图参数
     *
     ZOOMCONTROLS 显示缩放按钮
     ZOOMGESTURES 手势缩放
     SCALECONTROLS 显示比例尺
     COMPASSENABLE 显示指南针
     ONCELOCATION 是否一次定位

     LOCATIONMARKER 定位图片资源名称
     CENTERMARKER   中心点图片资源名称
     * @param view
     * @param Map
     */
    @ReactProp(name = "UISETTING")
    public void setUISETTING(RCTAMapView view,ReadableMap Map) {
        if(Map!=null) {
           if( Map.hasKey("ZOOMCONTROLS"))
            view.setZOOMCONTROLS(Map.getBoolean("ZOOMCONTROLS"));
            if( Map.hasKey("ZOOMGESTURES"))
            view.setZOOMGESTURES(Map.getBoolean("ZOOMGESTURES"));
            if( Map.hasKey("SCALECONTROLS"))
            view.setSCALECONTROLS(Map.getBoolean("SCALECONTROLS"));
            if( Map.hasKey("COMPASSENABLE"))
            view.setCOMPASSENABLE(Map.getBoolean("COMPASSENABLE"));
            if( Map.hasKey("ONCELOCATION"))
            view.setCOMPASSENABLE(Map.getBoolean("ONCELOCATION"));
            if( Map.hasKey("CENTERMARKER"))
            view.setCENTERMARKER(Map.getString("CENTERMARKER"));
            if( Map.hasKey("LOCATIONMARKER"))
            view.setLOCATIONMARKER(Map.getString("LOCATIONMARKER"));

        }

    }

    @Override
    protected void addEventEmitters(
            final ThemedReactContext reactContext,
            final RCTAMapView view) {
        view.setOnEvChangeListener(
                new RCTAMapView.OnEvChangeListener() {
                    @Override
                    public void getPoiItem(List<PoiItem> poiItem) {
                        reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher()
                                .dispatchEvent(new PoiEvent(view.getId(),poiItem));
                    }



                });
    }

    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put("PoiItemEvent", MapBuilder.of("registrationName", "onPoiSearch"))//registrationName 后的名字,RN中方法也要是这个名字否则不执行
                .put("onViewCenterChangeFinish", MapBuilder.of("registrationName", "onMapViewCenterChangeFinish"))//registrationName 后的名字,RN中方法也要是这个名字否则不执行
                .build();
    }

}
原生模块

RCTLBSModule代码如下:

public class RCTLBSModule extends ReactContextBaseJavaModule {
    ReactApplicationContext mContext;
    private AMapLocationClient locationClient = null;
    private AMapLocationClientOption locationOption = new AMapLocationClientOption();
boolean ADDRESSCHECK,GPSCHECK,CACHECHECK,LATESTCHECK,SENSORCHECK;
    long STRINTERVAL=2000;
     long TIMEOUT =30000;

    public RCTLBSModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
        LATESTCHECK=true;

    }

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

    /**
     * 开启定位服务
     */
    @ReactMethod
    public void startLocationService() {
        /**
         * 创建定位请求
         */
        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
//                if(mLocationClient==null) {
//                    initLocation();
//                }
//                mLocationClient.start();

                if (locationClient == null) {
                    initLocation();
                }

                startLocation();
            }
        });
    }

  /*  @ReactMethod
    public void getCenterLocation(final int tag){
        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag));
                Map.getCenterLocation();
            }
            });
    }*/

    @ReactMethod
    public void setCenterLocation(final int tag,final double latitude,final double longitude){
        mContext.getCurrentActivity().runOnUiThread(new Runnable() {
            public void run() {
                final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag));
                Map.setCenterLocation(latitude,longitude);
            }
        });
    }

    @ReactMethod
    public void startLocation(int tag){
        final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag));
        Map.startLocation();
    }
    @ReactMethod
    public void poiSearch(int tag,String keyWord,String cityCode,int currentPage){
        final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag));
        Map.poiSearch(keyWord,cityCode,currentPage);
    }
    @ReactMethod
    public void poiSearchRound(int tag,final double latitude,final double longitude,String cityCode,int currentPage){
        final RCTAMapView Map = ((RCTAMapView) mContext.getCurrentActivity().findViewById(tag));
        Map.poiSearchRound(new LatLonPoint(latitude,longitude),cityCode,currentPage);
    }



    /**
     * 初始化定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void initLocation() {
        //初始化client
        locationClient = new AMapLocationClient(mContext.getApplicationContext());
        //设置定位参数
        locationClient.setLocationOption(getDefaultOption());
        // 设置定位监听
        locationClient.setLocationListener(locationListener);
    }

    /**
     * 默认的定位参数
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private AMapLocationClientOption getDefaultOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(TIMEOUT);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(STRINTERVAL);//可选,设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(true);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
        return mOption;
    }

    /**
     * 定位监听
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation loc) {
            if (null != loc) {
                //解析定位结果
                String LocationData = Utils.getLocationStr(loc);
                WritableMap params = Arguments.createMap();
                params.putString("AMapLocation", LocationData);
                sendEvent(mContext, "onAMAPLocationResult", params);
            } else {

            }
        }
    };

    // 根据控件的选择,重新设置定位参数
    private void resetOption() {
        // 设置是否需要显示地址信息
        locationOption.setNeedAddress(ADDRESSCHECK);
        /**
         * 设置是否优先返回GPS定位结果,如果30秒内GPS没有返回定位结果则进行网络定位
         * 注意:只有在高精度模式下的单次定位有效,其他方式无效
         */
        locationOption.setGpsFirst(GPSCHECK);
        // 设置是否开启缓存
        locationOption.setLocationCacheEnable(CACHECHECK);
        //设置是否等待设备wifi刷新,如果设置为true,会自动变为单次定位,持续定位时不要使用
        locationOption.setOnceLocationLatest(LATESTCHECK);
        //设置是否使用传感器
        locationOption.setSensorEnable(SENSORCHECK);


            try {
                // 设置发送定位请求的时间间隔,最小值为1000,如果小于1000,按照1000算
                locationOption.setInterval(STRINTERVAL);
            } catch (Throwable e) {
                e.printStackTrace();
            }

            try {
                // 设置网络请求超时时间
                locationOption.setHttpTimeOut(TIMEOUT);
            } catch (Throwable e) {
                e.printStackTrace();
            }

    }

    /**
     * 开始定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private void startLocation() {
        //根据控件的选择,重新设置定位参数
        resetOption();
        // 设置定位参数
        locationClient.setLocationOption(locationOption);
        // 启动定位
        locationClient.startLocation();
    }

    /**
     * 停止定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */

    private void stopLocation() {
        // 停止定位
        locationClient.stopLocation();
    }

    /**
     * 销毁定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    @ReactMethod
    private void destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的,
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient.onDestroy();
            locationClient = null;
            locationOption = null;
        }
    }





    @ReactMethod
    public void stopLocationService() {
        stopLocation();

    }



    private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }

JS部分

组件部分封装到这里就结束啦 amap.js如下

import React, { Component, PropTypes } from 'react';
import {
    NativeAppEventEmitter,
    NativeModules,
    Platform,
    StyleSheet,
    requireNativeComponent,
    View,
    findNodeHandle,

} from 'react-native';
const MapManager = NativeModules.LBSModule;
const MapView = requireNativeComponent('RCTAMapView', AMapView);

export default class AMapView extends Component {

    static defaultProps = {}

    static propTypes = {

        ...View.propTypes, // 包含默认的View的属性
        LatLng:PropTypes.object,
        PAGESIZE:PropTypes.number,
        RADIUS:PropTypes.number,
        QUERYTYPE:PropTypes.string,
        UISETTING:PropTypes.object,
        onPoiSearch: PropTypes.func.isRequired,
        onMapViewCenterChangeFinish:PropTypes.func,

    }

    render() {
        return (
                <MapView
                    {...this.props}

                />

        );
    }




    //findNodeHandle(this) 传递View Id给RN module
    getCenterLocation() {
        MapManager.getCenterLocation(findNodeHandle(this))
    }

    startLocation() {

        MapManager.startLocation(findNodeHandle(this))
    }



    poisearch(keyWord, i,page) {
        MapManager.poiSearch(findNodeHandle(this), keyWord, i, page)
    }
    poiSearchRound(latitude,longitude, i,page) {
        MapManager.poiSearchRound(findNodeHandle(this), latitude,longitude ,i, page)
    }
}

RN中使用amap

import React, {
    Component,
} from 'react'
import {
    View,
    Text,
    StyleSheet,
    Alert,
    ScrollView,
    ListView,
    TextInput,
    Image,
    ActivityIndicator,
    ProgressBarAndroid,
    ActivityIndicatorIOS,
    TouchableHighlight,
    Platform,
    DeviceEventEmitter,
} from 'react-native'
import AMapView from './aMap'

import TimerEnhance from 'react-native-smart-timer-enhance'
let componentData = {}
let dataSource = new ListView.DataSource({
    rowHasChanged: (r1, r2) => {
        return r1 !== r2
    },
    sectionHeaderHasChanged: (s1, s2) => {
        return s1 !== s2
    },
})

let FirstEdit=0;//判断输入时间
class MapView extends Component {

    constructor(props) {
        super(props);
        // 初始状态
        this.state = {
            value: '',
            componentDataSource: dataSource.cloneWithRows(componentData),

        };
    }


    componentDidMount() {

        DeviceEventEmitter.addListener('PoiEvent', this.handleAndroidMessage);
    }

    componentWillUnMount() {
        //移除监听返回键
        DeviceEventEmitter.removeListener('PoiEvent');

        //关闭定位
        //NativeModules.LBSModule.destroyLocation()
    }

    handleAndroidMessage = (e)=> {
        let array=e.searchResultList;
        if(this.refs.TextInput.value!='') {
            this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(array)});
        }
    }

/*<Text onPress={this._getCenterLocation}
style={{position: 'absolute', bottom: 0, right: 0, padding: 20, fontSize: 24,}}>中心</Text>*/
    render() {
        return (
            <View style={{flex:1,flexDirection:'column',justifyContent:'center'}}>
                <View style={{flex:1}}>
                    <AMapView style={{flex:1}}
                              LatLng={{latitude:31.239201,longitude:121.431598}}
                              ref={ component => this._MapView = component }
                              onPoiSearch={this._onPoiSearch}
                              onMapViewCenterChangeFinish={this._onMapViewCenterChangeFinish}
                              UISETTING={{CENTERMARKER:'poi_marker'}}

                    />

                    <TouchableHighlight underlayColor={'#ccc'}  style={{position: 'absolute', bottom: 10, left: 10,
                     padding: 10,  backgroundColor: '#fff',}}
                                        onPress={this._startLocation}>
                        <Text style={{flex:1,fontSize: 20,}}
                             >定位</Text>

                    </TouchableHighlight>

                </View>
                <View style={{flex:1,flexDirection:'column',justifyContent:'center'}}>
                    <TextInput
                        ref="TextInput"
                        style={[styles.input]}
                        placeholder="请输入名称"
                        maxLength={20}
                        clearButtonMode="while-editing"
                        value={this.state.value}
                        onChangeText={this._changeText.bind(this)}
                        underlineColorAndroid="transparent"//删除下划线
                        //onSubmitEditing={this._onSubmitEditing.bind(this)}
                    />
                    <ListView
                        dataSource={this.state.componentDataSource}
                        enableEmptySections={true}
                        renderRow={this._renderRow}
                        style={{flex:1}}/>

                </View>
            </View>
        )
    }

    _renderRow = (rowData) => {

        return (

            <Text style={styles.item}>{rowData.name+','+rowData.address+','+rowData.distance }</Text>

        )
    }



    _startLocation = (e)=> {
        this._MapView.startLocation()
    }
    _getCenterLocation = (e)=> {
        this._MapView.getCenterLocation()
    }
   /* _onSubmitEditing = ()=> {

        if (value === '') {
            this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)});
        }
        else {

            this._MapView.poisearch(value, '上海')
        }


    }*/
    _changeText = (e)=> {
        let timestamp = (new Date()).valueOf();
        if (timestamp - FirstEdit > 1000) {
            FirstEdit = timestamp;

            if (e === '') {
                this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)});
            } else {

                this._MapView.poisearch(e, '',0)
            }
        }
        if (e === '') {
            this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(componentData)});
        }

        this.setState({value: e});

    }

     _onPoiSearch=(e)=>{
     let array=e.nativeEvent.searchResultList;
         if(this.refs.TextInput.value!='') {
             this.setState({componentDataSource: this.state.componentDataSource.cloneWithRows(array)});
         }
     }
    _onMapViewCenterChangeFinish=(e)=>{

        this._MapView.poiSearchRound(e.nativeEvent.latitude, e.nativeEvent.longitude,'',0)
    }

}
let styles = StyleSheet.create({
    header: {
        height: 40,
        flexDirection: 'row',
        justifyContent: 'flex-start',
        backgroundColor: '#F0F0FF',
        alignItems: 'stretch',
        top: 20,
    },
    flex: {
        flex: 1
    },
    item: {
        height: 30,
        //borderBottomWidth: StyleSheet.hairlineWidth,
        //borderBottomColor: '#ccc',
        overflow: 'hidden',
        justifyContent: 'center',
        alignItems: 'flex-start',

    },
    search: {
        flex: 1,
        height: 30,
        backgroundColor: '#fff',
        alignItems: 'stretch',
        borderWidth: 1,
        borderColor: '#ccc',
        borderRadius: 4,
        flexDirection: 'row',
    },
    input: {
        height: 40,
        borderWidth: 1,
        borderColor: '#ccc',
        borderRadius: 4,
        backgroundColor: '#ffff'
    },
    result: {
        flex: 1,

        backgroundColor: '#fff',
    },
    border: {
        borderWidth: 1,
        borderTopWidth: 0,
        borderColor: '#ccc',
        borderRadius: 4,
    },
    height30: {
        height: 30,
    },
    marginTop5: {
        marginTop: 5,
    },
    search_view: {
        top: 5,
        right: 0,
        width: 300,
        marginRight: 5,
        justifyContent: 'flex-start',
        alignItems: 'stretch',
        position: 'absolute',
        flexDirection: 'column',
    },
});
export default TimerEnhance(MapView)

因为是模拟器演示,定位的时候没有触发,效果如下:

高德地图android开发 高德地图开发支持_搜索