Android 高德地图无法后台持续定位,缺少后台定位权限#1207;

无法后台持续定位:

高德地图持续定位,在后台持续定位一段时间后就会报错;

AmapError: ErrCode:12, errInfo:缺少定位权限 请到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/查看错误码说明,错误详细信息:后台定位服务没有开启,请在设置中打开后台定位服务开关#1207

手机权限上就没有后台定位权限,Android8.0以后才会提示打开后台定位权限,(如果设置了target > 28,需要增加这个权限 ACCESS_BACKGROUND_LOCATION,否则不会弹出"始终允许"这个选择框);

下面看一下踩坑之旅:

 

集成高德地图定位SDK:

按照官方文档集成就行了:

1、Android Studio 配置工程 ;

2、获取定位数据 ;

3、Android 8.0权限说明,后台定位权限;

下面就是在后台持续定位的代码,前台服务;也可以参考这个官方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在后台运行可以正常使用;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章