onBind方法返回服务的绑定接口

发布时间:2025-06-24 17:20:52  作者:北方职教升学中心  阅读量:529


  • openCamera方法打开摄像头并设置图像读取器。
  • onBind方法返回服务的绑定接口。预览以及图像的捕获和保存。
  • saveImageToStorage方法将捕获的图像保存到存储中。
  • updatePreview方法更新预览画面。
  • createImageFile方法创建一个用于保存图像的临时文件。
  • startBackgroundThreadstopBackgroundThread方法分别启动和停止后台线程。
  • createCameraPreview方法创建摄像头预览会话。

    代码解释:

    • CameraService是一个后台服务,用于管理摄像头的打开、
      import android.annotation.SuppressLint;import android.app.Service;import android.content.Context;import android.content.Intent;import android.graphics.ImageFormat;import android.hardware.camera2.CameraAccessException;import android.hardware.camera2.CameraCaptureSession;import android.hardware.camera2.CameraCharacteristics;import android.hardware.camera2.CameraDevice;import android.hardware.camera2.CameraManager;import android.hardware.camera2.CameraMetadata;import android.hardware.camera2.CaptureRequest;import android.media.Image;import android.media.ImageReader;import android.os.Binder;import android.os.Handler;import android.os.HandlerThread;import android.os.IBinder;import android.util.Log;import android.view.Surface;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Date;public class CameraService extends Service {    private static final String TAG = "CameraService";    private CameraDevice cameraDevice;    private CameraCaptureSession cameraCaptureSession;    private CaptureRequest.Builder captureRequestBuilder;    private ImageReader imageReader;    private Handler backgroundHandler;    private HandlerThread backgroundThread;    private final IBinder binder = new LocalBinder();    public class LocalBinder extends Binder {        CameraService getService() {            return CameraService.this;       }    }    @Override    public IBinder onBind(Intent intent) {        return binder;   }    @Override    public void onCreate() {        super.onCreate();   }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        startBackgroundThread(); // 启动后台线程        openCamera(); // 打开摄像头        return START_NOT_STICKY;   }    @Override    public void onDestroy() {        closeCamera(); // 关闭摄像头        stopBackgroundThread(); // 停止后台线程        super.onDestroy();   }    private void startBackgroundThread() {        backgroundThread = new HandlerThread("CameraBackground");        backgroundThread.start();        backgroundHandler = new Handler(backgroundThread.getLooper());   }    private void stopBackgroundThread() {        backgroundThread.quitSafely();        try {            backgroundThread.join();            backgroundThread = null;            backgroundHandler = null;       } catch (InterruptedException e) {            Log.e(TAG, "Interrupted while waiting for background thread to close", e);       }    }    @SuppressLint("MissingPermission")    private void openCamera() {        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);        try {            String cameraId = chooseCamera(manager); // 选择摄像头            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);            imageReader = ImageReader.newInstance(                    720, 1080, ImageFormat.JPEG, 1);            imageReader.setOnImageAvailableListener(                    reader -> {                        Image image = reader.acquireLatestImage();                        // 处理图像数据,保存到沙箱                        saveImageToStorage(image);                        image.close();                   },                    backgroundHandler);            manager.openCamera(cameraId, new CameraDevice.StateCallback() {                @Override                public void onOpened(CameraDevice camera) {                    cameraDevice = camera;                    createCameraPreview(); // 创建摄像头预览               }                @Override                public void onDisconnected(CameraDevice camera) {                    cameraDevice.close();               }                @Override                public void onError(CameraDevice camera, int error) {                    cameraDevice.close();                    cameraDevice = null;               }            }, backgroundHandler);        } catch (CameraAccessException e) {            Log.e(TAG, "Cannot access the camera.", e);       }    }    private String chooseCamera(CameraManager manager) throws CameraAccessException {        for (String cameraId : manager.getCameraIdList()) {            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);            if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {                return cameraId; // 返回后置摄像头的ID           }        }        return manager.getCameraIdList()[0]; // 默认返回第一个摄像头    }    private void createCameraPreview() {        try {            Surface surface = imageReader.getSurface();            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);            captureRequestBuilder.addTarget(surface);            cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {                @Override                public void onConfigured(CameraCaptureSession session) {                    if (cameraDevice == null) {                        return;                   }                    cameraCaptureSession = session;                    updatePreview(); // 更新预览                }                @Override                public void onConfigureFailed(CameraCaptureSession session) {                    Log.e(TAG, "Failed to configure camera preview.");               }            }, null);        } catch (CameraAccessException e) {            Log.e(TAG, "Error creating camera preview.", e);       }    }    private void updatePreview() {        if (cameraDevice == null) {            return;       }        captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);        try {            cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler);       } catch (CameraAccessException e) {            Log.e(TAG, "Error updating preview.", e);       }    }    private void closeCamera() {        if (cameraCaptureSession != null) {            cameraCaptureSession.close();            cameraCaptureSession = null;       }        if (cameraDevice != null) {            cameraDevice.close();            cameraDevice = null;       }        if (imageReader != null) {            imageReader.close();            imageReader = null;       }    }    private void saveImageToStorage(Image image) {        ByteBuffer buffer = image.getPlanes()[0].getBuffer();        byte[] bytes = new byte[buffer.remaining()];        buffer.get(bytes);        File imageFile = null;        try {            imageFile = createImageFile(); // 创建图像文件       } catch (IOException e) {            Log.e(TAG, "Error creating image file.", e);       }        try (FileOutputStream output = new FileOutputStream(imageFile)) {            output.write(bytes);            closeCamera(); // 关闭摄像头            stopBackgroundThread(); // 停止后台线程            Log.d(TAG, "Image saved: " + imageFile.getAbsolutePath());       } catch (IOException e) {            Log.e(TAG, "Error saving image.", e);       }    }    private File createImageFile() throws IOException {        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());        String imageFileName = "JPEG_" + timeStamp + "_";        File storageDir = getFilesDir();        return File.createTempFile(imageFileName, ".jpg", storageDir); // 创建临时图像文件   }}
    • 提示:需在activity中启动CameraService服务,包括在AndroidManifest.xml添加权限,开启相机权限等等

  • onDestroy方法在服务销毁时调用,关闭摄像头并停止后台线程。
  • onStartCommand方法在服务启动时调用,启动后台线程并打开摄像头。
  • chooseCamera方法选择后置摄像头。
  • onCreate方法初始化服务。
  • closeCamera方法关闭摄像头和图像读取器。