高德后台定位注意事项

一、 定位权限

除了粗略定位权限和精准定位权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

注意添加后台定位权限

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

二、 调用高德开启后台定位

AMapLocationClient locationClient = new AMapLocationClient(context.getApplicationContext());

// 开启后台定位
locationClient.enableBackgroundLocation(id, notification);

原理为使用一个通知来调起后台定位,如下为通知的创建
java版本

private static final String              NOTIFICATION_CHANNEL_NAME = "自定义";
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.mipmap.zbmap_icon)
            .setContentTitle("自定义")
            .setContentText("自定义")
            .setWhen(System.currentTimeMillis());

    if (android.os.Build.VERSION.SDK_INT >= 16) {
        notification = builder.build();
    } else {
        return builder.getNotification();
    }
    return notification;
}

kotlin版本

private val NOTIFICATION_CHANNEL_NAME = "自定义"
private var notificationManager: NotificationManager? = null
internal var isCreateChannel = false

@SuppressLint("NewApi")
private fun buildNotification(): Notification? {

    var builder: Notification.Builder? = null
    var notification: Notification? = null
    if (android.os.Build.VERSION.SDK_INT >= 26) {
        //Android O上对Notification进行了修改,如果设置的targetSDKVersion>=26建议使用此种方式创建通知栏
        if (null == notificationManager) {
            notificationManager =
                    getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        }
        val channelId = packageName
        if (!isCreateChannel) {
            val notificationChannel = NotificationChannel(
                    channelId,
                    NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationChannel.enableLights(true)//是否在桌面icon右上角展示小圆点
            notificationChannel.lightColor = Color.BLUE //小圆点颜色
            notificationChannel.setShowBadge(true) //是否在久按桌面图标时显示此渠道的通知
            notificationManager!!.createNotificationChannel(notificationChannel)
            isCreateChannel = true
        }
        builder = Notification.Builder(applicationContext, channelId)
    } else {
        builder = Notification.Builder(applicationContext)
    }
    builder.setSmallIcon(R.mipmap.ic_app_face)
        .setContentTitle("自定义")
        .setContentText("自定义")
        .setWhen(System.currentTimeMillis())

    if (android.os.Build.VERSION.SDK_INT >= 16) {
        notification = builder.build()
    } else {
        return builder.notification
    }
    return notification
}

三、 高德关闭后台定位

locationClient.disableBackgroundLocation(boolean removeNotification);

开启和关闭的时机可以自己在应用内写一个,推荐 https://blog.csdn.net/u011386173/article/details/79095757 这篇文章的第三种方法,也是高德官方定位sdk中使用的方法

四、高德后台定位息屏问题

这里分两种情况:

  1. 息屏不联网
  2. 息屏联网
  3. 息屏联网带30s间隔心跳长链接

为什么只考虑联网不联网,因为使用高德定位是必须打开位置服务的

机型1、 小米9(android 10)息屏定位

息屏定位设置

在设置中搜索 "电池与性能",点击右上角 设置 图标,选择 "应用智能省点",对自己的应用选择 "无限制" 即可,总共有四个选项,默认都是 "智能限制后台运行",情况就是下面这些:

也可以在 "应用设置" —> "应用管理" 中找到自己的应用,将 "省电策略" 改为 "无限制"

如果不设置

情况1会在息屏一段时间(大概一分钟)后报

错误码: 4
错误详情:网络连接异常 请到http://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode/
查看错误码说明,错误详细信息:#id:YaDloaGZhYWg0ZjQ0NGFmbDhqa2Q5NWE3NmUxMzRkLFh0Q1hKL2lJV1hrREFCYWxmZGxwZXpYLw==
网络异常,未连接到网络,请连接网络#0401

情况2会在息屏一段时间(大概一分钟)后,返回lbs类型的定位信息,并且内容相同,很长时间才会变化且结果精度比较差

出现上述情况应该是息屏后一段时间cpu休眠导致,具体解决可查看高德官方的一个方法https://lbs.amap.com/faq/android/location-sdk/position/43278

情况3还是和情况2一样

机型2、 三星A6s(android 9)息屏定位

息屏定位设置

设置中搜索"优化电池使用量",打开后选择"所有应用程序",找到自己的应用并关闭掉优化

如果不设置

三种情况都会在后台定位一段时候后应用被杀死

机型3、 华为P30、Mate30(android 10)息屏定位

息屏定位设置

"手机管家" —> "应用启动管理" 中找到自己的应用,将 "手动管理" 改为 "自动管理",然后在换回 "手动管理" ,在弹出的选项中将 "允许后台活动" 打开

下面是之前做的一些无用尝试:
1.在设置中搜索 "电池" —> "更多电池设置" —> "休眠时始终保持网络连接打开" ,这可以保证有网时WebSocket长链接正常;
2.可以开启 "电池" —> "性能模式",但这应该无关紧要,只是会更耗电;
3."隐私" —> "权限管理",右上角更多选择"特殊访问权限" —> "电池优化",选择对自己的应用不允许优化

无用尝试的设置作用都不大,华为如果不开启"允许后台活动",充电刺激也能保证息屏时gps定位,可以用充电宝充着电,即使不联网在室外也没问题

如果不设置

三种情况息屏后定位10~30秒后直接停止了,再次解锁后才重新定位。

在这里插入图片描述

机型4、 vivo IQOO neo3(android 10)息屏定位

息屏定位设置

设置中"电池" —> "后台高耗电" 中找到自己的应用,允许在后台高耗电是继续运行即可

如果不设置

三种情况息屏后定位在2~3分钟后停止,再次解锁后才重新定位。

机型5、 oppo R17(android 10)息屏定位

待测试

你可能感兴趣的:(高德后台定位注意事项)