I am opening camera app as external intent from my applications. I am using following code to invoke the camera and following are my conditions:
It should open the front camera.
Highest picture quality.
Flash light has to be on
Following is my code:
Intent action = new Intent("android.media.action.IMAGE_CAPTURE");
action.putExtra("android.intent.extras.CAMERA_FACING", 1);
action.putExtra("android.intent.extras.FLASH_MODE_ON", 1);
action.putExtra("android.intent.extras.QUALITY_HIGH", 1);
Now, it does open the front camera BUT it does not turn on the flash and it does not set the picture quality to high.
My Manifest file's permission section looks like following:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
is there anything that I am missing?
Unfortunately, when using the camera with Intent, the only extra parameter you can set is
MediaStore.EXTRA_OUTPUT
Eg
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
Which allows you to map where the Camera application will store the image.
Camera Facing intent extra can sometimes work:
action.putExtra("android.intent.extras.CAMERA_FACING", 1);
Looking in the android source files, there are some "test" methods that are in the Util class file but not officially documented:
(Util)
private static final String EXTRAS_CAMERA_FACING =
"android.intent.extras.CAMERA_FACING";
// This is for test only. Allow the camera to launch the specific camera.
public static int getCameraFacingIntentExtras(Activity currentActivity) {
int cameraId = -1;
int intentCameraId =
currentActivity.getIntent().getIntExtra(Util.EXTRAS_CAMERA_FACING, -1);
if (isFrontCameraIntent(intentCameraId)) {
// Check if the front camera exist
int frontCameraId = CameraHolder.instance().getFrontCameraId();
if (frontCameraId != -1) {
cameraId = frontCameraId;
}
} else if (isBackCameraIntent(intentCameraId)) {
// Check if the back camera exist
int backCameraId = CameraHolder.instance().getBackCameraId();
if (backCameraId != -1) {
cameraId = backCameraId;
}
}
return cameraId;
}
And in the photomodule, the following method is used:
(PhotoModule)
private int getPreferredCameraId(ComboPreferences preferences) {
int intentCameraId = Util.getCameraFacingIntentExtras(mActivity);
if (intentCameraId != -1) {
// Testing purpose. Launch a specific camera through the intent
// extras.
return intentCameraId;
} else {
return CameraSettings.readPreferredCameraId(preferences);
}
}
And when the camera app initialises the photo mode, it calls this method to check which camera to use:
mCameraId = getPreferredCameraId(mPreferences);
intent.putExtra("android.intent.extras.CAMERA_FACING", android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
this is an intent to start capture with the front camera instead of the default rear camera.
this works as it is used in this popular cordova plugin in this link at line 145 :
https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin/blob/master/src/android/nl/xservices/plugins/videocaptureplus/VideoCapturePlus.java
hope this helps anyone facing the same problem.
also do you know if you can set an intent to disable the camera controls(filters,switch between cameras..etc) , so that they doesn't show ?
Related
I am not able to get GEO Exif infos from picture taken from camera.
This is the code, and the "oldExif" variable does have almost all values NULL (also GEO infos).
The "uri" variable is the uri of the image taken and created.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != AppCompatActivity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE) {
try {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
InputStream in = getContentResolver().openInputStream(uri);
ExifInterface oldExif = new ExifInterface(in);
// oldExif does have almost all values NULL
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
My android version is 5.0 and I already enabled the set of the camera about localization.
Indeed if I get a picture out of my app and show infos, I see geo data.
There is no Intent action that:
Causes a third-party camera app to offer the user to take a picture, and
Forces that camera app to add any particular EXIF tags
Your choices are:
Live without the EXIF tags
Add those tags yourself (e.g., find the user's location and put the geotags in the image), if they are missing
It's may be an old question but I couldn't find any solution for my issue. So asking it again
I am trying to capture an image and store it in internal storage and after usage in my app I am deleting it. It is working fine in all devices but in Samsung Note 3.
private void captureImage() {
try {
if(photoPath!=null) {
new File(photoPath).delete();
photoPath = null;
}
//SET THE IMAGE NAME AND IMAGE PATH FOR THE CURRENT IMAGE
final Random random = new Random();
photoPath = getPath(this)+"/img" + String.valueOf(random.nextInt()) + ".jpg";
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File imageStorage = new File(photoPath);
if (imageStorage != null) {
//to capture full image use URI otherwise use filepath
Uri photoURI = FileProvider.getUriForFile(this, "<<my path>>.fileprovider", imageStorage);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, Constants.ACTION_CAMERA_REQUEST);
}
}
catch (Throwable e) {
}
}
Is anything I am missing here. Please can anybody help me
In Manifeast.xml
<uses-permission android:name="android.permission.CAMERA" />
is mandatory in order to use the camera (I'm not using camera via Intent, I have a customize camera app)
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash"
android:required="false" />
android:required="false" means Google Play will not prevent the application from being installed to devices that do not include these camera features - so the user having a device without camera and camera flash will be able to install the app from market.
http://developer.android.com/reference/android/hardware/Camera.html
Background
Targeting API 24 or above, instead of using a simple "Uri.fromFile" command, developers need to use FileProvider (or their own ContentProvider), in order to let other apps to access the app's files.
The problem
I try to open a camera app to let it save a file into my app's private storage, using this code:
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final File photoFile = FileHelper.generateTempCameraFile(this);
mCameraCachedImageURI = FileProvider.getUriForFile(this, getPackageName()+ ".provider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraCachedImageURI);
takePictureIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(takePictureIntent, REQ_CODE_PICK_IMAGE_FROM_CAMERA);
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
manifest file
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
This starts fine, as the camera app is launched, but in the returned result, I fail to get the orientation of the image file using code that previously worked fine:
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int orientation = getOrientation(this,mCameraCachedImageURI );
...
public static int getOrientation(final Context context, final Uri photoUri) {
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(photoUri,
new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null);
} catch (final Exception ignored) {
}
if (cursor == null) {
// fallback
return getOrientation(photoUri.getPath());
}
int result = 0;
if (cursor.getCount() > 0) {
cursor.moveToFirst();
result = cursor.getInt(0);
}
cursor.close();
return result;
}
public static int getOrientation(final String filePath) {
if (TextUtils.isEmpty(filePath))
return 0;
try {
final ExifInterface exifInterface = new ExifInterface(filePath);
final int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
return rotate;
} catch (final IOException ignored) {
}
return 0;
}
This will crash, because the cursor doesn't have any columns while running this code.
Not only that, but even the fallback function (when changing the code to use it) doesn't work, as it adds an additional part to the path of the file ("external" in this case).
What I've found
It seems that the contentResolver uses the FileProvider here, instead of what was used on previous versions of Android.
Thing is, I need the ContentProvider of this URI in order to grant the camera app permission to access this file...
The question
How do I get the orientation using the above code (or even a better code), using the new FileProvider Uri ? Maybe I can force the ContentResolver to use the previously ContentProvider to get the needed column's data of the cursor?
Do I really have to create my own ContentProvider here?
A Uri is not a file. You are calling getPath() on a Uri and are treating it as if it were a file path. That only works if the scheme in the Uri is file. In your case, it is not.
You already have a File object pointing to the file. It is called photoFile. Hold onto that in a field of your activity, and save it in the saved instance state Bundle (as your process might get terminated while the camera app is in the foreground). Then, use photoFile. Don't use the built-in ExifInterface though, as it has security flaws.
How do I get the orientation using the above code (or even a better code), using the new FileProvider Uri ?
You don't. Use photoFile.
Maybe I can force the ContentResolver to use the previously ContentProvider to get the needed column's data of the cursor?
I have no idea why you would expect the getOrientation() that takes a Uri to work. You are querying the MediaStore for data about a Uri that does not come from the MediaStore.
Do I really have to create my own ContentProvider here?
No, because FileProvider is not your problem. You would have the same flawed getOrientation() methods with your own ContentProvider.
I need to take video from my application using only front camera. I am using intent to perform this action.
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
intent.putExtra("android.intent.extra.durationLimit", 30);
intent.putExtra("android.intent.extras.CAMERA_FACING", 1); //to open front facing camera
startActivityForResult(intent, VIDEO_CAPTURE);
When I run the application, I am able to take video using front camera. But suppose when I click my record video button and the camera view is opened. In that user go and change the camera to rear camera, then always my intent is opening rear camera only after that. Its not taking the line
intent.putExtra("android.intent.extras.CAMERA_FACING", 1);
Could someone please tell me whats the issue and is it able to be solved using intent?
There is no reliable way to use intent to show the front camera all the time at least not on all devices. Only way to reliably do it is to create a SurfaceView and capture the video yourself.
See if this works :
try {
if (Camera.getNumberOfCameras() == 2) {
if (frontCamera) {
frontCamera = false;
prCamera.stopPreview();
prMediaRecorder.release();
prMediaRecorder = null;
prCamera.release();
prCamera = null;
} else {
frontCamera = true;
prCamera.stopPreview();
prMediaRecorder.release();
prMediaRecorder = null;
prCamera.release();
prCamera = null;
}
Intent intent = new Intent(VideoCapture_New.this,
VideoCapture_New.class);
startActivity(intent);
} else {
Toast.makeText(VideoCapture_New.this,
"Your device doesn't contain Front Camera.",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(VideoCapture_New.this,
"Your device is not compatible for Front Camera.",
Toast.LENGTH_SHORT).show();
}
source : Front camera in android
Else you could use Android keyEvents to trigger the button press of camera switch if video starts to record on back camera. KeyEvents need to timed perfectly otherwise they end triggering something else! Check : KeyEvent.
Also if you are making use of
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
This signature for CamcorderProfile.get() defaults to a profile for the back-facing camera.
So instead of using this, use :
public static CamcorderProfile get (int cameraId, int quality)
mediaRecorder.setVideoFrameRate(15);
use any value, 1 - 15 for frame rate.
check this for additional details.
Hope this helps.
Create your custom video taking application that assure to only use the Front camera
i think this is the only way to do this .
Hope that Helps .
i'm trying to create an app that allows video recording. i know that using MediaStore.ACTION_IMAGE_CAPTURE, it actually calls the camera system from my app and after taking the picture, it will return to my app with result.
while using the code, i found a MediaStore.ACTION_VIDEO_CAPTURE. which i assume it will camera but in video mode, rather then image capturing mode.
the code that i used for calling the camera in video mode:
Intent takeVideoFromCameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri mUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "/Record/vid_"+ String.valueOf(System.currentTimeMillis()) + ".mp4"));
takeVideoFromCameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
startActivityForResult(takeVideoFromCameraIntent, RESULT_OK);
when i run the app with a real device, it does call the camera in video mode and also allows video recording. however, when i press the record button to finish recording, it returns to my app with a force close message saying that the camera is not responding.
at 1st, i thought that the video has not been captured, but when i searched for the file, it actually exist.
then, i thought its my onActivityResult method that causes the problem, but after i comment it with /* ... */ , it still have the same problem. but there isn't any details shown in LogCat.
i realize that i got the error because i'm adding extra to it. what i just needed to do is
Intent takeVideoFromCameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(takeVideoFromCameraIntent, 1111);
then, add an onActivityResult, with the request code == 1111 (depends on what you entered) and retrieve the last modified file that consist of the extension ".mp4" from the default folder of camera "DCIM/Camera"
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1111)//cam
{
File folder = new File(Environment.getExternalStorageDirectory(), "/DCIM/Camera");
long folderModi = folder.lastModified();
FilenameFilter filter = new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return (name.endsWith(mp4));
}
};
File[] folderList = folder.listFiles(filter);
String recentName = "";
for(int i=0; i<folderList.length;i++)
{
long fileModi = folderList[i].lastModified();
if(folderModi == fileModi)
{
recentName = folderList[i].getName();
}
}
}
this way, i can get the name of the file and also do the modification (e.g renaming) with it.
hope this would help other people. =)
please,add your logcat.
For the video capture, i am using the MediaRecorder class, I suggest you tu use this.
If you are interested, i can give you the right code.
I think, your problem is resolved by using this code.
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
Use this code in an activity and also set some property in xml file.
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
If you have another problem, please reply me.