You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android12(targetSDK31)前台服务BLE后台扫描30秒后停止求助

Android 12(targetSDK31)前台服务BLE后台扫描停止问题解决方案

权限调整

  1. 补充必要权限

    • 添加FOREGROUND_SERVICE和FOREGROUND_SERVICE_CONNECTED_DEVICE权限(Android 12+要求BLE相关前台服务声明此类型):
      <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
      <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
      
    • 修正BLUETOOTH_SCAN权限:如果扫描不需要获取设备位置,添加neverForLocation标记避免位置权限依赖导致的扫描限制;若需位置信息,必须申请ACCESS_FINE_LOCATION权限:
      <!-- 无需位置的扫描配置 -->
      <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
          android:usesPermissionFlags="neverForLocation" />
      <!-- 需要位置的扫描配置 -->
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      
    • 删除无效权限:REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND仅适用于Companion设备应用,普通APP无需;自定义的START_ACTIVITIES_FROM_BACKGROUND权限无实际作用,直接移除。
  2. 前台服务声明优化
    在Manifest的Service标签中指定前台服务类型:

    <service android:name=".YourBleScanForegroundService"
        android:foregroundServiceType="connectedDevice" />
    

扫描方式调整

  1. 改用周期性扫描
    Android 12对后台连续BLE扫描有严格限制,即使前台服务也会在30秒后终止。建议采用扫描+休眠的周期性策略,例如扫描10秒、休眠20秒循环执行:
    private void startPeriodicScan() {
        Handler handler = new Handler(Looper.getMainLooper());
        Runnable scanRunnable = new Runnable() {
            @Override
            public void run() {
                // 启动BLE扫描
                bluetoothLeScanner.startScan(scanFilters, scanSettings, scanCallback);
                // 10秒后停止扫描
                handler.postDelayed(() -> {
                    bluetoothLeScanner.stopScan(scanCallback);
                    // 20秒后再次启动扫描
                    handler.postDelayed(this, 20000);
                }, 10000);
            }
        };
        scanRunnable.run();
    }
    
  2. 调整扫描参数
    使用低功耗或平衡模式的扫描设置,避免后台不允许的高功耗扫描:
    ScanSettings scanSettings = new ScanSettings.Builder()
        .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) // 或SCAN_MODE_BALANCED
        .build();
    

前台服务启动合规性

启动前台服务时,Android 12+必须指定FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE类型,同时确保通知符合系统要求:

Notification notification = new NotificationCompat.Builder(this, "BLE_SCAN_CHANNEL")
       .setContentTitle("BLE扫描中")
       .setContentText("正在扫描周边BLE设备")
       .setSmallIcon(R.drawable.ic_scan)
       .setCategory(Notification.CATEGORY_SERVICE)
       .build();

// 适配Android 12+前台服务类型
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
   startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE);
} else {
   startForeground(NOTIFICATION_ID, notification);
}

内容的提问来源于stack exchange,提问作者KK_07k11A0585

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:00:58