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次也没用,如果有相同情况,可去优快云下载
测试可用下载地址:http://download.youkuaiyun.com/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
本文详细介绍了如何使用百度地图API实现位置服务,包括申请APIKey、使用百度定位、选择定位模式、显示地图及移动到指定位置。涵盖权限申请、定位参数控制、地图显示与操作、位置信息解析等内容。

被折叠的 条评论
为什么被折叠?



