See i have permissions for camera.Opening front camera returns null, Even though i have permissions for using camera, searched a lot of answers but nothing helped
This is how i am trying to open front camera
Camera cam = null;
try{
cam = Camera.open(1);
}catch (Exception e){
Log.e("Manojjjj", "Camera failed to open: " + e.getMessage());
e.printStackTrace();
}
return cam;
The code is working fine in android 5,But in android 6,it is returning null for front camera(Back camera is working fine), and when i change the id to 0(cam = Camera.open(0)), it opens back camera without any problem.
Thanks in advance.
the exception is:
09-01 16:52:29.228 24480-24480/com.magostech.dualcamera E/Manojjjj: Camera failed to open: Fail to connect to camera service
Every question that i have searched is saying to add run time permission, but i am already giving run time permission, So i am doing it right, i think my problem is not to add run time permission.
Full Code:
private Camera mCamera = null;
private Camera mCamera1 = null;
private Handler mBackgroundHandler;
private CameraActivity mPreview;
private CameraPreview mPreview1;
FrameLayout preview;
FrameLayout preview1;
private static final int REQUEST_CAMERA_PERMISSION = 1;
public boolean safeToTakePicture = false;
String front,back;
Bitmap bitmap1;
Bitmap bitmap2;
private static final int PERMISSION_CALLBACK_CONSTANT = 100;
private static final int REQUEST_PERMISSION_SETTING = 101;
String[] permissionsRequired = new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private SharedPreferences permissionStatus;
private boolean sentToSettings = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permissionStatus = getSharedPreferences("permissionStatus",MODE_PRIVATE);
checkForPermissions();
// Create an instance of Camera
}
public void checkForPermissions(){
if(ActivityCompat.checkSelfPermission(Main2Activity.this,permissionsRequired[0]) != PackageManager.PERMISSION_GRANTED
||ActivityCompat.checkSelfPermission(Main2Activity.this,permissionsRequired[1]) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[0])
||ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[1])){
AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
builder.setTitle("Need Multiple Permissions");
builder.setMessage("This app needs Camera and Location permissions.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
else if (permissionStatus.getBoolean(permissionsRequired[0],false)) {
//Previously Permission Request was cancelled with 'Dont Ask Again',
// Redirect to Settings after showing Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
builder.setTitle("Need Multiple Permissions");
builder.setMessage("This app needs Camera and Location permissions.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sentToSettings = true;
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getBaseContext(), "Go to Permissions to Grant Camera and Location", Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
//just request the permission
ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
}
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(permissionsRequired[0],true);
editor.commit();
} else {
//You already have the permission, just go ahead.
proceedAfterPermission();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == PERMISSION_CALLBACK_CONSTANT){
//check if all permissions are granted
boolean allgranted = false;
for(int i=0;i<grantResults.length;i++){
if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
allgranted = true;
} else {
allgranted = false;
break;
}
}
if(allgranted){
proceedAfterPermission();
} else if(ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[0])
|| ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[1])
|| ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[2])){
AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
builder.setTitle("Need Multiple Permissions");
builder.setMessage("This app needs Camera and Location permissions.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
Toast.makeText(getBaseContext(),"Unable to get Permission",Toast.LENGTH_LONG).show();
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_PERMISSION_SETTING) {
if (ActivityCompat.checkSelfPermission(Main2Activity.this, permissionsRequired[0]) == PackageManager.PERMISSION_GRANTED) {
//Got Permission
proceedAfterPermission();
}
}
}
private void proceedAfterPermission() {
mCamera = getCameraInstance();
mCamera1 = openFrontFacingCamera();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraActivity(this, mCamera);
mPreview1 = new CameraPreview(this,mCamera1);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview1 =(FrameLayout) findViewById(R.id.camera_preview1);
preview.addView(mPreview);
preview1.addView(mPreview1);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.take_picture);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (safeToTakePicture) {
mCamera.takePicture(null,null,backCamera);
mCamera1.takePicture(null, null, frontCamera);
safeToTakePicture = false;
}
}
});
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(0); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private Camera openFrontFacingCamera(){
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ) {
try {
Log.e("Cam Id",String.valueOf(camIdx));
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
e.printStackTrace();
Log.e("Manoj", "Camera failed to open: " );
}
}
}
return cam;
}
#Override
protected void onPostResume() {
super.onPostResume();
if (sentToSettings) {
if (ActivityCompat.checkSelfPermission(Main2Activity.this, permissionsRequired[0]) == PackageManager.PERMISSION_GRANTED) {
//Got Permission
proceedAfterPermission();
}
}
}
private Camera.PictureCallback frontCamera = new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
camera.startPreview();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Dual Camera");
if (myDir.exists()) {
myDir.delete();
}
myDir.mkdirs();
String fname = "Image" + new Date().getTime() + ".jpg";
File file = new File(myDir, fname);
try{
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
front = String.valueOf(file);
bitmap1 = BitmapFactory.decodeFile(front);
Log.e("Front",front);
if(bitmap1!=null&&bitmap2!=null){
mergeBitmap(bitmap1,bitmap2);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
safeToTakePicture = true;
}
};
public Bitmap mergeBitmap(Bitmap bitmap1, Bitmap bitmap2) {
Bitmap mergedBitmap = null;
int w, h = 0;
h = bitmap1.getHeight() + bitmap2.getHeight();
if (bitmap1.getWidth() > bitmap2.getWidth()) {
w = bitmap1.getWidth();
} else {
w = bitmap2.getWidth();
}
mergedBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mergedBitmap);
canvas.drawBitmap(bitmap1, 0f, 0f, null);
canvas.drawBitmap(bitmap2, 0f, bitmap1.getHeight(), null);
saveBitmap(mergedBitmap);
return mergedBitmap;
}
private Camera.PictureCallback backCamera = new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
camera.startPreview();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Dual Camera");
if (myDir.exists()) {
myDir.delete();
}
myDir.mkdirs();
String fname = "Image" + new Date().getTime() + ".jpg";
File file = new File(myDir, fname);
try{
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
back = String.valueOf(file);
bitmap2 = BitmapFactory.decodeFile(String.valueOf(file));
Log.e("Back",back);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
safeToTakePicture = true;
}
};
private void saveBitmap(Bitmap finalBitmap){
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Dual Camera");
if (myDir.exists()) {
myDir.delete();
}
myDir.mkdirs();
String fname = "Merged" + new Date().getTime() + ".jpg";
File file = new File(myDir, fname);
try{
FileOutputStream fos = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
Toast.makeText(getApplicationContext(),
"Image Saved to:" + file, Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
try {
mCamera = Camera.open(0);
mCamera.setPreviewCallback(null);
mPreview = new CameraActivity(Main2Activity.this, mCamera);
preview.addView(mPreview);
mCamera.startPreview();
}catch (Exception e) {
Log.d("Manoj", "Error starting camera preview: " + e.getMessage());
}try{
if (mCamera1 == null){
mCamera1 = openFrontFacingCamera();
//mCamera1 = Camera.open(1);
mCamera1.setPreviewCallback(null);
mPreview1 = new CameraPreview(Main2Activity.this,mCamera1);
preview1.addView(mPreview1);
mCamera1.startPreview();
}
}catch (Exception e){
Log.d("Manoj", "Error starting camera preview: " + e.getMessage());
}
safeToTakePicture = true;
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
}
#Override
protected void onPause() {
try {
// release the camera immediately on pause event
// releaseCamera();
mCamera1.stopPreview();
mCamera1.setPreviewCallback(null);
mPreview1.getHolder().removeCallback(mPreview1);
mCamera1.release();
mCamera1 = null;
} catch (Exception e) {
e.printStackTrace();
}
try{
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview);
mCamera.release();
mCamera = null;
}catch (Exception e){
e.printStackTrace();
}
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
}
#Override
public void onBackPressed(){
super.onBackPressed();
}
As per the Android Doc, Android app operates in a process sandbox.
For Android 6.0 or above OS, user can not access the additional capabilities not provided by the basic sandbox. You need to request for that PERMISSION first. Here are those critical PERMISSIONS
If the device is running Android 5.1 (API level 22) or lower, or the app's targetSdkVersion is 22 or lower, the system asks the user to grant the permissions at install time and you can access any sensitive tool.
Check the DOC for more detail.
Try this:
if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA}, 5);
}
}
And override the following method using Ctrl + O copying, pasting would might result in an error
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 5) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Now user should be able to use camera
}
else {
// Your app will not have this permission. Turn off all functions
// that require this permission or it will force close like your
// original question
}
}
}
Related
I use CameraX API for handle camera in my application, and I added SeekBar to control zoom camera, but it not working well when I seek to 0 it was zoom out then I seek to 100 it zoom to maximum amount, so what I need to do, zoom 0 - 100 zooming smoothly
Current Preview
CameraActivity.java
public class CameraActivity extends AppCompatActivity {
private Executor executor = Executors.newSingleThreadExecutor();
private int REQUEST_CODE_PERMISSIONS = 1001;
public static final int REQUEST_CAPTURE_IMAGE = 1002;
private final String[] REQUIRED_PERMISSIONS = new String[]{"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE"};
private PreviewView mPreviewView;
private FloatingActionButton captureImage;
private VerticalSeekBar seekBar;
private Camera camera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mPreviewView = findViewById(R.id.camera);
captureImage = findViewById(R.id.capture);
seekBar = findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
camera.getCameraControl().setLinearZoom((float) (progress/100));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
if(allPermissionsGranted()){
startCamera(); //start camera if permission has been granted by user
} else{
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
}
private void startCamera() {
final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(new Runnable() {
#Override
public void run() {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindPreview(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
}
}
}, ContextCompat.getMainExecutor(this));
}
void bindPreview(#NonNull ProcessCameraProvider cameraProvider) {
Preview preview = new Preview.Builder()
.build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.build();
ImageCapture.Builder builder = new ImageCapture.Builder();
//Vendor-Extensions (The CameraX extensions dependency in build.gradle)
HdrImageCaptureExtender hdrImageCaptureExtender = HdrImageCaptureExtender.create(builder);
// Query if extension is available (optional).
if (hdrImageCaptureExtender.isExtensionAvailable(cameraSelector)) {
// Enable the extension if available.
hdrImageCaptureExtender.enableExtension(cameraSelector);
}
final ImageCapture imageCapture = builder
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build();
preview.setSurfaceProvider(mPreviewView.getSurfaceProvider());
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis, imageCapture);
camera.getCameraControl().setZoomRatio(0.1f);
captureImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String path = getIntent().getStringExtra("path");
File file = null;
if(path != null){
file = new File(path, getIntent().getStringExtra("fileName"));
} else {
SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
file = new File(getBatchDirectoryName(), mDateFormat.format(new Date()) + ".jpg");
}
ImageCapture.Metadata metadata = new ImageCapture.Metadata();
if(Session.getLocation() != null) {
metadata.setLocation(Session.getLocation());
}
ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).setMetadata(metadata).build();
File finalFile = file;
imageCapture.takePicture(outputFileOptions, executor, new ImageCapture.OnImageSavedCallback () {
#Override
public void onImageSaved(#NonNull ImageCapture.OutputFileResults outputFileResults) {
Intent intent=new Intent();
intent.putExtra("path", finalFile.getPath());
setResult(RESULT_OK, intent);
finish();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(CameraActivity.this, "Image Saved successfully", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onError(#NonNull ImageCaptureException error) {
error.printStackTrace();
}
});
}
});
}
public String getBatchDirectoryName() {
String app_folder_path = "";
app_folder_path = Environment.getExternalStorageDirectory().toString() + "/images";
File dir = new File(app_folder_path);
if (!dir.exists() && !dir.mkdirs()) {
}
return app_folder_path;
}
private boolean allPermissionsGranted(){
for(String permission : REQUIRED_PERMISSIONS){
if(ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CODE_PERMISSIONS){
if(allPermissionsGranted()){
startCamera();
} else{
Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
this.finish();
}
}
}
}
You are casting the value incorrectly. So instead:
camera.getCameraControl().setLinearZoom((float) (progress/100));
do:
camera.getCameraControl().setLinearZoom((float) progress/seekBar.getMax());
I am trying to record calls on Android 8+ but getting error. Below is my code:
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/" + RECORDING_DIRECTORY);
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = getRecordingFileName() + "-";
//String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
recordstarted = true;
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d(e);
} catch (IOException e) {
e.printStackTrace();
Log.d(e);
} catch (Exception ex) {
Log.d(ex);
}
I get the following error message:
2020-02-20 16:38:37.893 12635-12635/com.companyname.appname
W/System.err: java.lang.IllegalStateException: phoneIsInUse
2020-02-20 16:38:37.894 12635-12635/com.companyname.appname
W/System.err: at
android.media.MediaRecorder.start(MediaRecorder.java:1017)
Has anyone dealt with this or knows what is happening?
For recording Phone Calls on Android 8+.
API level 28 or higher, apps running in the background cannot access the microphone.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
The example activity below shows how to use MediaRecorder to record an audio file. It Also uses MediaPlayer to play the audio back.
public class AudioRecordTest extends AppCompatActivity {
private static final String LOG_TAG = "AudioRecordTest";
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
private static String fileName = null;
private RecordButton recordButton = null;
private MediaRecorder recorder = null;
private PlayButton playButton = null;
private MediaPlayer player = null;
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false;
private String [] permissions = {Manifest.permission.RECORD_AUDIO};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted ) finish();
}
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording();
}
}
private void onPlay(boolean start) {
if (start) {
startPlaying();
} else {
stopPlaying();
}
}
private void startPlaying() {
player = new MediaPlayer();
try {
player.setDataSource(fileName);
player.prepare();
player.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
private void stopPlaying() {
player.release();
player = null;
}
private void startRecording() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
recorder.start();
}
private void stopRecording() {
recorder.stop();
recorder.release();
recorder = null;
}
class RecordButton extends Button {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
class PlayButton extends Button {
boolean mStartPlaying = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying);
if (mStartPlaying) {
setText("Stop playing");
} else {
setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
};
public PlayButton(Context ctx) {
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Record to the external cache directory for visibility
fileName = getExternalCacheDir().getAbsolutePath();
fileName += "/audiorecordtest.3gp";
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
LinearLayout ll = new LinearLayout(this);
recordButton = new RecordButton(this);
ll.addView(recordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
playButton = new PlayButton(this);
ll.addView(playButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
#Override
public void onStop() {
super.onStop();
if (recorder != null) {
recorder.release();
recorder = null;
}
if (player != null) {
player.release();
player = null;
}
}
}
Make changes according to your project
this code referred from official website for more details follow official website
MediaRecorder overview
am writing a body measurement app. I have been able to create the camera and it stores the image. I want to use the captured image in another activity where i called the method 'bodyMeasurement'
I really need help in achieving this. Further corrections are also welcomed. Thanks
Here is my Camera Activity;
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
cameraDevice = camera;
createCameraPreview();
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
cameraDevice=null;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = (TextureView)findViewById(R.id.textureView);
//From Java 1.4 , you can use keyword 'assert' to check expression true or false
assert textureView != null;
textureView.setSurfaceTextureListener(textureListener);
btnCapture = (ImageButton)findViewById(R.id.btnCapture);
/* Dexter.withActivity(this)
.withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (!report.areAllPermissionsGranted()) {
Toast.makeText(MainActivity.this, "You need to grant all permission to use this app features", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
}
})
.check();*/
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePicture();
}
});
}
private void takePicture() {
if(cameraDevice == null)
return;
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try{
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if(characteristics != null)
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
.getOutputSizes(ImageFormat.JPEG);
//Capture image with custom size
int width = 4608;
int height = 3456;
if(jpegSizes != null && jpegSizes.length > 0)
{
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
final ImageReader reader = ImageReader.newInstance(width,height,ImageFormat.JPEG,1);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
//Check orientation base on device
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
file = new File(Environment.getExternalStorageDirectory()+"/"+ ".CnatraSamp"+".jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try{
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if(image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try{
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
}finally {
if(outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(MainActivity.this, "Saved "+file, Toast.LENGTH_SHORT).show();
finish();
Intent i = new Intent(MainActivity.this,BlankActivity.class);
startActivity(i);
finish();
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
try{
cameraCaptureSession.capture(captureBuilder.build(),captureListener,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
}
},mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCameraPreview() {
try{
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
if(cameraDevice == null)
return;
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Changed", Toast.LENGTH_SHORT).show();
}
},null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
if(cameraDevice == null)
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE,CaptureRequest.CONTROL_MODE_AUTO);
try{
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(),null,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
try{
cameraId = manager.getCameraIdList()[1];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[1];
//Check realtime permission if run higher API 23
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId,stateCallback,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
openCamera();
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if(requestCode == REQUEST_CAMERA_PERMISSION)
{
if(grantResults[0] != PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "You can't use camera without permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if(textureView.isAvailable())
openCamera();
else
textureView.setSurfaceTextureListener(textureListener);
}
#Override
protected void onPause() {
stopBackgroundThread();
super.onPause();
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try{
mBackgroundThread.join();
mBackgroundThread= null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("Camera Background");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
the activity i need the image;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blank);
height = findViewById(R.id.height);
cancel = findViewById(R.id.cancel);
btnctn = findViewById(R.id.continuebtn);
cmIn = findViewById(R.id.cmIn);
height.setInputType(InputType.TYPE_CLASS_NUMBER |
InputType.TYPE_NUMBER_FLAG_DECIMAL |
InputType.TYPE_NUMBER_FLAG_SIGNED);
btnctn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (height.getText().toString().trim().isEmpty()){
Toast.makeText(BlankActivity.this,"Please input your height..",Toast.LENGTH_LONG).show();
}else {
final ProgressDialog progressDialog = new ProgressDialog(BlankActivity.this);
progressDialog.setMessage("Getting Your Measurement");
progressDialog.setTitle("Please wait!");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show(); // Display Progress Dialog
progressDialog.setCancelable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(BlankActivity.this, SettingsActivity.class);
startActivity(i);
progressDialog.dismiss();
}
},5000);
}
//place measurement object
bodyMeasurement();
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BlankActivity.this.finish();
Intent i = new Intent(BlankActivity.this, HomeActivity.class);
startActivity(i);
finish();
}
});
cmIn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
num = Double.parseDouble(String.valueOf(height.getText()));
in = 0.3937 * num;
String r = String.valueOf(in);
height.setText(r);
}else {
num = Double.parseDouble(String.valueOf(height.getText()));
cm = num / 0.3937;
String r = String.valueOf(cm);
height.setText(r);
}
}
});
}
private void bodyMeasurement() {
}
}
As mentioned in the comment, you can get the absolute path from the saved image and pass it through an intent to the Activity that it needs it.
To achieve this, you might want to convert your image file to a BitMap first, which will give you the actual path of the image (sometimes .getAbsolutePath() method returns a wrong file path, so it is a better solution to convert your image to a bitmap first).
This can be achieved:
String filePath = file.getPath();
Bitmap imgBitmap = BitmapFactory.decodeFile(filePath);
Then to obtain the real path of the image you saved you need to
1) Obtain the Uri of the created Bitmap:
public Uri getUri(Context context, Bitmap imgBitmap) {
ByteArrayOutputStream bOutputStream = new ByteArrayOutputStream();
String path = MediaStore.Images.Media.insertImage(context.getContentResolver(),
imgBitmap, "Title", null);
return Uri.parse(path);
}
2) Fetch the real path from Uri:
public String getRealPath(Uri uri) {
String [] proj={MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
cursor.close();
return path;
}
In your first activity you can pass the path of your image through an intent to the other activity, then fetch it and display it/etc.
Intent intent = new Intent(context,OtherActivity.class);
intent.putExtra("PATH",path);
startActivity(intent);
Receive the data you passed:
Intent intent = getIntent();
String path = intent.getStringExtra("PATH");
//convert the path to image/bitmap and display the image
You can also pass the entire Bitmap to the Activity you need it, but I strongly recommend that you don't, because it will use a lot of memory.
I've been trying for hours now, still can't seem to get this to work..
Using this as reference. I coded an application that records and saves a video. I have no problems running the reference application but many issues occurred when i ran my own application.
Issue:
The application have no issues recording video, saving the video, etc. However after recording and saving the first video, if i try to record a second video it crashes. The second error is supposedly caused by MediaRecorder: prepare failed: -2147483648, which in turned caused a IllegalStateException.(Log below) How do I go about solving this issue?
Manifest Permissions:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-feature android:name="android.hardware.camera2.full" />
Code:
public class VideoCapture extends AppCompatActivity {
static final int REQUEST_CODE_CAMERA = 0;
static final int REQUEST_CODE_EXTERNAL_WRITE = 1;
static final int REQUEST_CODE_MICROPHONE = 2;
static SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
static class CompareSizeByArea implements Comparator<Size> {
#Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) (lhs.getWidth() * lhs.getHeight()) - (long) (rhs.getWidth() * rhs.getHeight()));
}
}
File videoFolder;
File videoFile;
ImageButton recordButton;
Chronometer chronometer;
String cameraID;
MediaRecorder mediaRecorder;
Size previewSize;
Size videoSize;
int totalRotation;
boolean isRecording;
HandlerThread backgroundHandlerThread;
Handler backgroundHandler;
CaptureRequest.Builder captureRequestBuilder;
CameraCaptureSession previewCaptureSession;
CameraCaptureSession recordCaptureSession;
TextureView textureView;
TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
startCamera();
Log.e("onSurfaceTextureAvail", "startCamera width:"+String.valueOf(width)+" height" +String.valueOf(height));
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.e("onSurfaceTextureDestroy","Surface destroyed" + String.valueOf(surface));
return false;
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.e("onSurfaceTextureSizeCha","Surface changed" + String.valueOf(surface) +"width" +String.valueOf(width)+" height" +String.valueOf(height));
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
CameraDevice cameraDevice;
CameraDevice.StateCallback cameraDeviceStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(CameraDevice camera) {
cameraDevice = camera;
mediaRecorder = new MediaRecorder();
Log.e("cameraDeviceStateCalbac","onOpened mediaRecorder = new MediaRecorder(); camera:"+String.valueOf(camera));
/**
* Application will "Reset" when granting write storage permission and call onPause and onResume.
* The check is to ensure that the camera will correctly follow up with start record.
**/
Log.e("cameraDeviceStateCalbac", "onOpened calling startPreview");
startPreview();
}
#Override
public void onDisconnected(CameraDevice camera) {
Log.e("cameraDeviceStateCalbac", "onDisconnected closing camera" + String.valueOf(camera));
camera.close();
cameraDevice = null;
Log.e("cameraDeviceStateCalbac", "onDisconnected nulling camera to value:" + String.valueOf(cameraDevice));
}
#Override
public void onError(CameraDevice camera, int error) {
Log.e("cameraDeviceStateCalbac", "onError closing camera" + String.valueOf(camera)+"Error value: "+String.valueOf(error));
camera.close();
cameraDevice = null;
Log.e("cameraDeviceStateCalbac", "onError nulling camera to value:" + String.valueOf(cameraDevice));
}
};
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
finish();
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videocapture);
Log.e("onCreate", "Running");
if (checkCameraPermission() != PackageManager.PERMISSION_GRANTED) requestCameraPermission();
if (checkWriteExternalStoragePermission() != PackageManager.PERMISSION_GRANTED)
requestWriteExternalStoragePermission();
if (checkMicrophonePermission() != PackageManager.PERMISSION_GRANTED)
requestMicrophonePermission();
Log.e("onCreate", "Calling createVideoFolder");
createVideoFolder();
isRecording = false;
Log.e("onCreate", "setting isRecording Value" + String.valueOf(isRecording));
// Chronometer is the timer during a video recording
chronometer = (Chronometer) findViewById(R.id.chronometer);
// TextureView is the container that displays the preview
textureView = (TextureView) findViewById(R.id.textureView);
// Set up video capture click handler
recordButton = (ImageButton) findViewById(R.id.recordButton);
Log.e("onCreate", "recordButton setOnClickListener");
recordButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) // Record/Stop button click
{
Log.e("recordOnClick","RUNNING");
if (!isRecording) // Start Recording
{
Log.e("recordOnClick","isRecording = false");
if (checkCameraPermission() == PackageManager.PERMISSION_GRANTED &&
checkWriteExternalStoragePermission() == PackageManager.PERMISSION_GRANTED) {
try {
isRecording = true;
Log.e("recordOnClick"," set isRecording = true. Final value: "+String.valueOf(isRecording));
recordButton.setImageResource(R.mipmap.btn_video_busy);
Log.e("recordOnClick", "Calling createVideoFile()");
createVideoFile();
Log.e("recordOnClick", "Calling startRecord()");
startRecord();
Log.e("recordOnClick", "Calling mediaRecorder.start()");
mediaRecorder.start();
Log.e("recordOnClick", "If you see this, mediaRecorder.start() passed.");
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setVisibility(View.VISIBLE);
chronometer.start();
} catch (IllegalArgumentException iaEx) {
Log.e("recordOnClick","click to record failed.");
StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
iaEx.printStackTrace(printWriter);
printWriter.flush();
String stackTrace = writer.toString();
Toast.makeText(getApplicationContext(), stackTrace, Toast.LENGTH_LONG).show();
} catch (IOException ex) {
Log.e("recordOnClick","click to record failed.");
}
}
} else // Stop recording
{
Log.e("recordOnClick","isRecording = true");
isRecording = false;
Log.e("recordOnClick"," set isRecording = false. Final value: "+String.valueOf(isRecording));
chronometer.stop();
chronometer.setVisibility(View.INVISIBLE);
recordButton.setImageResource(R.mipmap.btn_video_online);
Log.e("recordOnClick","Calling mediaRecorder.stop()");
mediaRecorder.stop();
Log.e("recordOnClick", "If you see this, mediaRecorder.stop() passed.");
Log.e("recordOnClick","Calling mediaRecorder.reset()");
mediaRecorder.reset();
Log.e("recordOnClick", "If you see this, mediaRecorder.reset() passed.");
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(videoFile));
sendBroadcast(mediaStoreUpdateIntent);
Log.e("recordOnClick","Calling startPreview()");
startPreview();
Log.e("recordOnClick", "If you see this, startPreview() passed.");
Intent intent = new Intent(VideoCapture.this, FrameExtraction.class);
intent.putExtra("videoUri", Uri.fromFile(videoFile));
Log.e("recordOnClick","Video Uri Saved" + String.valueOf(Uri.fromFile(videoFile)));
startActivity(intent);
finish();
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_CAMERA)
{
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Application will not be able to capture videos without camera permission.", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == REQUEST_CODE_EXTERNAL_WRITE)
{
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Application doesn't have write permission. Videos cannot be saved.", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == REQUEST_CODE_MICROPHONE) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Application doesn't have microphone permission. Videos will have no audio.", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if (textureView.isAvailable()) {
setupCamera(textureView.getWidth(), textureView.getHeight());
startCamera();
Log.e("RESUME", "RESUME STARTCAMERA");
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener);
Log.e("RESUME", "ELSE, SET TEXTURE LISTENER");
}
}
#Override
protected void onPause() {
Log.e("PAUSE", "PAUSE CloseCAMERA");
cameraDevice.close();
cameraDevice = null;
stopBackgroundThread();
super.onPause();
}
#Override
public void onWindowFocusChanged(boolean hasFocas) {
super.onWindowFocusChanged(hasFocas);
View decorView = getWindow().getDecorView();
if (hasFocas) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
Log.e("setupCamera","RUNNING");
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
identification number
for (String currentCameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(currentCameraId);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT)
continue;
int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
totalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
boolean swapRotation = totalRotation == 90 || totalRotation == 270;
int rotatedWidth = width;
int rotatedHeight = height;
if (swapRotation) {
rotatedWidth = height;
rotatedHeight = width;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
videoSize = chooseOptimalSize(map.getOutputSizes(MediaRecorder.class), rotatedWidth, rotatedHeight);
cameraID = currentCameraId;
return;
}
} catch (CameraAccessException e) {
}
}
private int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation) {
int sensorOrienatation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
deviceOrientation = ORIENTATIONS.get(deviceOrientation);
return (sensorOrienatation + deviceOrientation + 360) % 360;
}
private Size chooseOptimalSize(Size[] choices, int width, int height) {
List<Size> bigEnough = new ArrayList<>();
for (Size option : choices) {
if (option.getHeight() == option.getWidth() * height / width && option.getWidth() >= width && option.getHeight() >= height) {
bigEnough.add(option);
}
}
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizeByArea());
} else {
return choices[0];
}
}
private void startCamera() {
Log.e("startCamera()","RUNNING");
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkCameraPermission() == PackageManager.PERMISSION_GRANTED)
cameraManager.openCamera(cameraID, cameraDeviceStateCallback, backgroundHandler);
else {
requestCameraPermission();
}
} else
cameraManager.openCamera(cameraID, cameraDeviceStateCallback, backgroundHandler);
} catch (CameraAccessException e) {
Log.e("startCamera()", "Failed to cameraManager.openCamera" + String.valueOf(e));
}
}
private void startPreview() {
Log.e("startPreview","RUNNING");
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(previewSurface);
cameraDevice.createCaptureSession(Arrays.asList(previewSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
previewCaptureSession = session;
try {
previewCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
Log.e("startPreview", "onConfigureFailed");
}
}, null);
} catch (CameraAccessException e) {
Log.e("startPreviewCATCH", "StartPreview FAILED CATCH: " + String.valueOf(e));
}
}
private void startRecord() {
try {
Log.e("startRecord", "RUNNING");
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
mediaRecorder.setVideoEncodingBitRate(1000000);
mediaRecorder.setVideoFrameRate(60);
mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setOrientationHint(totalRotation);
}catch(Exception e){
}
try {
mediaRecorder.prepare();
Log.e("startRecord","mediaRecorder.prepare()");
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
Surface recordSurface = mediaRecorder.getSurface();
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
captureRequestBuilder.addTarget(previewSurface);
captureRequestBuilder.addTarget(recordSurface);
cameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface),
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(CameraCaptureSession session) {
recordCaptureSession = session;
try {
recordCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
}
}
#Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, null);
} catch (IOException ioEx) {
Log.e("prepare Failed", String.valueOf(ioEx));
} // mediaRecorder.prepare()
catch (CameraAccessException caEx) {
} // cameraDevice.createCaptureSession()
}
private void closeCamera() {
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
if (mediaRecorder != null) {
mediaRecorder.reset();
Log.e("closeCamera()","mediaRecorder.reset()");
mediaRecorder = null;
Log.e("closeCamera()","mediaRecorder = null");
}
}
private int checkCameraPermission() {
return ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
}
private int checkWriteExternalStoragePermission() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
private int checkMicrophonePermission() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
}
private void requestCameraPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA);
}
private void requestWriteExternalStoragePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_EXTERNAL_WRITE);
}
private void requestMicrophonePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CODE_MICROPHONE);
}
private void createVideoFolder() {
// Create the folder for video files to be written to if it doesn't exist.
// Battery Videos is the folder name created under the movies public directory.
Log.e("createVideoFolder", "RUNNING");
videoFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "Battery Videos");
if (!videoFolder.exists()) videoFolder.mkdirs();
}
private File createVideoFile() throws IOException {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = "Video_" + timestamp + ".mp4";
videoFile = new File(videoFolder, fileName);
return videoFile;
}
private void startBackgroundThread() {
backgroundHandlerThread = new HandlerThread("Camera2VideoImage");
backgroundHandlerThread.start();
backgroundHandler = new Handler(backgroundHandlerThread.getLooper());
}
private void stopBackgroundThread() {
backgroundHandlerThread.quitSafely();
try {
backgroundHandlerThread.join();
backgroundHandlerThread = null;
backgroundHandler = null;
} catch (InterruptedException e) {
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e("onDestroy", "It Happened");
mediaRecorder.release();
}
}
Stack Trace in startRecord():
W/System.err: java.io.IOException: prepare failed.
W/System.err: at android.media.MediaRecorder._prepare(Native Method)
W/System.err: at android.media.MediaRecorder.prepare(MediaRecorder.java:782)
W/System.err: at com.application.batterysoc.activity.VideoCapture.startRecord(VideoCapture.java:490)
W/System.err: at com.application.batterysoc.activity.VideoCapture.access$600(VideoCapture.java:55)
W/System.err: at com.application.batterysoc.activity.VideoCapture$3.onClick(VideoCapture.java:214)
W/System.err: at android.view.View.performClick(View.java:4861)
W/System.err: at android.view.View$PerformClick.run(View.java:19980)
W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:211)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5373)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
E/recordOnClick: Calling mediaRecorder.start()
I've solved the issue, with reference from this site
by removing the line mediaRecorder.setVideoFrameRate(60);
The application now runs without any issues.
I have modified a simple camera application. Basically it will ask the user to type in their preferred "album name' at the beginning. Right now I'm currently stuck on how to validate if a folder with the same name exist. What I'm trying to do is to restrict the user from creating a folder with same folder/directory name, and I was hoping someone could please help me out. Thanks again,
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static String folderValue;
private Camera mCamera;
public static final String TAG = "CamActivity";
private boolean isFilterOpen = false;
private ImageView filterButton;
private boolean isSaving = false; //onClick, onTakePicture
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Dialog Box Part
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Welcome to BloCC!");
builder.setMessage("Please Enter Session Name");
final EditText userInput = new EditText(MainActivity.this);
builder.setView(userInput);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
folderValue = userInput.getText().toString();
}
})
.setCancelable(false)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MainActivity.this, MainMenu.class);
startActivity(intent);
}
});
builder.show();
// Create an instance of Camera
mCamera = getCameraInstance(); //checks for null //titosaw2
// Create our Preview view and set it as the content of our activity.
CameraPreview mPreview = new CameraPreview(this, mCamera); //check for conflicts onResume
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
if (preview != null) {
preview.addView(mPreview);
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.setColorEffect(Camera.Parameters.EFFECT_MONO);
mCamera.setParameters(parameters);
ImageView captureButton = (ImageView) findViewById(R.id.button_capture);
if (captureButton != null) {
captureButton.setOnClickListener(this);
}
}
/**
* A safe way to get an instance of the Camera object.
*/
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) { //check View v
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
MediaScannerConnection.scanFile(MainActivity.this,
new String[]{pictureFile.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
mCamera.startPreview();
Toast.makeText(getApplicationContext(), "Photo Taken", Toast.LENGTH_SHORT).show();
isSaving = false;
}
};
private static File getOutputMediaFile() {
//new folder or check for existing
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderValue);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getAbsolutePath() + File.separator +
"IMG_" + timeStamp + ".jpg");
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_capture:
if (isSaving == false) {
mCamera.takePicture(null, null, mPicture); //onPictureTaken
isSaving = true;
} else {
//stillsaving
}
break; //check for instance
}
}
#Override
protected void onPause() {
super.onPause();
//releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
#Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
setContentView(R.layout.activity_main);
mCamera = getCameraInstance();
CameraPreview mPreview = new CameraPreview(this, mCamera); //check for conflicts onResume
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); //check
preview.addView(mPreview); //check for null
Camera.Parameters parameters = mCamera.getParameters();
parameters.setColorEffect(Camera.Parameters.EFFECT_MONO);
mCamera.setParameters(parameters);
//copied from onCreate
ImageView captureButton = (ImageView) findViewById(R.id.button_capture);
if (captureButton != null) {
captureButton.setOnClickListener(this);
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid()); //test see manifest //fixed
}
}