序言
在很多项目中我们需要使用定位,但是每次都要去配置AndroidManifest.xml,添加很多权限,而且每次都要配置jni相关的目录,特别在需要定位的时候需要声明一个server,就是这个家伙,很多时候我都忘记配置,结果搞了半天。而且当我们项目集成了百度地图,ShareSDK等等第三方SDK的时候,我们都需要为它们单独配置混淆规则,基于以上原因,我觉得有必要把百度地位封装成library,今天试了一下成功了,记录一下吧。
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" />
效果
目录结构
注意事项
1在申请APPKey的时候使用的是app的包名
2.要运行demo请使用这个keystore,密码写在说明文件里了
清单文件
混淆文件
以后你就可以只管混淆自己的项目了,百度的混淆配置已经在library
定位工具
这是我写的一个定位工具
package com.zgh.locationlib;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
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;
/**
* 用于定位的工具类
* Created by zhuguohui on 2016/7/22.
*/
public class LocationUtil {
// 定位相关
static LocationClient mLocClient;
public static MyLocationListener myListener = new MyLocationListener();
private static BDLocation sLocation = null;
private static int MSG_CHECK_TIMEOUT = 1;
private static boolean haveInited=false;
public static boolean test=true;
private static Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
if(sLocation==null){
if(mLocationListener!=null){
mLocationListener.onGetLocationTimeOut();
}
}
if(mLocClient.isStarted()){
mLocClient.stop();
}
break;
}
}
};
public static void init(Context context) {
//百度地图初始化
SDKInitializer.initialize(context.getApplicationContext());
// 定位初始化
mLocClient = new LocationClient(context.getApplicationContext());
mLocClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
mLocClient.setLocOption(option);;
haveInited=true;
}
/**
* 定位SDK监听函数
*/
private static class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null) {
return;
}
sLocation = location;
if (mLocationListener != null) {
mLocationListener.onReceiveLocation(sLocation);
}
if (sNeedAutoClose) {
if (mLocClient.isStarted()) {
mLocClient.stop();
}
}
}
}
public static interface LocationListener {
//定位开始,可以显示加载动画
void onGetLocationStart();
//获取定位地址
void onReceiveLocation(BDLocation location);
//定位超时,可以显示重试按钮
void onGetLocationTimeOut();
}
//如果不想重写全部方法,可以继承这个类
public static class LocationListenrAdatper implements LocationListener{
@Override
public void onGetLocationStart() {
}
@Override
public void onReceiveLocation(BDLocation location) {
}
@Override
public void onGetLocationTimeOut() {
}
}
private static LocationListener mLocationListener = null;
private static boolean sNeedAutoClose=true;
/**
* 获取定位
*
* @param listener 回调
* @param timeOut 超时时间:单位毫秒,-1表示不限时间。
* @param forceUpdate 强制刷新
*/
public static void getLocation(LocationListener listener, long timeOut, boolean forceUpdate,boolean autoClose) {
if(!haveInited){
throw new RuntimeException("请先使用init()方法进行初始化");
}
if(forceUpdate||sLocation==null){
if (mLocationListener != null) {
mLocationListener.onGetLocationStart();
}
}
//不要求强制刷新的时候,使用已有的定位
if (!forceUpdate && sLocation != null) {
if (listener != null) {
listener.onReceiveLocation(sLocation);
}
}
//开始定位
sNeedAutoClose=autoClose;
sLocation=null;
mLocationListener = listener;
mLocClient.start();
if (timeOut != -1) {
mHandler.sendEmptyMessageDelayed(MSG_CHECK_TIMEOUT, timeOut);
}
}
/**
* 获取一次定位
* @param listener
*/
public static void getLocation(LocationListener listener,boolean forceUpdate){
getLocation(listener,-1,forceUpdate,true);
}
public static void stopLoacation(){
if(mLocClient!=null&&mLocClient.isStarted()){
mLocClient.stop();
}
}
}
使用方法,在Application中初始化
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
LocationUtil.init(this);
}
}
在需要定位的时候使用
package com.zgh.locationdemo;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.zgh.locationlib.LocationUtil;
public class MainActivity extends Activity implements LocationUtil.LocationListener {
MapView mMapView = null;
LinearLayout ll_load, ll_retry;
private BaiduMap mBaiduMap = null;
private boolean isFirstLoc = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
ll_load = (LinearLayout) findViewById(R.id.ll_load);
ll_retry = (LinearLayout) findViewById(R.id.ll_retry);
ll_retry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getLocation();
}
});
//打开测试,用于测试状态切换是否正常
LocationUtil.test=true;
getLocation();
}
int retryTimes=0;
private void getLocation() {
//重试两次,成功
retryTimes++;
if(retryTimes==2){
LocationUtil.test=false;
}
LocationUtil.getLocation(this, 3000, false, false);
}
@Override
protected void onDestroy() {
super.onDestroy();
LocationUtil.stopLoacation();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(false);
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
@Override
public void onGetLocationStart() {
hideAll();
ll_load.setVisibility(View.VISIBLE);
}
@Override
public void onReceiveLocation(BDLocation location) {
hideAll();
mMapView.setVisibility(View.VISIBLE);
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(15.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
@Override
public void onGetLocationTimeOut() {
hideAll();
ll_retry.setVisibility(View.VISIBLE);
}
private void hideAll() {
ll_retry.setVisibility(View.GONE);
ll_load.setVisibility(View.GONE);
mMapView.setVisibility(View.GONE);
}
}