第一行代码第二版(郭霖著)笔记之第十一章(百度地图)
来源:互联网 发布:php 打印数组内容 编辑:程序博客网 时间:2024/05/22 02:23
1. 基于位置的服务简介
- GPS定位:基于手机内置的GPS硬件直接和卫星交互来后去当前的经纬度信息,这种定格为i方式精确度非常高,但缺点是只能在室外使用,室内基本无法接收到卫星的信号。
- 网络定位:根据手机当前网络附近的三个基站进行测速,以此计算出手机和每个基站之间的距离,在通过三角定位确定出一个大概的位置,这种定位方式精确度一般,但优点是在室内室外都可以使用。
- 在国内Google的网路服务不可用,所以网络定位的API失效。为了在室内和室外都可以成功定位,这里采用百度SDK来进行开发操作。
2. 获取发布版SHA1:
- 在cmd中输入命令,然后输入密码即可:
keytool -list -v -keystore <签名文件路径>
3. 确定自己位置的经纬度
- 布局:
<TextView android:id="@+id/position_text_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="经纬度是多少" android:textSize="25dp" android:visibility="gone" />
- 配置文件:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fkq.baidumaps"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <uses-permission android:name="android.permission.ACCESS_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"></uses-permission> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission> <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="6bnAKCzjTlK27e4Wl5UBQRqQGslWoV34"></meta-data> <activity android:name=".MainActivity"> <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. 添加了meta-data标签,注明APIKEY.3. 注册一个LBS SDK的服务。
- MainActivity:
public class MainActivity extends AppCompatActivity { public LocationClient mLocationClient; private TextView positionText; private StringBuilder currentPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); setContentView(R.layout.activity_main); positionText = (TextView) findViewById(R.id.position_text_view); List<String> permissionList = new ArrayList<>(); if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.READ_PHONE_STATE); } if (ContextCompat.checkSelfPermission(MainActivity.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(MainActivity.this, permissions, 1); } else { requestLocation(); } } private void requestLocation() { initLocation(); mLocationClient.start(); } private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setScanSpan(5000); mLocationClient.setLocOption(option); } @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, "必须同意所有权限才能使用本程序", Toast.LENGTH_SHORT).show(); finish(); return; } } requestLocation(); } else { Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show(); finish(); } break; default: } } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { currentPosition = new StringBuilder(); currentPosition.append("纬度:").append(location.getLatitude()).append("\n"); currentPosition.append("经度:").append(location.getLongitude()).append("\n"); currentPosition.append("定位方式:"); if (location.getLocType() == BDLocation.TypeGpsLocation) { currentPosition.append("GPS"); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { currentPosition.append("网络"); } runOnUiThread(new Runnable() { @Override public void run() { positionText.setText(currentPosition); } }); } @Override public void onConnectHotSpotMessage(String s, int i) { } } @Override protected void onDestroy() { super.onDestroy(); mLocationClient.stop(); }}说明:1. onCreate方法中创建LocationClient实例,接收一个全局的上下文参数。接着实例会注册一个监听器,当获取位置信息的时候,回调这个定位监听器。2. 运行时权限采用集合的方式,如果没有授权便添加权限到集合中,然后将List转化为数组,再调用ActivityCompat.requestPermissions方法一次性申请。onRequestPermissionsResult方法循环每个权限,如果有一个权限被拒绝,直接调用finish方法关闭当前程序,只有所有的权限被用户同意,才会调用requestLocation方法进行地理位置的定位。3. mLocationClient.start()方法进行定位,回调监听器:BDLocation.getLatitude获取位置的纬度,getLongitude获取位置的经度,getLocType获取定位方式。4. 默认情况下定位mLocationClient.start()方法只会执行一次。增加 initLocation()方法,在方法中创建LocationClientOption对象,然后调用它的setScanSpan方法设置更新的间隔,传入5000,表示5秒钟会更新一下当前的位置,意味着监听器跟随5秒设置页面的经纬度。5.活动被销毁的时候调用mLocationClient.stop()方法停止定位。
4. 选择定位模式
- 手机定位三种模式:高精度定位、节电、仅限设备。高精度定位允许使用GPS、无线网络、蓝牙或移动网络进行定位,节电模式表示仅使用网络定位,仅限设备模式表示仅使用GPS定位。不用担心开启了GPS定位,耗费电量,因为只有定位的时候才会消耗电量。
- initLocation方法(百度LBS)中对定位模式进行了指定:Hight_Accuracy、Battery_Saving和Device_Sensors。分别对应手机定位的三种模式。
- 我们这里设定为高精度模式(第一行代码为设备模式):
private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); mLocationClient.setLocOption(option);}说明:不管是在屋里还是屋外都可以对位置进行定位。
5. 显示看得懂的定位信息
- 在initLocation()方法添加如下代码:
option.setIsNeedAddress(true);说明:表示我们需要获取详细的地理信息
- 在onReceiveLocation方法中获取省市区街道等信息
currentPosition.append("国家:").append(location.getCountry()).append("\n");currentPosition.append("省:").append(location.getProvince()).append("\n");currentPosition.append("市:").append(location.getCity()).append("\n");currentPosition.append("区:").append(location.getDistrict()).append("\n");currentPosition.append("街道:").append(location.getStreet()).append("\n");注意:如果定位方式指定为设备,但是获取具体信息这一功能,还是会自动开启网络定位。
6. 显示百度地图
- 布局:
<com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" />说明: 自定义的MapView控件,用来显示地图。
- MainActivity添加代码:
onCreate方法中:SDKInitializer.initialize(getApplicationContext());setContentView(R.layout.activity_main);mapView = (MapView) findViewById(R.id.bmapView); @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mLocationClient.stop(); mapView.onDestroy(); }说明:1. SDKInitializer调用initialize方法,传入全局的上下文进行初始化操作,地图就会显示出来了,一句代码!2. 通过findViewById方法获取到了MapView实例。3. 在onResume、onPause和onDestroy方法中对MapView生命周期进行管理,以免浪费资源。
7. 移动到我的位置
- 获取地图的总控制器BaiduMap类的实例。
BadiuMap baiduMap = mapView.getMap();说明:有了BiaduMap类的实例,就可以对地图进行各种各样的操作,比如设置地图的缩放级别以及将地图移动到某一个经纬度上。
- 百度地图可以将缩放级别的取值范围定在3到19之间,值越大,地图越精细。
MapStatusUpdate update = MapStatusUpdateFactory.zoomTo(16f);baiduMap.animateMapStatus(update);
- 借助LatLng类实现地图移动到某一个经纬度上
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);baiduMap.animateMapStatus(update);
8. 让“我”显示在地图上
- 取消百度地图让”我”显示在地图上的限制
baiduMap.setMyLocationEnabled(true);
- 借助MyLocationData.Builder类封装经纬度信息
MyLocationData.Builder locationBuilder = new MyLocationData.Builder(); locationBuilder.latitude(location.getLatitude()); locationBuilder.longitude(location.getLongitude());
- 借助MyLocationData.Builder类的build方法,让设备的位置显示在地图上
MyLocationData locationdata = locationBuilder.build(); baiduMap.setMyLocationData(locationdata);
- 程序退出的时候,关闭我的位置显示功能
baiduMap.setMyLocationEnabled(false);
9. 附上MainActivity的代码
public class MainActivity extends AppCompatActivity { public LocationClient mLocationClient; private TextView positionText; private StringBuilder currentPosition; private MapView mapView; private BaiduMap baiduMap; private boolean isFirstLocate = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); positionText = (TextView) findViewById(R.id.position_text_view); mapView = (MapView) findViewById(R.id.bmapView); baiduMap = mapView.getMap(); baiduMap.setMyLocationEnabled(true); List<String> permissionList = new ArrayList<>(); if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); } if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.READ_PHONE_STATE); } if (ContextCompat.checkSelfPermission(MainActivity.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(MainActivity.this, permissions, 1); } else { requestLocation(); } } private void requestLocation() { initLocation(); mLocationClient.start(); } private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); option.setScanSpan(5000); option.setIsNeedAddress(true); mLocationClient.setLocOption(option); } @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, "必须同意所有权限才能使用本程序", Toast.LENGTH_SHORT).show(); finish(); return; } } requestLocation(); } else { Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show(); finish(); } break; default: } } private void navigateTo(BDLocation location) { if (isFirstLocate) { LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); baiduMap.animateMapStatus(update); update = MapStatusUpdateFactory.zoomTo(16f); baiduMap.animateMapStatus(update); isFirstLocate = false; } MyLocationData.Builder locationBuilder = new MyLocationData.Builder(); locationBuilder.latitude(location.getLatitude()); locationBuilder.longitude(location.getLongitude()); MyLocationData locationdata = locationBuilder.build(); baiduMap.setMyLocationData(locationdata); } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location.getLocType() == BDLocation.TypeGpsLocation || location.getLocType() == BDLocation.TypeNetWorkLocation) { navigateTo(location); } currentPosition = new StringBuilder(); currentPosition.append("纬度:").append(location.getLatitude()).append("\n"); currentPosition.append("经度:").append(location.getLongitude()).append("\n"); currentPosition.append("国家:").append(location.getCountry()).append("\n"); currentPosition.append("省:").append(location.getProvince()).append("\n"); currentPosition.append("市:").append(location.getCity()).append("\n"); currentPosition.append("区:").append(location.getDistrict()).append("\n"); currentPosition.append("街道:").append(location.getStreet()).append("\n"); currentPosition.append("定位方式:"); if (location.getLocType() == BDLocation.TypeGpsLocation) { currentPosition.append("GPS"); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { currentPosition.append("网络"); } runOnUiThread(new Runnable() { @Override public void run() { positionText.setText(currentPosition); } }); } @Override public void onConnectHotSpotMessage(String s, int i) { } } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mLocationClient.stop(); mapView.onDestroy(); baiduMap.setMyLocationEnabled(false); }}
阅读全文
1 0
- 第一行代码第二版(郭霖著)笔记之第十一章(百度地图)
- 第一行代码第二版(郭霖著)笔记之第二章(探究活动)
- 第一行代码第二版(郭霖著)笔记之第五章(详解广播机制)
- 第一行代码第二版(郭霖著)笔记之第三章(UI开发的点点滴滴)
- 第一行代码第二版(郭霖著)笔记之第六章(详解持久化技术)
- 第一行代码第二版(郭霖著)笔记之第十二章(Material Design 实战)
- 第一行代码第二版(郭霖著)笔记之第一章(你的第一行Android代码)
- 第一行代码(第二版)读书笔记
- 第一行代码笔记,第十一章------位置的探究
- 第一行代码学习笔记 第二章
- 《第一行代码》第一章、第二章笔记
- 第一行代码 之 第二篇代码笔记
- 第一行代码第二版 使用百度定位
- 第一行代码+Android+第2版 笔记第二天
- 《第一行代码(第二版)》的学习(一)
- 《第一行代码(第二版)》学习(二)
- 跟着第一行代码学安卓(第二版书)-1
- 《第一行代码》读书笔记(第一章,第二章)
- 如何设置滚动条样式?
- webStorm的常用快捷键
- Oracle的substr函数简单用法
- 可视化证明神经网络可以计算任何函数
- C语言qsort函数如何使用
- 第一行代码第二版(郭霖著)笔记之第十一章(百度地图)
- 流程python学习笔记:第二章(1)
- 关于MAVEN项目包冲突问题
- 设置MySQL数据库权限及用户密码
- 用jspSmartUpload组件实现文件上传、下载
- etcdv3的操作脚本
- ListView扩展实现XListView、ZListView
- Express中use挂载中间件的方法
- 万丈高楼平地起,勿在浮沙筑高台--论程序员基础知识的重要性