onBind方法返回服务的绑定接口
发布时间:2025-06-24 17:20:52 作者:北方职教升学中心 阅读量:529
openCamera
方法打开摄像头并设置图像读取器。onBind
方法返回服务的绑定接口。预览以及图像的捕获和保存。saveImageToStorage
方法将捕获的图像保存到存储中。updatePreview
方法更新预览画面。createImageFile
方法创建一个用于保存图像的临时文件。startBackgroundThread
和 stopBackgroundThread
方法分别启动和停止后台线程。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
方法关闭摄像头和图像读取器。