后台定位

当应用处于后台时,Android 系统会对定位操作施加限制。 通过将定位服务设置为前台服务,可以提高进程优先级,保障后台定位的正常运行。

如果应用本身已存在前台服务,或有其他方式保证进程处于前台,则无需使用本方案。



配置步骤

1. Manifest 声明 Service

AndroidManifest.xml 中添加 Service 声明,foregroundServiceType 设为 location

<service
    android:name="com.tencent.map.geolocation.s"
    android:foregroundServiceType="location" />

2. 启动前台定位

在发起定位请求之前,调用 enableForegroundLocation 开启前台服务:

mLocationManager.enableForegroundLocation(LOC_NOTIFICATIONID, buildNotification());
mLocationManager.requestLocationUpdates(request, this, getMainLooper());

enableForegroundLocation 需传入一个 int 类型的 Notification ID 和一个 Notification 实例。

3. 构建 Notification

前台服务需要一个通知栏通知。以下示例兼容 Android O(API 26)及以上的通知渠道机制:

private Notification buildNotification() {
    Notification.Builder builder = null;
    Notification notification = null;

    if (android.os.Build.VERSION.SDK_INT >= 26) {
        if (notificationManager == null) {
            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);
            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)
            .setContentTitle("LocationDemo")
            .setContentText("正在后台运行")
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
            .setWhen(System.currentTimeMillis());

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

4. 停止前台定位

// 停止定位
mLocationManager.removeUpdates(this);

// 调用 disableForegroundLocation 关闭前台服务释放资源。
// 参数 true 表示同时移除通知栏通知。
mLocationManager.disableForegroundLocation(true);

注意事项

  • 必须在 requestLocationUpdates 之前调用 enableForegroundLocation,否则前台服务无法生效。
  • 停止定位时务必调用 disableForegroundLocation,避免前台服务常驻。
  • Android O 及以上版本需要创建 NotificationChannel,否则通知无法展示。
  • 后台定位需要 ACCESS_BACKGROUND_LOCATION 权限(Android 10+),请确保已在 Manifest 中声明并动态申请。

相关链接

本页内容