《第一行代码》笔记(18)——百度地图简单使用

package com.zjw.mylocationbasedservices;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

//11.1 p379 基于位置的服务简介
/*
LBS:基于位置的服务。
主要原理:
一:GPS
    基于手机内置GPS硬件直接和卫星交互来获取当前的经纬度信息
    优点:精确度高
    缺点:适合室外使用,室内基本无法接收卫星信号
二:网络定位
    根据手机当前网络附近的三个基站进行测速,
    以此计算出手机和每个基站之间的距离,
    再通过三角定位确定出一个大概的位置
    优点:室内室外都可用
    缺点:精确度一般
 */

//11.2 p380 申请API Key
/*
申请API Key:
1.注册一个百度账号
2.申请成为百度开发者,登陆百度账号后访问http://developer.baidu.com/user/reg
3.访问http://lbsyun.baidu.com/apiconsole/key创建应用,提交信息后获取AK(API Key)
    应用名随意
    类型选Android SDK
    启用服务默认
    发布版SHA1,开发版SHA1:打包程序时所用签名文件的SHA1指纹
        Android Studio查看方式:点击右侧工具栏的Gradle->项目名->module名->Tasks->android->
                              signingReport可查看签名文件信息(双击后如果是列表一样的,最近的左上图标切换)
        cmd查看方式:keytool -list -v -keystore <签名文件路径>
                   比如默认签名:
                   cmd进入debug.keystore 默认目录:C:\Documents and Settings\Administrator\.androi
                   输入keytool -list -v -keystore debug.keystore,然后再输入密钥库口令,这里默认是android
 */

//11.3 p384 使用百度定位
//11.3.1 p384 准备LBS SDK
/*
下载SDK地址:http://lbsyun.baidu.com/sdk/download
根据需要下载,这里用到定位,基础地图
我官网下载的一直解压错误,重下n次也没用,如果有相同情况,可去CSDN下载
测试可用下载地址:http://download.csdn.net/download/mr_wzc/9882687
 */
/*
下载下来的文件分为jar包和so文件
jar包:Java层使用
so文件:Native层使用,用c/c++语言编写,NDK编译,百度已经做好封装
libs目录:存放jar包
新建jniLibs目录(与res同级):存放so文件
 */
/*
我么直接复制jar包,没有修改gradle文件,必须手动同步,不然无法引用到Jar包中提供的接口
 */

//11.3.2 p386 确定自己位置的经纬度
//布局:TextView,用于显示当前位置信息
/*
改清单文件:申请权限,AK(写你自己申请到的那个),注册服务(百度SDK中代码都是混淆过的),配置不能错,不然……已亲身试验
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.zjw.mylocationbasedservices">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="BfIcM8iPqSbinkr3henQD2vMchHmohnG"/>

        <activity android:name=".UseBaiduLocation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote"></service>
    </application>
</manifest>
 */
/*
主类:
1.布局
2.获取LocationClient对象
3.注册监听器
4.申请权限,权限回调
5.开始定位,回调监听里获取经纬度,定位方式
 */
/*
mLocationClient.start();方法只会定位一次
如果正在高速移动中,实时更新位置
改主类代码
注意:最后必须stop()定位,不然程序会在后台不停定位,消耗电量
 */

//11.3.3 p391 选择定位模式
/*
手动手机上开GPS后
代码里指定定位模式locationClientOption.setLocationMode()
三种模式:
LocationClientOption.LocationMode.Hight_Accuracy  优先GPS,然后网络定位
LocationClientOption.LocationMode.Battery_Saving  省电模式,网络定位
LocationClientOption.LocationMode.Device_Sensors  GPS
 */

//11.3.4 p392 看得懂的位置信息
/*
 locationClientOption.setIsNeedAddress(true);设置是否需要地址信息,默认为无地址
 到监听器里获取国家省市区镇等信息
 */

//11.4 p395 使用百度地图
//11.4.1 p395 让地图显示出来
/*
改布局
把之前的TextView设为不可见
android:visibility="gone"
加上
    <com.baidu.mapapi.map.MapView
        android:id="@+id/mv_baidu_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.baidu.mapapi.map.MapView>
 */
/*
主类里面:
初始化: SDKInitializer.initialize(getApplicationContext());//初始化
注意:初始化 BaiduMap SDK要在显示界面setContentView()之前
重写: @Override
    protected void onResume() {
        super.onResume();
        mMvBaiduMap.onResume();
    }

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();//停止定位
        mMvBaiduMap.onDestroy();
    }
    此时运行出来地图显示北京市中心
 */

//11.4.2 p397 移动到我的位置
/*
1.获取BaiduMap实例
BaiduMap baiduMap= mMvBaiduMap.getMap();
2.有了BaiduMap实例后可对地图进行各种操作
    1.设置地图缩放比例
        百度地图将缩放级别取指范围限定在3-19之间,小数也可,值越大,地图越精细
        MapStatusUpdate update=MapStatusUpdateFactory.zoomTo(12.5f);
        mBaiduMap.animateMapStatus(update);
    2.让地图移动到某一个经纬度
        借助LatLng类(主要用于存放经纬度值)
        构造函数参数传入两个参数:一:纬度,二:经度
        调用MapStatusUpdateFactory.的newLatLng()方法
        LatLng ll=new LatLng(29.915,116.404);
        MapStatusUpdate update=MapStatusUpdateFactory.newLatLng(ll);
        mBaiduMap.animateMapStatus(update);
3.这里主要是下面代码navigateTo()方法
 */

//11.4.3 p400 让"我"显示在地图上
/*
 MyLocationData.Builder类,用来封装设备当前所在的位置
 将经纬度信息封装入这个类
 MyLocationData.Builder locationBuilder=new MyLocationData.Builder();
 locationBuilder.latitude(39.915);
 locationBuilder.longitude(116.404);
 封装完后调用build(),然后设置给地图
 MyLocationData myLocationData=locationBuilder.build();
 mBaiduMap.setMyLocationData(myLocationData);
 */

/*
可参考网络资料:
    http://www.cnblogs.com/act262/p/3812840.html,别人的博客,可能需要更全SDK下载
    http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/getloc百度官方文档
 */
public class UseBaiduLocation extends AppCompatActivity {

    @BindView(R.id.tv_position)
    TextView mTvPosition;
    @BindView(R.id.mv_baidu_map)
    MapView mMvBaiduMap;

    private LocationClient mLocationClient;
    private BaiduMap mBaiduMap;
    private boolean isFirstLocate=true;

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

        mLocationClient = new LocationClient(getApplicationContext());//LocationClient对象
        mLocationClient.registerLocationListener(new MyLocationListener());//注册监听器

        SDKInitializer.initialize(getApplicationContext());//初始化

        setContentView(R.layout.activity_use_baidu_location);
        ButterKnife.bind(this);

        requestAllPermissions();//请求运行时权限

        //获取BaiduMap实例
        mBaiduMap = mMvBaiduMap.getMap();
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
    }



    //开始定位,定位结果会回调到监听器中
    private void requestLocation() {
        //只定位一次
//        mLocationClient.start();

        //实时更新位置
        initLocation();
        mLocationClient.start();
    }

    //实时更新位置,以及其他一些定位参数控制
    private void initLocation() {
        LocationClientOption locationClientOption = new LocationClientOption();
        locationClientOption.setScanSpan(3 * 1000);//设置更新时间
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//设置模式
        locationClientOption.setOpenGps(true); // 打开GPS
        locationClientOption.setTimeOut(10 * 1000); // 超时
        locationClientOption.setIsNeedAddress(true);//设置是否需要地址信息,默认为无地址
        mLocationClient.setLocOption(locationClientOption);
    }



    //获取位置信息后回调的监听器
    //获取经纬度,定位方式
    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            StringBuilder currentPositonSB = new StringBuilder();
            currentPositonSB.append("纬度:").append(bdLocation.getLatitude()).append("\n");
            currentPositonSB.append("经度:").append(bdLocation.getLongitude()).append("\n");
            currentPositonSB.append("国家:").append(bdLocation.getCountry()).append("\n");
            currentPositonSB.append("省:").append(bdLocation.getProvince()).append("\n");
            currentPositonSB.append("市:").append(bdLocation.getCity()).append("\n");
            currentPositonSB.append("区:").append(bdLocation.getDistrict()).append("\n");
            currentPositonSB.append("街道:").append(bdLocation.getStreet()).append("\n");
            currentPositonSB.append("定位方式:");
            if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {
                currentPositonSB.append("GPS定位");
            } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {
                currentPositonSB.append("网络定位");
            } else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {
                currentPositonSB.append("离线定位");
            } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {
                currentPositonSB.append("网络连接失败,一般由于手机无有效网络连接导致,请检查手机是否能够正常上网");
            } else {
                currentPositonSB.append("其他:" + bdLocation.getLocType());
            }
            mTvPosition.setText(currentPositonSB);

            //11.4.2 p397 移动到我的位置
            if(bdLocation.getLocType() == BDLocation.TypeGpsLocation||bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){
                navigateTo(bdLocation);
            }

        }
    }

    //11.4.2 p397 移动到我的位置
    private void navigateTo(BDLocation bdLocation) {
        if(isFirstLocate){
            LatLng ll=new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
            MapStatusUpdate update= MapStatusUpdateFactory.newLatLng(ll);
            mBaiduMap.animateMapStatus(update);
            update=MapStatusUpdateFactory.zoomTo(17f);
            mBaiduMap.animateMapStatus(update);
            isFirstLocate=false;
        }
        //11.4.3 p400 让"我"显示在地图上
        MyLocationData.Builder locationBuilder=new MyLocationData.Builder();
        locationBuilder.latitude(bdLocation.getLatitude());
        locationBuilder.longitude(bdLocation.getLongitude());
        MyLocationData myLocationData=locationBuilder.build();
        mBaiduMap.setMyLocationData(myLocationData);
    }

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

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();//停止定位
        mMvBaiduMap.onDestroy();
        mBaiduMap.setMyLocationEnabled(false);
    }

    //请求运行时权限
    private void requestAllPermissions() {
        //权限列表
        List<String> permissionList = new ArrayList<>();
        //运行时权限
        //如果用户之前没有允许权限进行的操作,添加到列表中
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        //如果权限列表不为空,就一起申请权限
        if (!permissionList.isEmpty()) {
            String[] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(this, permissions, 1);
        } else {
            //如果用户之前已经允许权限后进行的操作
            requestLocation(); //开始定位,定位结果会回调到监听器中
        }
    }
    //申请权限回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    for (int result : grantResults) {
                        if (result != PackageManager.PERMISSION_GRANTED) {
                            //如果用户拒绝请求进行的操作
                            Toast.makeText(this, "You denid the permission,the program will be close", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation(); //开始定位,定位结果会回调到监听器中
                } else {
                    Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
                break;
        }
    }
}

转载于:https://my.oschina.net/u/3620480/blog/1492151

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值