411 lines
22 KiB
Java
411 lines
22 KiB
Java
package com.uiuios.aios.manager;
|
||
|
||
import android.annotation.SuppressLint;
|
||
import android.content.Context;
|
||
import android.provider.Settings;
|
||
import android.text.TextUtils;
|
||
import android.util.Log;
|
||
|
||
import com.baidu.location.BDAbstractLocationListener;
|
||
import com.baidu.location.BDLocation;
|
||
import com.baidu.location.LocationClient;
|
||
import com.baidu.location.LocationClientOption;
|
||
import com.blankj.utilcode.util.SPUtils;
|
||
import com.google.gson.Gson;
|
||
import com.google.gson.reflect.TypeToken;
|
||
import com.tencent.mmkv.MMKV;
|
||
import com.uiuios.aios.disklrucache.CacheHelper;
|
||
import com.uiuios.aios.utils.GsonUtils;
|
||
|
||
import java.lang.reflect.Type;
|
||
|
||
public class AmapManager {
|
||
private static final String TAG = AmapManager.class.getSimpleName();
|
||
@SuppressLint("StaticFieldLeak")
|
||
private static AmapManager sInstance;
|
||
private Context mContext;
|
||
@SuppressLint("StaticFieldLeak")
|
||
private LocationClient mLocationClient = null;
|
||
private LocationClientOption mOption;
|
||
private BDLocation mLocation;
|
||
private CacheHelper mCacheHelper;
|
||
|
||
private static final String AMAPLOCATION_JSON_KEY = "MAPLOCATION_JSON_STRING";
|
||
public static final String LONGITUDE_KEY = "map_longitude_key";
|
||
public static final String LATITUDE_KEY = "map_latitude_key";
|
||
public static final String ADDRESS_KEY = "map_address_key";
|
||
public static final String ERROR_KEY = "map_error_key";
|
||
|
||
private AmapManager(Context context) {
|
||
this.mContext = context;
|
||
this.mCacheHelper = new CacheHelper(context);
|
||
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+gps");
|
||
initAmap();
|
||
}
|
||
|
||
public static void init(Context context) {
|
||
if (context == null) {
|
||
throw new RuntimeException("Context is NULL");
|
||
}
|
||
if (sInstance == null) {
|
||
sInstance = new AmapManager(context);
|
||
}
|
||
}
|
||
|
||
public static AmapManager getInstance() {
|
||
if (sInstance == null) {
|
||
throw new IllegalStateException("You must be init AmapManager first");
|
||
}
|
||
return sInstance;
|
||
}
|
||
|
||
public void initAmap() {
|
||
if (mLocationClient == null) {
|
||
mLocationClient = new LocationClient(mContext);
|
||
}
|
||
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+gps");
|
||
mLocationClient.setLocOption(getDefaultLocationClientOption());
|
||
mLocationClient.registerLocationListener(mListener);
|
||
mLocationClient.stop();
|
||
mLocationClient.start();
|
||
}
|
||
|
||
|
||
public LocationClient getLocationClient() {
|
||
if (mLocationClient == null) {
|
||
initAmap();
|
||
}
|
||
return mLocationClient;
|
||
}
|
||
|
||
public BDLocation getNowMapLocation() {
|
||
if (mLocation == null) {
|
||
String aMapLocationjson = SPUtils.getInstance().getString(AMAPLOCATION_JSON_KEY,"");
|
||
if (TextUtils.isEmpty(aMapLocationjson)) {
|
||
return null;
|
||
}
|
||
Type type = new TypeToken<BDLocation>() {
|
||
}.getType();
|
||
try {
|
||
BDLocation bdLocation = new Gson().fromJson(aMapLocationjson, type);
|
||
return bdLocation;
|
||
} catch (Exception e) {
|
||
Log.e(TAG, "getNowMapLocation: " + e.getMessage());
|
||
return null;
|
||
}
|
||
}
|
||
return this.mLocation;
|
||
}
|
||
|
||
public String getLocation() {
|
||
BDLocation bdLocation = getNowMapLocation();
|
||
if (bdLocation == null) {
|
||
return "0,0";
|
||
} else {
|
||
String location = bdLocation.getLongitude() + "," + bdLocation.getLatitude();
|
||
Log.e(TAG, "getLocation: " + location);
|
||
return location;
|
||
}
|
||
}
|
||
|
||
|
||
/***
|
||
*
|
||
* @return DefaultLocationClientOption 默认O设置
|
||
*/
|
||
public LocationClientOption getDefaultLocationClientOption() {
|
||
if (mOption == null) {
|
||
mOption = new LocationClientOption();
|
||
mOption.setCoorType("bd09ll"); // 可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
|
||
mOption.setScanSpan(0); // 可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
|
||
mOption.setIsNeedAddress(true); // 可选,设置是否需要地址信息,默认不需要
|
||
mOption.setIsNeedLocationDescribe(true); // 可选,设置是否需要地址描述
|
||
mOption.setNeedDeviceDirect(false); // 可选,设置是否需要设备方向结果
|
||
mOption.setLocationNotify(false); // 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
|
||
mOption.setIgnoreKillProcess(true); // 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop
|
||
mOption.setIsNeedLocationDescribe(true); // 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation
|
||
mOption.setIsNeedLocationPoiList(true); // 可选,默认false,设置是否需要POI结果,可以在BDLocation
|
||
mOption.SetIgnoreCacheException(false); // 可选,默认false,设置是否收集CRASH信息,默认收集
|
||
mOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); // 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备,模糊
|
||
mOption.setIsNeedAltitude(false); // 可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
|
||
// 可选,设置首次定位时选择定位速度优先还是定位准确性优先,默认为速度优先
|
||
// mOption.setFirstLocType(LocationClientOption.FirstLocType.SPEED_IN_FIRST_LOC);
|
||
}
|
||
return mOption;
|
||
}
|
||
|
||
|
||
/*****
|
||
*
|
||
* 定位结果回调,重写onReceiveLocation方法,可以直接拷贝如下代码到自己工程中修改
|
||
*
|
||
*/
|
||
private BDAbstractLocationListener mListener = new BDAbstractLocationListener() {
|
||
|
||
/**
|
||
* 定位请求回调函数
|
||
* @param location 定位结果
|
||
*/
|
||
@Override
|
||
public void onReceiveLocation(BDLocation location) {
|
||
if (null != location) {
|
||
switch (location.getLocType()) {
|
||
case BDLocation.TypeGpsLocation:// GPS定位结果
|
||
case BDLocation.TypeNetWorkLocation:// 网络定位结果
|
||
case BDLocation.TypeOffLineLocation:// 离线定位结果
|
||
SPUtils.getInstance().put(AMAPLOCATION_JSON_KEY, GsonUtils.toJsonString(location));
|
||
Log.e(TAG, "onLocationChanged: " + "定位成功");
|
||
Log.e(TAG, "onLocationChanged: longitude = " + location.getLongitude());
|
||
Log.e(TAG, "onLocationChanged: latitude = " + location.getLatitude());
|
||
Log.e(TAG, "onLocationChanged: " + location.getAddrStr() + location.getLocationDescribe());
|
||
mCacheHelper.put(ADDRESS_KEY, location.getAddrStr() + location.getLocationDescribe());
|
||
mCacheHelper.put(LONGITUDE_KEY, location.getLongitude());
|
||
mCacheHelper.put(LATITUDE_KEY, location.getLatitude());
|
||
mCacheHelper.put(ERROR_KEY, "-");
|
||
break;
|
||
case BDLocation.TypeServerError:
|
||
Log.e(TAG, "onReceiveLocation: " + "服务端网络定位失败");
|
||
mCacheHelper.put(ERROR_KEY, "服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
|
||
break;
|
||
case BDLocation.TypeNetWorkException:
|
||
Log.e(TAG, "onReceiveLocation: " + "网络不同导致定位失败,请检查网络是否通畅");
|
||
mCacheHelper.put(ERROR_KEY, "网络不同导致定位失败,请检查网络是否通畅");
|
||
break;
|
||
case BDLocation.TypeCriteriaException:
|
||
Log.e(TAG, "onReceiveLocation: " + "无法获取有效定位依据导致定位失败");
|
||
mCacheHelper.put(ERROR_KEY, "无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
|
||
break;
|
||
default:
|
||
}
|
||
}
|
||
// if (null != location && location.getLocType() != BDLocation.TypeServerError) {
|
||
// StringBuffer sb = new StringBuffer(256);
|
||
// sb.append("time : ");
|
||
// /**
|
||
// * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来,每次回调的时间;
|
||
// * location.getTime() 是指服务端出本次结果的时间,如果位置不发生变化,则时间不变
|
||
// */
|
||
// sb.append(location.getTime());
|
||
// sb.append("\nsysTime : ");
|
||
// sb.append(SystemClock.elapsedRealtime());
|
||
// sb.append("\nlocType : ");// 定位类型
|
||
// sb.append(location.getLocType());
|
||
// sb.append("\nlocType description : ");// *****对应的定位类型说明*****
|
||
// sb.append(location.getLocTypeDescription());
|
||
// sb.append("\nlatitude : ");// 纬度
|
||
// sb.append(location.getLatitude());
|
||
// sb.append("\nlongtitude : ");// 经度
|
||
// sb.append(location.getLongitude());
|
||
// sb.append("\nradius : ");// 半径
|
||
// sb.append(location.getRadius());
|
||
// sb.append("\nCountryCode : ");// 国家码
|
||
// sb.append(location.getCountryCode());
|
||
// sb.append("\nProvince : ");// 获取省份
|
||
// sb.append(location.getProvince());
|
||
// sb.append("\nCountry : ");// 国家名称
|
||
// sb.append(location.getCountry());
|
||
// sb.append("\ncitycode : ");// 城市编码
|
||
// sb.append(location.getCityCode());
|
||
// sb.append("\ncity : ");// 城市
|
||
// sb.append(location.getCity());
|
||
// sb.append("\nDistrict : ");// 区
|
||
// sb.append(location.getDistrict());
|
||
// sb.append("\nTown : ");// 获取镇信息
|
||
// sb.append(location.getTown());
|
||
// sb.append("\nStreet : ");// 街道
|
||
// sb.append(location.getStreet());
|
||
// sb.append("\naddr : ");// 地址信息
|
||
// sb.append(location.getAddrStr());
|
||
// sb.append("\nStreetNumber : ");// 获取街道号码
|
||
// sb.append(location.getStreetNumber());
|
||
// sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
|
||
// sb.append(location.getUserIndoorState());
|
||
// sb.append("\nDirection(not all devices have value): ");
|
||
// sb.append(location.getDirection());// 方向
|
||
// sb.append("\nlocationdescribe: ");
|
||
// sb.append(location.getLocationDescribe());// 位置语义化信息
|
||
// sb.append("\nPoi: ");// POI信息
|
||
// if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
|
||
// for (int i = 0; i < location.getPoiList().size(); i++) {
|
||
// Poi poi = (Poi) location.getPoiList().get(i);
|
||
// sb.append("poiName:");
|
||
// sb.append(poi.getName() + ", ");
|
||
// sb.append("poiTag:");
|
||
// sb.append(poi.getTags() + "\n");
|
||
// }
|
||
// }
|
||
// if (location.getPoiRegion() != null) {
|
||
// sb.append("PoiRegion: ");// 返回定位位置相对poi的位置关系,仅在开发者设置需要POI信息时才会返回,在网络不通或无法获取时有可能返回null
|
||
// PoiRegion poiRegion = location.getPoiRegion();
|
||
// sb.append("DerectionDesc:"); // 获取POIREGION的位置关系,ex:"内"
|
||
// sb.append(poiRegion.getDerectionDesc() + "; ");
|
||
// sb.append("Name:"); // 获取POIREGION的名字字符串
|
||
// sb.append(poiRegion.getName() + "; ");
|
||
// sb.append("Tags:"); // 获取POIREGION的类型
|
||
// sb.append(poiRegion.getTags() + "; ");
|
||
// sb.append("\nSDK版本: ");
|
||
// }
|
||
//// int permission = checkPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION);
|
||
//// sb.append("\npermsission: " + permission);
|
||
//// sb.append(locationService.getSDKVersion()); // 获取SDK版本
|
||
// if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
|
||
// sb.append("\nspeed : ");
|
||
// sb.append(location.getSpeed());// 速度 单位:km/h
|
||
// sb.append("\nsatellite : ");
|
||
// sb.append(location.getSatelliteNumber());// 卫星数目
|
||
// sb.append("\nheight : ");
|
||
// sb.append(location.getAltitude());// 海拔高度 单位:米
|
||
// sb.append("\ngps status : ");
|
||
// sb.append(location.getGpsAccuracyStatus());// *****gps质量判断*****
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("gps定位成功");
|
||
// } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
|
||
// // 运营商信息
|
||
// if (location.hasAltitude()) {// *****如果有海拔高度*****
|
||
// sb.append("\nheight : ");
|
||
// sb.append(location.getAltitude());// 单位:米
|
||
// }
|
||
// sb.append("\noperationers : ");// 运营商信息
|
||
// sb.append(location.getOperators());
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("网络定位成功");
|
||
// } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("离线定位成功,离线定位结果也是有效的");
|
||
// } else if (location.getLocType() == BDLocation.TypeServerError) {
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
|
||
// } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("网络不同导致定位失败,请检查网络是否通畅");
|
||
// } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
|
||
// sb.append("\ndescribe : ");
|
||
// sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
|
||
// }
|
||
//// logMsg(sb.toString(), tag);
|
||
// Log.e(TAG, "onReceiveLocation: " + sb);
|
||
// }
|
||
Log.e(TAG, "AmapAddress: " + mCacheHelper.getAsString(ADDRESS_KEY));
|
||
Log.e(TAG, "AmapError: " + mCacheHelper.getAsString(ERROR_KEY));
|
||
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-network");
|
||
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-gps");
|
||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ASSISTED_GPS_ENABLED, 0);
|
||
}
|
||
|
||
@Override
|
||
public void onConnectHotSpotMessage(String s, int i) {
|
||
super.onConnectHotSpotMessage(s, i);
|
||
}
|
||
|
||
/**
|
||
* 回调定位诊断信息,开发者可以根据相关信息解决定位遇到的一些问题
|
||
* @param locType 当前定位类型
|
||
* @param diagnosticType 诊断类型(1~9)
|
||
* @param diagnosticMessage 具体的诊断信息释义
|
||
*/
|
||
@Override
|
||
public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
|
||
super.onLocDiagnosticMessage(locType, diagnosticType, diagnosticMessage);
|
||
// int tag = 2;
|
||
StringBuffer sb = new StringBuffer(256);
|
||
sb.append("诊断结果: ");
|
||
if (locType == BDLocation.TypeNetWorkLocation) {
|
||
if (diagnosticType == 1) {
|
||
sb.append("网络定位成功,没有开启GPS,建议打开GPS会更好");
|
||
sb.append("\n" + diagnosticMessage);
|
||
} else if (diagnosticType == 2) {
|
||
sb.append("网络定位成功,没有开启Wi-Fi,建议打开Wi-Fi会更好");
|
||
sb.append("\n" + diagnosticMessage);
|
||
}
|
||
} else if (locType == BDLocation.TypeOffLineLocationFail) {
|
||
if (diagnosticType == 3) {
|
||
sb.append("定位失败,请您检查您的网络状态");
|
||
sb.append("\n" + diagnosticMessage);
|
||
}
|
||
} else if (locType == BDLocation.TypeCriteriaException) {
|
||
if (diagnosticType == 4) {
|
||
sb.append("定位失败,无法获取任何有效定位依据");
|
||
sb.append("\n" + diagnosticMessage);
|
||
} else if (diagnosticType == 5) {
|
||
sb.append("定位失败,无法获取有效定位依据,请检查运营商网络或者Wi-Fi网络是否正常开启,尝试重新请求定位");
|
||
sb.append(diagnosticMessage);
|
||
} else if (diagnosticType == 6) {
|
||
sb.append("定位失败,无法获取有效定位依据,请尝试插入一张sim卡或打开Wi-Fi重试");
|
||
sb.append("\n" + diagnosticMessage);
|
||
} else if (diagnosticType == 7) {
|
||
sb.append("定位失败,飞行模式下无法获取有效定位依据,请关闭飞行模式重试");
|
||
sb.append("\n" + diagnosticMessage);
|
||
} else if (diagnosticType == 9) {
|
||
sb.append("定位失败,无法获取任何有效定位依据");
|
||
sb.append("\n" + diagnosticMessage);
|
||
}
|
||
} else if (locType == BDLocation.TypeServerError) {
|
||
if (diagnosticType == 8) {
|
||
sb.append("定位失败,请确认您定位的开关打开状态,是否赋予APP定位权限");
|
||
sb.append("\n" + diagnosticMessage);
|
||
}
|
||
}
|
||
Log.e(TAG, "onLocationChanged: " + "定位失败");
|
||
mCacheHelper.put(ERROR_KEY, sb.toString());
|
||
Log.e(TAG, "onLocDiagnosticMessage: " + sb);
|
||
// logMsg(sb.toString(), tag);
|
||
}
|
||
};
|
||
|
||
// public AMapLocationClient getLocationClient() {
|
||
// if (null == locationClient) {
|
||
// initAmap();
|
||
// }
|
||
// return locationClient;
|
||
// }
|
||
|
||
// public void initAmap() {
|
||
// locationClient = new AMapLocationClient(mContext);
|
||
// AMapLocationClientOption option = new AMapLocationClientOption();
|
||
// option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);
|
||
// option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
|
||
// option.setNeedAddress(true);
|
||
// //获取一次定位结果:
|
||
// //该方法默认为false。
|
||
// option.setOnceLocation(true);
|
||
// //获取最近3s内精度最高的一次定位结果:
|
||
// //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。
|
||
// // 如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
|
||
// option.setOnceLocationLatest(true);
|
||
// locationClient.setLocationOption(option);
|
||
// //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
|
||
// //设置定位监听
|
||
// locationClient.setLocationListener(new AMapLocationListener() {
|
||
//
|
||
// @Override
|
||
// public void onLocationChanged(AMapLocation aMapLocation) {
|
||
// StringBuilder sb = new StringBuilder();
|
||
// //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
|
||
// if (aMapLocation.getErrorCode() == 0) {
|
||
// Log.e(TAG, "onLocationChanged: " + "定位成功");
|
||
// Log.e(TAG, "onLocationChanged: " + aMapLocation.getAddress());
|
||
// sb.append(aMapLocation.getAddress()).append("\n");
|
||
// mMMKV.encode( ADDRESS_KEY, aMapLocation.getAddress());
|
||
// mMMKV.encode( LONGITUDE_KEY, aMapLocation.getLongitude());
|
||
// mMMKV.encode( LATITUDE_KEY, aMapLocation.getLatitude());
|
||
// mMMKV.encode( ERROR_KEY, "");
|
||
// } else {
|
||
// //定位失败
|
||
// sb.append("定位失败" + "\n");
|
||
// Log.e(TAG, "onLocationChanged: " + "定位失败");
|
||
// mMMKV.encode( ERROR_KEY, String.valueOf(aMapLocation.getErrorInfo()));
|
||
// }
|
||
// Log.e(TAG, (String) SPUtils.get(mContext, ADDRESS_KEY, "-"));
|
||
// Log.e(TAG, (String) SPUtils.get(mContext, ERROR_KEY, "-"));
|
||
// Log.e(TAG, "amap: " + sb.toString());
|
||
// }
|
||
// });
|
||
// //设置场景模式后最好调用一次stop,再调用start以保证场景模式生效
|
||
// locationClient.stopLocation();
|
||
// locationClient.startLocation();
|
||
// Log.e(TAG, "initAmap: " + "startLocation");
|
||
// }
|
||
|
||
|
||
}
|