I am taking pictures in a background service, by creating a new thread. The issue is camera.takePicture is not executed. service starts, stops and iterates correctly just takePicture is not executed. It shows W/Camera-JNI: callback on dead camera object in the logcat in each iteration.
Here is My CameraService 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;
}
}
}
Please Help me, what is wrong with my code?
CodePudding user response:
Background services cannot access the camera. Forground services can only if you specify the camera service type. And yours is definitely a background service. This was added back in Android 11.