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
Related
The image source is a Uri which is stored in Firestore.
If a user saves their profile photo from either camera or album, it gets its Uri then stores as a string in the Firestore. There's no problem until this point.
I'll say the photo taken from Camera as CameraImage, and the photo chosen from the album as AlbumImage.
But when displaying the AlbumImage's Uri(as String) retrieved from Firestore, Security Exception is thrown.
Possible solutions I'm assuming are:
need to save the Uri in a different way.
need to load Uri in a different way.
Loding the image(error on this line):
iv_photo.setImageURI(Uri.parse(mUser.getPhotoString()));
Activity for result:
Intent selectIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
selectIntent.setType("image/*");
galleryResultLauncher.launch(selectIntent);
ActivityResultLauncher<Intent> galleryResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == Activity.RESULT_OK){
Uri selectedImg = result.getData().getData();
iv_photo.setImageURI(selectedImg);
mUri = selectedImg.toString();
}
}
});
Security Exception:
Permission Denial: opening provider com.google.android.apps.photos.contentprovider.impl.MediaContentProvider from ProcessRecord{c7fba1f 23624:com.example.seanlee_thefootballgallery_2201/u0a165} (pid=23624, uid=10165) that is not exported from UID 10118
AlbumImage URIs is similar to this.
content://com.example.seanlee_thefootballgallery_2201/app_images/10-02-2022-09-17-01.jpg
CameraImage URIs is similar to this.
content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F25/ORIGINAL/NONE/image%2Fjpeg/967503137
Manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
you can upload your photo to firebase storage first, you can read this upload file to firebase storage .after that you can add more code like this to get Url from storage
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child()
//that child is up to you
storageReference.putFile(imageUri).addOnCompleteListener(task ->
storageReference.getDownloadUrl().addOnSuccessListener(uri -> {
String url = uri.toString();
}));
after that you can save url into firestore. if you want show it into your app you should get url from firestore first after that download it from firebase storage. for download file you can read this download file from firebase storage
hope it can solve your problem :)
Solved.
Changing intent action from ACTION_PICK to ACTION_OPEN_DOCUMENT solved the issue.
In androidx.activity version 1.2.0-alpha05 API for TakePicture contract has been changed:
The TakePicture contract now returns a boolean indicating success rather than a thumbnail Bitmap as this was very rarely supported by camera apps when writing the image to the provided Uri
While in alpha04 callback received a Bitmap object, now only a Boolean object that describes success is received by the callback.
So now the Uri Parameter of the launch method of the launcher must not be null, but must be the destination where the picture is saved. Did not manage to create an Uri object that is accepted by the launcher and that can be used for my app to read the result picture.
Does anybody have an example for me for a valid Uri object that can be provided to the launcher?
I can't find any example on the internet
Here is an example.
File file = new File(getFilesDir(), "picFromCamera");
Uri uri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", file);
ActivityResultLauncher<Uri> mGetContent = registerForActivityResult(
new ActivityResultContracts.TakePicture(),
new ActivityResultCallback<Boolean>() {
#Override
public void onActivityResult(Boolean result) {
// do what you need with the uri here ...
}
});
mGetContent.launch(uri);
Note1: You are likely to run into FileUriExposedException , need to expose this uri for the camera app to access
Related: android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
Note2: If you have <uses-permission android:name="android.permission.CAMERA" /> declared in your manifest, you need to have permission before launching, otherwise java.lang.SecurityException: Permission Denial
thanks #babyishTank for good answer, after adding following changes works for me
val directory = File(context.filesDir, "camera_images")
if(!directory.exists()){
directory.mkdirs()
}
val file = File(directory,"${Calendar.getInstance().timeInMillis}.png")
Uri uri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", file);
ActivityResultLauncher<Uri> mGetContent = registerForActivityResult(
new ActivityResultContracts.TakePicture(),
new ActivityResultCallback<Boolean>() {
#Override
public void onActivityResult(Boolean result) {
// do what you need with the uri here ...
}
});
mGetContent.launch(uri);
and in filepaths.xml add following code
<files-path
name="images"
path="camera_images/"/>
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 ?
i have a problem with code of take a picture and save. It crash when i launchCamera().
Can you help me please?
private void launchCamera() {
try {
mOutputFile = File.createTempFile("prova", null);
Intent intentCamera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(mOutputFile));
startActivityForResult(intentCamera, CAMERA_REQUEST);
} catch (Exception e) {
Toast t = Toast.makeText(this, "ERROR:\n" + e.toString(), Toast.LENGTH_LONG);
t.show();
}
}
I am using this piece of code try it out :
/**
* This method is used to start the camera activity and save the image taken as the imagename passed
*
* #param imagename : this is the name of the image which will be saved
*/
private void clickPicture(String imagename) {
Intent getCameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
File cameraFolder;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cameraFolder = new File(android.os.Environment.getExternalStorageDirectory(),"myfolder/");
else
cameraFolder= context.getCacheDir();
if(!cameraFolder.exists())
cameraFolder.mkdirs();
String imageFileName = imagename;
File photo = new File(Environment.getExternalStorageDirectory(), "myfolder/" + imageFileName);
getCameraImage.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
Uri.fromFile(photo);
startActivityForResult(getCameraImage, 1);
}
and add the permisson in your manifest file :
<uses-permission android:name="android.permission.CAMERA" ></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Maybe you didn't added the necessary permissions in the manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Also I would suggest you to go over this blog post I wrote on this topic of taking a picture using the build-in Camera Activity:
Take Picture with build in Camera Activity
To access the device camera, you must declare the CAMERA permission in your Android Manifest
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.