無法後臺持續定位:
高德地圖持續定位,在後臺持續定位一段時間後就會報錯;
AmapError: ErrCode:12, errInfo:缺少定位權限 請到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯誤碼說明,錯誤詳細信息:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207
手機權限上就沒有後臺定位權限,Android8.0以後纔會提示打開後臺定位權限,(如果設置了target > 28,需要增加這個權限 ACCESS_BACKGROUND_LOCATION,否則不會彈出"始終允許"這個選擇框);
下面看一下踩坑之旅:
集成高德地圖定位SDK:
按照官方文檔集成就行了:
2、獲取定位數據 ;
下面就是在後臺持續定位的代碼,前臺服務;也可以參考這個官方Demo android-o-backgroundlocation:
public class BackLocationService extends Service {
public BackLocationService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1,buildNotification());
initLocation();
// 設置定位參數
locationClient.setLocationOption(locationOption);
// 啓動定位
locationClient.startLocation();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
locationClient.onDestroy();
super.onDestroy();
}
private AMapLocationClient locationClient = null;
private AMapLocationClientOption locationOption = null;
private void initLocation() {
//初始化client
locationClient = new AMapLocationClient(this.getApplicationContext());
locationOption = getDefaultOption();
//設置定位參數
locationClient.setLocationOption(locationOption);
// 設置定位監聽
locationClient.setLocationListener(locationListener);
}
/**
* 默認的定位參數
*/
private AMapLocationClientOption getDefaultOption() {
AMapLocationClientOption mOption = new AMapLocationClientOption();
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可選,設置定位模式,可選的模式有高精度、僅設備、僅網絡。默認爲高精度模式
mOption.setGpsFirst(false);//可選,設置是否gps優先,只在高精度模式下有效。默認關閉
mOption.setHttpTimeOut(30000);//可選,設置網絡請求超時時間。默認爲30秒。在僅設備模式下無效
mOption.setInterval(2000);//可選,設置定位間隔。默認爲2秒
mOption.setNeedAddress(true);//可選,設置是否返回逆地理地址信息。默認是true
mOption.setOnceLocation(false);//可選,設置是否單次定位。默認是false
mOption.setOnceLocationLatest(false);//可選,設置是否等待wifi刷新,默認爲false.如果設置爲true,會自動變爲單次定位,持續定位時不要使用
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可選, 設置網絡請求的協議。可選HTTP或者HTTPS。默認爲HTTP
mOption.setSensorEnable(true);//可選,設置是否使用傳感器。默認是false
mOption.setWifiScan(true); //可選,設置是否開啓wifi掃描。默認爲true,如果設置爲false會同時停止主動刷新,停止以後完全依賴於系統刷新,定位位置可能存在誤差
mOption.setLocationCacheEnable(true); //可選,設置是否使用緩存定位,默認爲true
return mOption;
}
/**
* 定位監聽
*/
AMapLocationListener locationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation location) {
if (null != location) {
StringBuffer sb = new StringBuffer();
//errCode等於0代表定位成功,其他的爲定位失敗,具體的可以參照官網定位錯誤碼說明
if (location.getErrorCode() == 0) {
sb.append("Service定位成功" + ",");
sb.append("經 度 : " + location.getLongitude() + ",");
sb.append("緯 度 : " + location.getLatitude() + ",");
sb.append("定位時間: " + Utils.formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + ",");
} else {
//定位失敗
sb.append("Service定位失敗" + ",");
sb.append("經 度 : " + location.getLongitude() + ",");
sb.append("緯 度 : " + location.getLatitude() + ",");
sb.append("定位時間: " + Utils.formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + ",");
sb.append("錯誤碼:" + location.getErrorCode() + ",");
sb.append("錯誤信息:" + location.getErrorInfo() + ",");
sb.append("錯誤描述:" + location.getLocationDetail() + ",");
// stopForeground(true);
}
//定位之後的回調時間
sb.append("回調時間: " + Utils.formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "\n");
//解析定位結果,
String result = sb.toString();
Log.i("Location", result);
} else {
}
}
};
private static final String NOTIFICATION_CHANNEL_NAME = "BackgroundLocation";
private NotificationManager notificationManager = null;
boolean isCreateChannel = false;
@SuppressLint("NewApi")
private Notification buildNotification() {
Notification.Builder builder = null;
Notification notification = null;
if (android.os.Build.VERSION.SDK_INT >= 26) {
//Android O上對Notification進行了修改,如果設置的targetSDKVersion>=26建議使用此種方式創建通知欄
if (null == notificationManager) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
String channelId = getPackageName();
if (!isCreateChannel) {
NotificationChannel notificationChannel = new NotificationChannel(channelId,
NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.enableLights(true);//是否在桌面icon右上角展示小圓點
notificationChannel.setLightColor(Color.BLUE); //小圓點顏色
notificationChannel.setShowBadge(true); //是否在久按桌面圖標時顯示此渠道的通知
notificationManager.createNotificationChannel(notificationChannel);
isCreateChannel = true;
}
builder = new Notification.Builder(getApplicationContext(), channelId);
} else {
builder = new Notification.Builder(getApplicationContext());
}
builder.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(Utils.getAppName(this))
.setContentText("定位Srevice正在後臺運行")
.setContentIntent(PendingIntent.getActivity(this, 0, this.getPackageManager().getLaunchIntentForPackage(this.getPackageName()), PendingIntent.FLAG_UPDATE_CURRENT))
.setWhen(System.currentTimeMillis());
if (android.os.Build.VERSION.SDK_INT >= 16) {
notification = builder.build();
} else {
return builder.getNotification();
}
return notification;
}
}
後臺持續定位開始報錯:
當程序切換到後臺,或黑屏幾分鐘後,就開始報錯獲取不到位置;
錯誤碼:12,錯誤信息:缺少定位權限 請到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯誤碼說明,錯誤詳細信息:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207;
我把錯誤打印日誌拉出來幾條看一下:
2020-03-31 16:54:22.996 22627-22627/com.ccb.socketdemo I/Location: Service定位成功,經 度 : 121.548713,緯 度 : 31.32618,定位時間: 2020-03-31 16:50:30,回調時間: 2020-03-31 16:54:22
2020-03-31 16:54:25.049 22627-22627/com.ccb.socketdemo I/Location: Service定位失敗,經 度 : 0.0,緯 度 : 0.0,定位時間: 1970-01-01 08:00:00,錯誤碼:12,錯誤信息:缺少定位權限 請到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯誤碼說明,錯誤詳細信息:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207,錯誤描述:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207,回調時間: 2020-03-31 16:54:25
2020-03-31 16:54:27.008 22627-22627/com.ccb.socketdemo I/Location: Service定位失敗,經 度 : 0.0,緯 度 : 0.0,定位時間: 1970-01-01 08:00:00,錯誤碼:12,錯誤信息:缺少定位權限 請到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看錯誤碼說明,錯誤詳細信息:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207,錯誤描述:後臺定位服務沒有開啓,請在設置中打開後臺定位服務開關#1207,回調時間: 2020-03-31 16:54:27
2020-03-31 16:54:29.020 22627-22627/com.ccb.socketdemo I/Location: Service定位成功,經 度 : 121.548723,緯 度 : 31.326164,定位時間: 2020-03-31 16:54:19,回調時間: 2020-03-31 16:54:29
我換了好多種保護後臺定位方法:⚪ 前臺服務中持續定位、⚪ Activity+通知欄 持續定位、⚪ 保活服務(前臺服務+無聲音樂+雙服務互相啓動+像素保活)中持續定位。都會出現這個問題;沒有辦法,我把高德的定位Demo下載試了一下,也是會出現這個問題;
於是,我向高德官方提交了問題工單:
關於後臺持續定位的答覆:
高德的答覆是:目前大部分系統會凍結或關閉後臺服務,導致後臺服務無法正常運行。 目前建議您與對應的廠商進行聯繫,爲您的APP開通白名單權限,保證您的APP在後臺運行可以正常使用;