Android集成百度地图-----显示地图、定位、长按显示地址信息

一、基础部分

转载请注明出处:https://blog.csdn.net/Hunter2916/article/details/82867205

1、下载百度地图的SDK

下载地址:http://lbsyun.baidu.com/index.php?title=android-locsdk/geosdk-android-download

2、申请key值

注册百度账号——>登录百度地图官网——>控制台—–>创建应用

具体方法地址:http://lbsyun.baidu.com/apiconsole/key 

3、解压后的jar包放到app下的libs中,并右键add到build.gradle中

build.gradle中添加ndk

ndk {
            //选择要添加的对应 cpu 类型的.so 库。
            abiFilters 'armeabi', 'armeabi-v7a', 'armeabi64-v8a', 'x86', 'x86_64'
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
        }


dependencies{
//百度定位架包
    compile files('libs/BaiduLBS_Android.jar')
}

4、在manifest.xml中添加key和service

 <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="你自己申请的key" />
        <!-- 声明service组件 -->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" />

5、添加权限

<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD卡读取权限,用户写入离线定位数据-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>



//切记有些权限在Android5.0以后还需要在代码中动态获取
//例如:

private void requestRunPermissions() {
        List<PermissionItem> permisson = new ArrayList<>();
        permisson.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, "电话状态", R.drawable.permission_ic_phone));
        permisson.add(new PermissionItem(Manifest.permission.ACCESS_COARSE_LOCATION, "地理位置", R.drawable.permission_ic_location));
        permisson.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "地理位置", R.drawable.permission_ic_location));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            permisson.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "读取权限", R.drawable.permission_ic_storage));
            permisson.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "写入权限", R.drawable.permission_ic_storage));
        }
        HiPermission.create(this)
                .title("开启地图权限")
                .permissions(permisson)
                .filterColor(ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme()))
                .style(R.style.PermissionBlueStyle)
                .msg("我们需要获得以下权限才能为您提供服务")
                .checkMutiPermission(new PermissionCallback() {
                    @Override
                    public void onClose() {

                    }

                    @Override
                    public void onFinish() {
//                        showToastShort("所有权限申请完成");
                    }

                    @Override
                    public void onDeny(String permission, int position) {

                    }

                    @Override
                    public void onGuarantee(String permission, int position) {

                    }
                });
    }


//添加权限第三方框架
compile 'me.weyye.hipermission:library:1.0.7'

6、主界面布局

 <com.baidu.mapapi.map.MapView
            android:id="@+id/bmapView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true" />

7、Activity中的代码

private BaiduMap mBaiduMap;



 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        mBaiduMap = binding.bmapView.getMap();
        //initView();
        //在定位之前进行一次动态的获取权限
        requestRunPermissions();
    }

在不设置任何属性的情况下,定位在北京比例为5公里

7.1、设置缩放比例并使用静态定位

private void initView() {
        //更新地图
        //设置初始化比例  500米左右   zoom越大则地图越详细
       LatLng latLng = new LatLng(30.272858,120.15941);
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(latLng)
                .zoom(16)
                .build();
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);        //改变地图状态
        mBaiduMap.setMapStatus(mMapStatusUpdate);

    }

二、定位以及长按地图获取地理信息

1、Activity中代码

public class MainActivity extends BaseActivity {
    ActivityMainBinding binding;
    private Context context;
    private BaiduMap mBaiduMap;

    //定位相关
    private LocationClient mLocationClient;
    private MyLocationListener mLocationListener = new MyLocationListener();
    private Boolean isFirstIn = true;
    private double latitude;
    private double longtitude;
    //定位图标
    private BitmapDescriptor mIconLocation;
    private MyOrientationListener myOrientationListener;
    private float mCurrentX;
    private LatLng mDestLocationData;
    private LatLng mLastLocationData;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        mLocationListener = new MyLocationListener();
        context = this;

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        geoCoder = GeoCoder.newInstance();
        mBaiduMap = binding.bmapView.getMap();
        initView();
        //在定位之前进行一次动态的获取权限
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        requestRunPermissions();
//        }
        initLocation();
    }



    private void initListener() {
        binding.typeNone.setOnClickListener(this);
        binding.typeNoraml.setOnClickListener(this);
//        binding.typeSatellite.setOnClickListener(this);
        binding.typeTraffic.setOnClickListener(this);
        binding.location.setOnClickListener(this);
        binding.overlay.setOnClickListener(this);
      
    }


    private void requestRunPermissions() {
        List<PermissionItem> permisson = new ArrayList<>();
        permisson.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, "电话状态", R.drawable.permission_ic_phone));
        permisson.add(new PermissionItem(Manifest.permission.ACCESS_COARSE_LOCATION, "地理位置", R.drawable.permission_ic_location));
        permisson.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "地理位置", R.drawable.permission_ic_location));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            permisson.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "读取权限", R.drawable.permission_ic_storage));
            permisson.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "写入权限", R.drawable.permission_ic_storage));
        }
        HiPermission.create(this)
                .title("开启地图权限")
                .permissions(permisson)
                .filterColor(ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme()))
                .style(R.style.PermissionBlueStyle)
                .msg("我们需要获得以下权限才能为您提供服务")
                .checkMutiPermission(new PermissionCallback() {
                    @Override
                    public void onClose() {

                    }

                    @Override
                    public void onFinish() {
//                        showToastShort("所有权限申请完成");
                    }

                    @Override
                    public void onDeny(String permission, int position) {

                    }

                    @Override
                    public void onGuarantee(String permission, int position) {

                    }
                });
    }

    /**
     * 定位的方法
     */
    private void initLocation() {
//        binding.LocationResult.setMovementMethod(ScrollingMovementMethod.getInstance());
        myOrientationListener = new MyOrientationListener(this);
        mLocationClient = new LocationClient(this);
        mLocationClient.registerLocationListener(mLocationListener);
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//精确定位
        option.setCoorType("bd09ll");//可选,设置返回的定位结果坐标系
        option.setIsNeedAddress(true);//获取详细地址
        option.setOpenGps(true);//设置是否使用GPS
//        option.setScanSpan(1000);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤GPS仿真结果,默认需要
        mLocationClient.setLocOption(option);
        //定位后的图标 初始化图标
        mIconLocation = BitmapDescriptorFactory.fromResource(R.mipmap.navi_map_gps_locked);
//设置自定以图标
            MyLocationConfiguration configuration = new
                    MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, mIconLocation);
            mBaiduMap.setMyLocationConfiguration(configuration);
    }

    private void initView() {
        //更新地图
        //设置初始化比例  500米左右   zoom越大则地图越详细

 MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        mBaiduMap.setMapStatus(msu);

    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.type_noraml://普通地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                break;
//            case R.id.type_satellite://卫星模式
//                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//                break;
            case R.id.type_none:
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
                break;
            case R.id.type_traffic:
                if (mBaiduMap.isTrafficEnabled()) {
                    mBaiduMap.setTrafficEnabled(false);
                    binding.typeTraffic.setText("实时路况(开)");
                } else {
                    mBaiduMap.setTrafficEnabled(true);
                    binding.typeTraffic.setText("实时路况(关)");
                }
                break;

        }
    }

   
    /***
     * Stop location service
     */
    @Override
    protected void onStop() {
        super.onStop();
        //停止定位
        mBaiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();
    }

    @Override
    protected void onStart() {
        super.onStart();
        //开启定位
        mBaiduMap.setMyLocationEnabled(true);
        //判断的时候注意
        if (!mLocationClient.isStarted()) {
            mLocationClient.start();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        binding.bmapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        binding.bmapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        binding.bmapView.onDestroy();
        
    }

   
    /**
     * 定位结果回调,重写onReceiveLocation方法,定位的回调  latitude 纬度
     */
    private class MyLocationListener extends BDAbstractLocationListener {
        if (location == null || binding.bmapView == null) {
                return;
            }
            MyLocationData data = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            mBaiduMap.setMyLocationData(data);

        @Override
        public void onReceiveLocation(BDLocation location) {
            
            if (isFirstIn) {
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
                mBaiduMap.animateMapStatus(msu);
                isFirstIn = false;
                Toast.makeText(context, "我的位置信息为::" + location.getDistrict(),
                        Toast.LENGTH_SHORT).show();
            }

           
        }
    }


}

2、点击按钮回到定位的地方

private double latitude;//纬度
private double longtitude;//经度


 /**
     * 获取当前的定位方法
     */
    private void getMyLocation() {
        LatLng latLng = new LatLng(latitude, longtitude);
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.animateMapStatus(msu);
    }




/**
     * 定位结果回调,重写onReceiveLocation方法,定位的回调  latitude 纬度
     */
    private class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null || binding.bmapView == null) {
                return;
            }
            MyLocationData data = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .direction(mCurrentX)//方向传感器
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            mBaiduMap.setMyLocationData(data);

            latitude = location.getLatitude();
            longtitude = location.getLongitude();
            if (isFirstIn) {
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
                mBaiduMap.animateMapStatus(msu);
                isFirstIn = false;
//                Toast.makeText(context, "我的位置信息为::" + poiList.get(0).getName(),
//                        Toast.LENGTH_SHORT).show();
                Toast.makeText(context, "我的位置信息为::" + location.getDistrict(),
                        Toast.LENGTH_SHORT).show();
            }


        }
    }

3、长按定位显示信息

 /**
         * 长按定位图标
         */
        mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
//                MapStatus maps = new MapStatus.Builder().target(latLng).zoom(15).build();
//                MapStatusUpdate m = MapStatusUpdateFactory.newMapStatus(maps);
                //改变地图状态
//                mBaiduMap.setMapStatus(m);


//                showToastShort("设置目的地成功");
//                showToastShort("设置目的地成功"+latLng.toString());
//                mDestLocationData = latLng;
                latlngToAddress(latLng);
                addDestInfoOverLay(latLng);
            }
        });



 /**
     * 经纬度或地址相互转换
     *
     * @param latlng
     */
    private void latlngToAddress(LatLng latlng) {

        // 设置反地理经纬度坐标,请求位置时,需要一个经纬度
//        geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latlng));

        //设置地址或经纬度反编译后的监听,这里有两个回调方法,
        geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            //经纬度转换成地址
            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
                if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                    Toast.makeText(MainActivity.this, "找不到该地址!", Toast.LENGTH_SHORT).show();
                }
//                tv_address.setText("地址:" + result.getAddress());
                assert result != null;
                showToastShort("地址:" + result.getAddress());
            }

            //把地址转换成经纬度
            @Override
            public void onGetGeoCodeResult(GeoCodeResult result) {
                // 详细地址转换在经纬度
                String address = result.getAddress();
            }
        });

        // 设置反地理经纬度坐标,请求位置时,需要一个经纬度
        //切记一定要放在下面不然第一次长按定位不走该方法
        geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latlng));
    }



 /**
     * 长按添加覆盖物
     *
     * @param latLng
     */
    private void addDestInfoOverLay(LatLng latLng) {
        //清除所有的覆盖物
        mBaiduMap.clear();
        OverlayOptions options = new MarkerOptions().position(latLng)
                .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_myloc))
                .zIndex(5);//层数
        mBaiduMap.addOverlay(options);

    }

猜你喜欢

转载自blog.csdn.net/Hunter2916/article/details/82867205