I wrote the Android program shown below to record the front camera in the background. It works very well. But now I also want to take a picture every 5 seconds while recording. Is it possible? When I try to open the second camera (in another service), I get an error message.
public class RecorderService extends Service implements SurfaceHolder.Callback { private WindowManager windowManager; private SurfaceView surfaceView; private Camera camera = null; private MediaRecorder mediaRecorder = null; @Override public void onCreate() { // Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); surfaceView = new SurfaceView(this); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( 1, 1, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT ); layoutParams.gravity = Gravity.LEFT | Gravity.TOP; windowManager.addView(surfaceView, layoutParams); surfaceView.getHolder().addCallback(this); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new NotificationCompat.Builder(this) //.setSmallIcon(R.mipmap.app_icon) .setContentTitle("Background Video Recorder") .setContentText("") .setContentIntent(pendingIntent).build(); startForeground(MainActivity.NOTIFICATION_ID_RECORDER_SERVICE, notification); return Service.START_NOT_STICKY; } // Method called right after Surface created (initializing and starting MediaRecorder) @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { camera = Camera.open(1); mediaRecorder = new MediaRecorder(); camera.unlock(); mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); mediaRecorder.setCamera(camera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P)); FileUtil.createDir("/storage/emulated/0/Study/Camera"); mediaRecorder.setOutputFile("/storage/emulated/0/Study/Camera/" + Long.toString(System.currentTimeMillis()) + ".mp4"); try { mediaRecorder.prepare(); } catch (Exception e) {} mediaRecorder.start(); try { camera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { e.printStackTrace(); } Runnable runnable = new PictureThread(camera); Thread thread = new Thread(runnable); thread.start(); } // Stop recording and remove SurfaceView @Override public void onDestroy() { mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); camera.lock(); camera.release(); windowManager.removeView(surfaceView); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {} @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {} @Override public IBinder onBind(Intent intent) { return null; } }
Edit : I have now written a PictureThread thread. This thread starts with RecorderService and tries to take a snapshot during video recording.
public class PictureThread implements Runnable { private final static String TAG = PictureThread.class.getSimpleName(); private Camera camera; PictureThread(Camera camera) { this.camera = camera; } @Override public void run() { camera.startPreview(); camera.takePicture(shutterCallback, rawCallback, jpegCallback); } Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() { public void onShutter() { } }; Camera.PictureCallback rawCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { } }; Camera.PictureCallback jpegCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { Log.i(TAG, "onPictureTaken - jpeg"); } }; }
Unfortunately, jpegCallback never called (i.e. a log message is never printed). When I open the camera application of my tablet, I can take pictures during video recording, so this should be possible.
I also tried the Camera2 API example suggested by Alex Cohn ( https://github.com/mobapptuts/android_camera2_api_video_app ). Video recording works, and shooting is also performed, but when I try to take a picture while recording, the image is not created (but also without errors). However, I found that this application does not work very reliably (maybe there is another sample application).
Change 2 . shutterCallback and rawCallback of takePicture , but the rawCallback data is null. jpegCallback never called. Any idea why and how this can be resolved? I also tried to wait in the thread for some time to give the callback time for the call, and I tried to make the callbacks static in my main action (so that it was not going to collect garbage). Nothing succeeded.