Advertisement
NotTrue

Camera crash

Nov 2nd, 2019
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.41 KB | None | 0 0
  1. package com.chronotum.testing2;
  2.  
  3. import android.Manifest;
  4. import android.annotation.SuppressLint;
  5. import android.content.Context;
  6. import android.content.SharedPreferences;
  7. import android.content.pm.PackageManager;
  8. import android.graphics.ImageFormat;
  9. import android.hardware.camera2.CameraAccessException;
  10. import android.hardware.camera2.CameraCaptureSession;
  11. import android.hardware.camera2.CameraCharacteristics;
  12. import android.hardware.camera2.CameraDevice;
  13. import android.hardware.camera2.CameraManager;
  14. import android.hardware.camera2.CameraMetadata;
  15. import android.hardware.camera2.CaptureRequest;
  16. import android.hardware.camera2.params.StreamConfigurationMap;
  17. import android.media.MediaRecorder;
  18. import android.os.Build;
  19. import android.os.Bundle;
  20. import android.os.Environment;
  21. import android.os.Handler;
  22. import android.os.HandlerThread;
  23. import android.os.VibrationEffect;
  24. import android.os.Vibrator;
  25. import android.util.Log;
  26. import android.util.Size;
  27. import android.view.Menu;
  28. import android.view.MenuItem;
  29. import android.view.Surface;
  30. import android.view.View;
  31. import android.widget.Toast;
  32.  
  33. import androidx.annotation.NonNull;
  34. import androidx.appcompat.app.AppCompatActivity;
  35. import androidx.appcompat.widget.Toolbar;
  36.  
  37. import com.google.android.material.floatingactionbutton.FloatingActionButton;
  38.  
  39. import java.io.File;
  40. import java.io.IOException;
  41. import java.text.SimpleDateFormat;
  42. import java.util.ArrayList;
  43. import java.util.Collections;
  44. import java.util.Date;
  45. import java.util.concurrent.Semaphore;
  46. import java.util.concurrent.TimeUnit;
  47.  
  48. import static android.os.Environment.getExternalStoragePublicDirectory;
  49.  
  50. public class MainActivity extends AppCompatActivity {
  51.  
  52.     @Override
  53.     protected void onCreate(Bundle savedInstanceState) {
  54.         super.onCreate(savedInstanceState);
  55.         setContentView(R.layout.activity_main);
  56.         Toolbar toolbar = findViewById(R.id.toolbar);
  57.         setSupportActionBar(toolbar);
  58.  
  59.         Log.v(TAG, "EXTERNAL STORAGE AVAILABLE:"+Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()));
  60.  
  61.  
  62.         cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
  63.         vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
  64.  
  65.         checkAllRequiredPermissions();
  66.  
  67.         FloatingActionButton fab = findViewById(R.id.fab);
  68.         fab.setOnClickListener(new View.OnClickListener() {
  69.             @Override
  70.             public void onClick(View view) {
  71.                 startRecording();
  72.             }
  73.         });
  74.     }
  75.  
  76.     private boolean checkAllRequiredPermissions() {
  77.  
  78.         //Missing permissions
  79.         ArrayList<String> requiredPermissions = new ArrayList<>();
  80.  
  81.         //Fundamental permissions
  82.         if (checkCallingOrSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
  83.             requiredPermissions.add(Manifest.permission.CAMERA);
  84.         }
  85.         if (checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
  86.             requiredPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
  87.         }
  88.         Log.e(TAG, "TEST Manifest.permission.READ_EXTERNAL_STORAGE");
  89.         if (checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
  90.             requiredPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
  91.             Log.e(TAG, "TEST Manifest.permission.READ_EXTERNAL_STORAGE");
  92.         }
  93.  
  94.         //Audio
  95.         if ((checkCallingOrSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_DENIED)) {
  96.             requiredPermissions.add(Manifest.permission.RECORD_AUDIO);
  97.         }
  98.  
  99.         //Request required permissions
  100.         if (!requiredPermissions.isEmpty()) {
  101.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  102.                 requestPermissions(requiredPermissions.toArray(new String[0]), 0);
  103.                 //Toast.makeText(getBaseContext(),"Error: Permission requirements are not met!",Toast.LENGTH_LONG).show();
  104.             }
  105.             return false;
  106.         }
  107.  
  108.         return true;
  109.     }
  110.  
  111.     @Override
  112.     public boolean onCreateOptionsMenu(Menu menu) {
  113.         // Inflate the menu; this adds items to the action bar if it is present.
  114.         getMenuInflater().inflate(R.menu.menu_main, menu);
  115.         return true;
  116.     }
  117.  
  118.     @Override
  119.     public boolean onOptionsItemSelected(MenuItem item) {
  120.         // Handle action bar item clicks here. The action bar will
  121.         // automatically handle clicks on the Home/Up button, so long
  122.         // as you specify a parent activity in AndroidManifest.xml.
  123.         int id = item.getItemId();
  124.  
  125.         //noinspection SimplifiableIfStatement
  126.         if (id == R.id.action_settings) {
  127.             return true;
  128.         }
  129.  
  130.         return super.onOptionsItemSelected(item);
  131.     }
  132.  
  133.     //TAG
  134.     private String TAG = "Service";
  135.  
  136.     //Managers
  137.     private static CameraManager cameraManager;
  138.     private static Vibrator vibrator;
  139.  
  140.     //States
  141.     public static boolean isRecording = false;
  142.     public static boolean isSettingUpRecording = false;
  143.  
  144.     //Preference variables
  145.     private static int cameraId;
  146.     private static Integer cameraDirection;
  147.     private static Size cameraResolution;
  148.     private static int cameraOrientation;
  149.     private static boolean flashlightEnable;
  150.     private static boolean durationEnabled;
  151.     private static int recordingDuration;
  152.     private static boolean repeatingEnabled;
  153.     private static int recordingRepeat;
  154.     private static long recordingFileSize;
  155.     private static File recordingDirectory;
  156.     private static boolean vibrationStartRecordingEnabled;
  157.     private static boolean vibrationStartOfEachFileEnabled;
  158.     private static boolean vibrationStopRecordingEnabled;
  159.     private static boolean microphoneEnabled;
  160.  
  161.     //Thread
  162.     private HandlerThread mBackgroundThread;
  163.     private Handler mBackgroundHandler;
  164.  
  165.     //Recording
  166.     private static MediaRecorder mMediaRecorder;
  167.     private static CameraCaptureSession captureSession;
  168.     private static CaptureRequest.Builder captureRequestBuilder;
  169.  
  170.     //Camera lock
  171.     private Semaphore mCameraOpenCloseLock = new Semaphore(1);
  172.  
  173.     /**
  174.      * A reference to the opened {@link android.hardware.camera2.CameraDevice}.
  175.      */
  176.     private CameraDevice mCameraDevice;
  177.  
  178.     public void startRecording() {
  179.  
  180.         //Check if the we are already setting up settings or if we are already recording
  181.         if (isRecording || isSettingUpRecording) {
  182.             Log.v(TAG, "Start recording denied \n" +
  183.                     "isRecording: " + isRecording + "\n" +
  184.                     "isSettingUpRecording: " + isSettingUpRecording + "\n" +
  185.                     "\n" +
  186.                     "Start recording denied");
  187.             return;
  188.         }
  189.  
  190.         //We are now setting up the recording session
  191.         isSettingUpRecording = true;
  192.  
  193.         //Setup preferences
  194.         if (!setupPreferences()) {
  195.             stopRecording();
  196.         }
  197.  
  198.         startBackgroundThread();
  199.  
  200.         if (!openCamera()) {
  201.             Toast.makeText(getBaseContext(), "ERROR OPENING CAMERA", Toast.LENGTH_LONG).show();
  202.             stopRecording();
  203.         }
  204.  
  205.     }
  206.  
  207.     /**
  208.      * Tries to open a {@link CameraDevice}. The result is listened by `mStateCallback`.
  209.      */
  210.     private boolean openCamera() {
  211.  
  212.         if (checkCallingOrSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
  213.             return false;
  214.         }
  215.  
  216.         try {
  217.             if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
  218.                 Log.e(TAG, "Time out waiting to lock camera opening.");
  219.                 return false;
  220.             }
  221.  
  222.             cameraManager.openCamera(String.valueOf(cameraId), new CameraDevice.StateCallback() {
  223.                 @Override
  224.                 public void onOpened(@NonNull CameraDevice camera) {
  225.                     Log.i(TAG, "onOpened");
  226.  
  227.                     mCameraDevice = camera;
  228.  
  229.                     //Select method by version
  230.                     if (21 <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < 26) {
  231.                         Log.i(TAG, "VERSION 21");
  232. //                        setupV21();
  233. //                        startRecordingSessionV21();
  234.                     } else if (26 <= Build.VERSION.SDK_INT) {
  235.                         Log.i(TAG, "VERSION 26");
  236.                         startRecordingSessionV26();
  237.                     }
  238.  
  239.                     mCameraOpenCloseLock.release();
  240.                 }
  241.  
  242.                 @Override
  243.                 public void onDisconnected(@NonNull CameraDevice camera) {
  244.                     Log.i(TAG, "onDisconnected");
  245.                     mCameraOpenCloseLock.release();
  246.                     camera.close();
  247.                     mCameraDevice = null;
  248.                 }
  249.  
  250.                 @Override
  251.                 public void onError(@NonNull CameraDevice camera, int error) {
  252.                     Log.e(TAG, "onError");
  253.                     mCameraOpenCloseLock.release();
  254.                     camera.close();
  255.                     mCameraDevice = null;
  256.                 }
  257.             }, null);
  258.  
  259.         } catch (InterruptedException | CameraAccessException e) {
  260.             e.printStackTrace();
  261.             return false;
  262.         }
  263.         return true;
  264.     }
  265.  
  266.     public void stopRecording(){
  267.  
  268.     }
  269.  
  270.     public boolean setupPreferences() {
  271.  
  272.         //Id of selected camera
  273.         cameraId = 0;
  274.  
  275.         try {
  276.             //Camera properties
  277.             CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(Integer.toString(cameraId));
  278.  
  279.             //Direction of the camera
  280.             cameraDirection = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
  281.  
  282.             //Camera resolution
  283.             int cameraResolutionIndex = 0;
  284.             cameraResolution = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(MediaRecorder.class)[cameraResolutionIndex];
  285.  
  286.             StreamConfigurationMap streamConfigurationMap =cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
  287.  
  288.             //Orientation
  289.             cameraOrientation = 0;
  290.  
  291.             //Camera Extra
  292.             flashlightEnable = true;
  293.  
  294.             //Audio
  295.             microphoneEnabled = true;
  296.  
  297.             //Duration
  298.             durationEnabled = true;
  299.             recordingDuration = 3600 * 1000;
  300.  
  301.             //Repeating
  302.             repeatingEnabled = true;
  303.             recordingRepeat = 12;
  304.             //Max value if set to 0
  305.             if (recordingRepeat == 0) {
  306.                 recordingRepeat = Integer.MAX_VALUE - 1;
  307.             }
  308.  
  309.             recordingFileSize = 35 * 1024 * 1024;
  310.  
  311.             recordingDirectory = new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM + "/Camera");
  312.             recordingDirectory.mkdirs();
  313.  
  314.             Log.v(TAG, "CREATE FOLDER: CHECK");
  315.             if (!recordingDirectory.exists()) {
  316.  
  317.             }
  318.             Log.v(TAG, "FOLDER EXISTS: "+recordingDirectory.exists());
  319. //            Log.v(TAG, "CREATE FOLDER: "+recordingDirectory.mkdirs());
  320.             //Vibration
  321.             vibrationStartRecordingEnabled = true;
  322.             vibrationStartOfEachFileEnabled = true;
  323.             vibrationStopRecordingEnabled = true;
  324.  
  325.         } catch (CameraAccessException e) {
  326.             e.printStackTrace();
  327.             return false;
  328.         }
  329.  
  330.         return true;
  331.     }
  332.  
  333.  
  334.  
  335.     //Message threads
  336.     /**
  337.      * Starts a background thread and its {@link Handler}.
  338.      */
  339.     private void startBackgroundThread() {
  340.         mBackgroundThread = new HandlerThread("CameraBackground");
  341.         mBackgroundThread.start();
  342.         mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
  343.     }
  344.  
  345.     /**
  346.      * Stops the background thread and its {@link Handler}.
  347.      */
  348.     private void stopBackgroundThread() {
  349.         mBackgroundThread.quitSafely();
  350.         try {
  351.             mBackgroundThread.join();
  352.             mBackgroundThread = null;
  353.             mBackgroundHandler = null;
  354.         } catch (InterruptedException e) {
  355.             e.printStackTrace();
  356.         }
  357.     }
  358.  
  359.  
  360.     //SDK version 26 (sdk version 26 and above)
  361.     private void startRecordingSessionV26() {
  362.         prepareMediaRecorderV26();
  363.  
  364.         try {
  365.             captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
  366.         } catch (CameraAccessException e) {
  367.             e.printStackTrace();
  368.             stopRecording();
  369.         }
  370.  
  371.         Surface recorderSurface = mMediaRecorder.getSurface();
  372.         captureRequestBuilder.addTarget(recorderSurface);
  373.  
  374.         if (flashlightEnable)
  375.             captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
  376.  
  377.         captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
  378.  
  379.         //Start recording on configured
  380.         try {
  381.             mCameraDevice.createCaptureSession(Collections.singletonList(recorderSurface), new CameraCaptureSession.StateCallback() {
  382.  
  383.                 @Override
  384.                 public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
  385.                     Log.i(TAG, "onConfigured");
  386.                     try {
  387.                         captureSession = cameraCaptureSession;
  388.                         captureSession.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
  389.  
  390.                         //Start recording
  391.                         mMediaRecorder.start();
  392.  
  393.                         //Update states
  394.                         isRecording = true;
  395.  
  396.                         //Update UI
  397. //                        callbacks.recordingStarted();
  398.  
  399.                     } catch (IllegalStateException | CameraAccessException e) {
  400.                         e.printStackTrace();
  401.                         stopRecording();
  402.                     }
  403.  
  404.                     isSettingUpRecording = false;
  405.                 }
  406.  
  407.                 @Override
  408.                 public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
  409.                     Log.e(TAG, "onConfigureFailed");
  410.                     stopRecording();
  411.                 }
  412.             }, mBackgroundHandler);
  413.         } catch (IllegalStateException | CameraAccessException e) {
  414.             e.printStackTrace();
  415.         }
  416.  
  417.  
  418.     }
  419.  
  420.     private File presetRecordingFile(File directory, int clipNumber, String timeStamp) {
  421.         return new File(directory.getPath() + File.separator + "file_" + timeStamp + "_" + clipNumber + ".mp4");
  422.     }
  423.  
  424.     private void prepareMediaRecorderV26() {
  425.         mMediaRecorder = new MediaRecorder();
  426.  
  427.  
  428.         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
  429.         mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
  430.         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
  431.  
  432.         mMediaRecorder.setVideoEncodingBitRate(10000000);
  433.         mMediaRecorder.setVideoFrameRate(30);
  434.         mMediaRecorder.setVideoSize(cameraResolution.getWidth(), cameraResolution.getHeight());
  435.         Log.i(TAG, "Width:"+ cameraResolution.getWidth()+" Height:"+ cameraResolution.getHeight());
  436.         mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
  437.         mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
  438.  
  439.         // Save location and file
  440.         @SuppressLint("SimpleDateFormat")
  441.         final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
  442.  
  443.         final File outputFile = presetRecordingFile(recordingDirectory, 1, timeStamp);
  444.         mMediaRecorder.setOutputFile(outputFile.getAbsolutePath());
  445.  
  446.         mMediaRecorder.setMaxFileSize(recordingFileSize);
  447.         mMediaRecorder.setMaxDuration(120000);
  448.  
  449.         mMediaRecorder.setOrientationHint(cameraOrientation);
  450.  
  451.  
  452.         //Todo: native max duration leads to MediaServer dying
  453.         //mMediaRecorder.setMaxDuration(recordingDuration);
  454.         //mMediaRecorder.setMaxFileSize(recordingFileSize);
  455.  
  456.         //Listen to file size and other relevant info to continue recording
  457.  
  458.         mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
  459.             int i = 2;
  460.             String startTimeStamp = timeStamp;
  461.             File currentOutputFile = outputFile;
  462.             private String TAG = "MediaRecorder info listener";
  463.  
  464.             @SuppressLint("NewApi")
  465.             @Override
  466.             public void onInfo(MediaRecorder mr, int what, int extra) {
  467.  
  468.                 switch (what) {
  469.                     case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING:
  470.  
  471.                         try {
  472.                             currentOutputFile = presetRecordingFile(recordingDirectory, i, startTimeStamp);
  473.                             mr.setNextOutputFile(currentOutputFile);
  474.                             i++;
  475.                         } catch (IOException e) {
  476.                             e.printStackTrace();
  477.                         }
  478.  
  479.                         Log.i(TAG, "Max file size approaching");
  480.                         break;
  481.  
  482.                     case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:
  483.                         Log.i(TAG, "Max file size reached");
  484.                         stopRecording();
  485.                         break;
  486.  
  487.                     case MediaRecorder.MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED:
  488.                         Log.i(TAG, "OutputFile: " + currentOutputFile);
  489.                         if (vibrationStartRecordingEnabled && vibrationStartOfEachFileEnabled) {
  490.                             vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
  491.                         }
  492.                         break;
  493.                 }
  494.             }
  495.         });
  496.  
  497.         mMediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
  498.             @Override
  499.             public void onError(MediaRecorder mr, int what, int extra) {
  500.  
  501.                 Log.i(TAG, "ERROR: "+ what);
  502.  
  503.                 if (what == MediaRecorder.MEDIA_ERROR_SERVER_DIED) {
  504.                     Log.i(TAG, "MediaRecorder.MEDIA_ERROR_SERVER_DIED");
  505.                     MainActivity.this.stopRecording();
  506.                 }
  507.             }
  508.         });
  509.  
  510.  
  511.         try {
  512.             mMediaRecorder.prepare();
  513.         } catch (IOException e) {
  514.             e.printStackTrace();
  515.         }
  516.  
  517.     }
  518. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement