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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:15:19