基于位置的服务 LBS ,最开始移动设备设备功能有限,之前就是定位成功也不干其他事情。比如天气预报程序可以根据用户所在位置自动选择城市,发微博可以显示自己所在城市。。 首先是先确定用户所在位置:
方法一: GPS定位,基于手机内置的GPS 硬件直接和卫星交互来获取当前经纬度信息,精度高但是一般在室外使用,室内无法收到卫星信号;
方法二: 网络定位 ,根据手机当前网络福建的三个基站进行测速,以此来计算,精度 不太高,室内外都行;
第三方SDK: 百度,高德
进入网址:http://lbsyun.baidu.com/apiconsole/key
http://lbsyun.baidu.com/apiconsole/key/create
在百度官方上,有个发布SHA1 还有个开发SHA1
在右边工具栏 Gradle ——应用名—— :app ——Android ——signingReport 用这个半天都不出来,所以换一个:
mac 系统: 在终端下,进入.android 目录下,然后执行keytool -list -v -keystore debug.keystore 跳过密码输入,因为这个不需要密码
然后在http://lbsyun.baidu.com/sdk/download 选择要用的,下载下来解压,然后把jar 拷到libs 目录,然后把其他几个新建个jniLibs 然后同步一下 如果不行,就在build。gradle中加个空格,
第一步:配置清单文件
这样就把SDK 准备好了
还要增加
还要在application 下 :
第二步:代码编写
初始化:
locationClient = new LocationClient(getApplicationContext());
locationClient.registerLocationListener(new MyLocationListener());
动态添加权限:
List list = new ArrayList<>();
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.READ_PHONE_STATE);
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
list.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!list.isEmpty()) {
String[] permissons = list.toArray(new String[list.size()]);
ActivityCompat.requestPermissions(MainActivity.this, permissons, 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 per: grantResults){
if(per!= PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this,"必要的权限还是给我啊!",Toast.LENGTH_LONG).show();
finish();
return;
}
}
requestLocation();
}else {
Toast.makeText(MainActivity.this,"出现未知错误!",Toast.LENGTH_LONG).show();
finish();
}
break;
default:
break;
}
}
在RequestLocation方法中调用:locationClient.start();
class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("经度: ").append(bdLocation.getLatitude()).append("\n").append("维度 : ").append(bdLocation.getLongitude()).append("\n")
.append("定位方式: ");
if(bdLocation.getLocType() ==BDLocation.TypeGpsLocation){
stringBuilder.append("GPS ");
}else if(bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){
stringBuilder.append("网络");
}
stringBuilder.append(bdLocation.getCountry()).append(bdLocation.getProvince()).append(bdLocation.getCity()).append(bdLocation.getDistrict()).append(bdLocation.getStreet());
runOnUiThread(new Runnable() {
@Override
public void run() {
position.setText(stringBuilder);
}
});
}
@Override
public void onConnectHotSpotMessage(String s, int i) {
}
}
这样返回的街道名还是null 还要增加初始化initlocation方法,该方法中增加了移动获取功能:
LocationClientOption locationClientOption = new LocationClientOption();
locationClientOption.setScanSpan(5000);
locationClientOption.setIsNeedAddress(true);//获取当前位置的详细信息
locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//设置定位模式
locationClient.setLocOption(locationClientOption);
整个MainActivity 的代码如下:
package com.example.lbstest;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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;
public class MainActivity extends AppCompatActivity {
public LocationClient mLocationClient;
private TextView positionText;
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);
mapView = (MapView) findViewById(R.id.bmapView);
baiduMap = mapView.getMap();
baiduMap.setMyLocationEnabled(true);
positionText = (TextView) findViewById(R.id.position_text_view);
List 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 navigateTo(BDLocation location) {
if (isFirstLocate) {
Toast.makeText(this, "nav to " + location.getAddrStr(), Toast.LENGTH_SHORT).show();
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);
}
private void requestLocation() {
initLocation();
mLocationClient.start();
}
private void initLocation(){
LocationClientOption option = new LocationClientOption();
option.setScanSpan(5000);
option.setIsNeedAddress(true);
mLocationClient.setLocOption(option);
}
@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);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, 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) {
// StringBuilder 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("网络");
// }
// positionText.setText(currentPosition);
if (location.getLocType() == BDLocation.TypeGpsLocation
|| location.getLocType() == BDLocation.TypeNetWorkLocation) {
navigateTo(location);
}
}
}
}
启动更精确的GPS需要用户去启动, 只有定位功能真正开始操作了才会影响到手机的电量;
#下面让地图显示出来
// 初始化
locationClient = new LocationClient(getApplicationContext());
locationClient.registerLocationListener(new MyLocationListener());
SDKInitializer.initialize(getApplicationContext());
//必须放这之前,不然会报错
setContentView(R.layout.activity_main);
首先布局文件中增加全包名的MapView,然后在setContentView前面加上SDKInitializer.initialize(getApplicationContext()); 还有就是之前遇到获取当前城市失败问题也是初始化问题;为了节约资源,在获得焦点失去焦点及销毁方法中都加上对应的方法。到目前为止,地图显示出来了,但是是北京的!
百度地图提供了一个管理类: BaiduMap map = mp.getMap();
现在让地图移动到我的位置,做一个全局的变量定义是不是第一次: boolean fisrtLocation =true;然后添加方法:
private void navigateTo(BDLocation bdLocation) {
if (fisrtLocation) {
LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng);
map.animateMapStatus(mapStatusUpdate);
mapStatusUpdate = MapStatusUpdateFactory.zoomTo(16f);
map.animateMapStatus(mapStatusUpdate);
fisrtLocation = false;
}
}
并且 在 MyLocationListener方法中加上:
if (location.getLocType() == BDLocation.TypeGpsLocation
|| location.getLocType() == BDLocation.TypeNetWorkLocation) {
navigateTo(location);
}
这样确实地图显示在我们附近了,但是没有显示我的位置在地图上那个具体的位置
让我自己显示在地图上
1.在管理类后面调用 map.setMyLocationEnable(true);
2.在移动到我位置方法中增加:
MyLocationData.Builder locationBuilder = new MyLocationData.
Builder();
locationBuilder.latitude(location.getLatitude());
locationBuilder.longitude(location.getLongitude());
MyLocationData locationData = locationBuilder.build();
map.setMyLocationData(locationData);
3.在Ondestory方法中map(false);
这样,我的位置就显示在地图上了;