如何在服务中创建的新线程中拍照?
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.
中添加的
我正在通过创建一个新线程在后台服务中拍照。 问题是 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.
中添加的