如何在服务中创建的新线程中拍照?

How Can I take pictures in a new Thread which is created in a service?

我正在通过创建一个新线程在后台服务中拍照。 问题是 camera.takePicture 没有被执行。服务启动、停止和迭代正确只是 takePicture 没有执行。 表明 W/Camera-JNI:死相机对象回调 在每次迭代中 logcat。

这是我的相机服务class

package com.flynn.pictureseverysecond;


import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.Nullable;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class CameraService extends Service implements Info {
    public static final int MEDIA_TYPE_IMAGE = 1;

    volatile boolean running = true;

    private Camera mCamera;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: service started");
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "run: Thread still alive");
                while (running) {
                    mCamera = Util.getCameraInstance();
                    Log.i(TAG, "run: created camera instance");
                    if (mCamera != null) {
                        try {
                            mCamera.setPreviewTexture(new SurfaceTexture(0));
                            mCamera.startPreview();
                            Log.i(TAG, "run: preview set");
                            mCamera.takePicture(null, null, new Camera.PictureCallback() {

                                @Override
                                public void onPictureTaken(byte[] data, Camera camera) {
                                    Log.i(TAG, "onPictureTaken: here");
                                    File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
                                    if (pictureFile == null) {
                                        Log.e(TAG, "onPictureTaken: cannot create media files check Permissions");
                                        return;
                                    }
                                    try {
                                        Log.i(TAG, "onPictureTaken: arrived");
                                        FileOutputStream fos = new FileOutputStream(pictureFile);
                                        fos.write(data);
                                        fos.close();
                                    } catch (FileNotFoundException e) {
                                        Log.e(TAG, "onPictureTaken: File not found" + e.getMessage());
                                    } catch (IOException e) {
                                        Log.e(TAG, "onPictureTaken: Error Accessing File " + e.getMessage());
                                    }
                                }
                            });
                            releaseCamera();
                            Thread.sleep(3000);
                        } catch (IOException | InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestroy: cam service ending....");
        running = false;
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private static Uri getOutputMediaFileUri(int type) {
        return Uri.fromFile(getOutputMediaFile(type));
    }

    private static File getOutputMediaFile(int type) {
        Log.i(TAG, "getOutputMediaFile: inside");
        File storageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "fuckrey");
        Log.i(TAG, "getOutputMediaFile: dir created");
        if (!storageDir.exists()) {
            if (!storageDir.mkdirs()) {
                Log.e(TAG, "getOutputMediaFile: Failed to create directory");
                return null;
            }
        }

        @SuppressLint("SimpleDateFormat")
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(storageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
        } else {
            Log.i(TAG, "getOutputMediaFile: returning null");
            return null;
        }

        Log.i(TAG, "getOutputMediaFile: properly returning");
        return mediaFile;
    }


        private void releaseCamera () {
            if (mCamera != null) {
                mCamera.release();        // release the camera for other applications
                mCamera = null;
            }
        }

}

请帮助我,我的代码有什么问题?

后台服务无法访问相机。 Forground 服务只有在您指定相机服务类型时才能使用。而你的绝对是后台服务。这是在 Android 11.

中添加的