Android Studio中使用Kotlin在Foreground Service集成CameraX实现后台相机
实现ForegroundService中基于CameraX的后台相机功能
前置准备
- 在
build.gradle(Module)中添加CameraX依赖:
dependencies { def camerax_version = "1.3.0" implementation "androidx.camera:camera-core:$camerax_version" implementation "androidx.camera:camera-camera2:$camerax_version" implementation "androidx.camera:camera-lifecycle:$camerax_version" }
- 在
AndroidManifest.xml声明必要权限与服务:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 可选,用于保持设备唤醒 --> <service android:name=".MyForegroundService" android:foregroundServiceType="camera" />
注意:Android 12+要求前台服务类型指定为
camera,同时必须动态申请CAMERA权限。
修改MyForegroundService完整实现
import android.app.Service import android.content.Intent import android.os.IBinder import android.util.Log import androidx.camera.core.CameraSelector import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageProxy import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider import androidx.core.content.ContextCompat import com.google.common.util.concurrent.ListenableFuture class MyForegroundService : Service() { private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider> private var cameraProvider: ProcessCameraProvider? = null override fun onCreate() { super.onCreate() // 初始化CameraProvider cameraProviderFuture = ProcessCameraProvider.getInstance(this) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val notification = createNotification() startForeground(1, notification) // 启动CameraX初始化 cameraProviderFuture.addListener({ cameraProvider = cameraProviderFuture.get() bindCameraUseCases() }, ContextCompat.getMainExecutor(this)) return START_STICKY } private fun bindCameraUseCases() { val cameraProvider = cameraProvider ?: return // 图像分析用例——后台相机核心,用于处理帧数据 val imageAnalysis = ImageAnalysis.Builder() .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build() .also { it.setAnalyzer(ContextCompat.getMainExecutor(this), object : ImageAnalysis.Analyzer { override fun analyze(imageProxy: ImageProxy) { // 在此处处理相机帧数据,比如图像采集、特征识别等 Log.d("CameraX", "收到相机帧:${imageProxy.imageInfo.timestamp}") // 处理完成必须关闭imageProxy,避免资源泄漏 imageProxy.close() } }) } // 选择后置摄像头(如需前置可替换为DEFAULT_FRONT_CAMERA) val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA try { // 先解绑所有已绑定的用例 cameraProvider.unbindAll() // 绑定生命周期与相机用例 cameraProvider.bindToLifecycle(this, cameraSelector, imageAnalysis) } catch(exc: Exception) { Log.e("CameraX", "相机用例绑定失败", exc) } } private fun createNotification() = androidx.core.app.NotificationCompat.Builder(this, "camera_service_channel") .setContentTitle("后台相机运行中") .setContentText("相机正在后台采集数据") .setSmallIcon(R.drawable.ic_notification) .build() override fun onDestroy() { super.onDestroy() // 销毁时释放相机资源 cameraProvider?.unbindAll() cameraProvider = null } override fun onBind(intent: Intent?): IBinder? = null }
关键注意事项
- 权限处理:启动服务前必须确保已获取
CAMERA权限,可在Activity中动态申请:
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA), 100) } else { startForegroundService(Intent(this, MyForegroundService::class.java)) }
- 版本限制:Android 10及以上系统对后台相机有严格限制,必须通过前台服务运行;Android 12+需指定
foregroundServiceType="camera"。 - 资源释放:Service销毁时务必解绑所有CameraX用例,避免内存泄漏和相机资源占用。
内容的提问来源于stack exchange,提问作者ahmad yamani
相关产品推荐
相关产品推荐

