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() { }.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"); // } }