I am in trouble with this issue, couldn't find any way out yet.
I have configured a Fileprovider in manifest.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
where the #xml/file_paths is like
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="my_images"
path="Android/data/com.package.name/files/Pictures" />
<external-files-path
name="my_images_" />
</paths>
And my java code is like below
private void selectImageFromCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("selectImageFromCamera", "Error: " + ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
try {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.package.name.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CAMERA_PIC_REQUEST);
} catch (Exception e) {
e.printStackTrace();
Log.e("selectImageFromCamera", "Error: " + e);
}
}
}
The method createImageFile()
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
Log.e("storageDir", "storageDir: " + storageDir.getAbsolutePath());
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
myCurrentPhotoPath = image.getAbsolutePath();
return image;
}
But I am always getting problem when creating photoUri, to be exactly at below line.
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"com.package.name.fileprovider",
photoFile);
Error in try catch
.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.package.name/files/Pictures/JPEG_20170417_115925_834197983.jpg
Any help would be appreciated. Thanks.
Related
I need your help.
I'm starting to create an app, and I would save photos, videos, vocal memo etc. like a post/note and everything are part of this post.
These multimedia files, will be saved in a folder, which name is a timestamp. On this way, every post/note is charaterized by the timestamp. The timestamp should update every time when I want to create a new post.
I want to save my files by following this path:
Name_app
Timestamp
Pictures
Pictures1
Pictures2
...
Videos
Video1
...
Below my code.
This is the code which create my Image File (and it look like to work):
private File createImageFile () throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File root = new File(Environment.getExternalStorageDirectory().toString());
File myDir = new File(root + "/Urban_stories_sharing/" + timeStamp + "/Pictures");
if (!myDir.exists()) {
myDir.mkdirs();
}
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
myDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
This is the code which start the activity:
public void goToCamera(View v) {
getCameraPermission();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
isStoragePermissionGranted();
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.andreacarubelli.urbanstoriessharing.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
I think that the problem is on "Uri photoURI = FileProvider.getUriForFile(this,
"com.example.andreacarubelli.urbanstoriessharing.fileprovider",
photoFile);"
This is the code of my path (and I don't know how to change it dynamically like this -> "Urban_stories_sharing/" + timeStamp + "/Pictures"):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images"
path="Urban_stories_sharing/Pictures" />
</paths>
This is my provider in my Android Manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.andreacarubelli.urbanstoriessharing.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
</provider>
Thank you so much.
I am currently trying to create a button the opens the camera app, and saves the picture with a specific name and location.
this is used to create the name/directory
// create a filename for image to be stored into
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String Calib_image_File_Name = "Calibration" + "_" + timeStamp + "STOP";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
Calib_image_File_Name, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
And this is my handler
public void Take_Image_calib(View view)
{
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
// ...
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
The issue i have is that after the "STOP" , it adds a 19 digit number afterwards. i don't know why this is happening, advice?
EDIT:
File provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
This is happening because of the createTempFile in its definition it has this line:
...new File(tmpDirFile, prefix + tempFileRandom.nextInt() + suffix);
which I believe causes the problem. Simply use new File(...):
File image = new File(storageDir, Calib_image_File_Name + ".jpg");
I am calling this method when capturing image from the nought.
private void CallCameraFeature() {
Intent cameraOpeningIntent = new
Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String fileName = EmpConstants.startImgName +
new SimpleDateFormat(EmpConstants.PhotoFileFormat,
Locale.US).format(new Date());
File imgFile = new File(mContext.getFilesDir(), "images");
File outFile = new File(imgFile, fileName + ".jpg");
Uri photoURi = FileProvider.getUriForFile(mContext,
BuildConfig.APPLICATION_ID + ".provider", outFile);
cameraOpeningIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURi);
startActivityForResult(cameraOpeningIntent, REQUEST_IMAGE_CAPTURE);
}
}
I have created xml file in
values -> provider_paths.xml
Storing the image in this path
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths >
<files-path name="my_images" path="images/"/>
<files-path name="my_docs" path="docs/"/>
</paths>
Path defined like this to store image DCIM.
public String getEmpThumbImageDirPath() {
try {
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_
DCIM).toString() + EmpConstants.appDir;
}catch (Exception e) {
Log.d("eEmp/ImgDir", e.toString());
return "";
}
camera is opening and capturing the image but image is not loading. What mistake I have done.
Any help would be appreciated.
04-13 20:05:43.738 30272-30272/com.efftronics.android.eEmployee E/ContentValues: createImageFile: directory was created successfully.
04-13 20:05:43.739 30272-30272/com.efftronics.android.eEmployee E/ContentValues: run: image folder path is: /storage/emulated/0/FolderName/InsideFolderNameIFYOUWant
04-13 20:05:43.739 30272-30272/com.efftronics.android.eEmployee E/ContentValues: createImageFile: image file name is: imageName_1523630143739
04-13 20:05:49.791 30272-30272/com.efftronics.android.eEmployee E/ContentValues: createImageFile: directory already exists.
04-13 20:05:49.792 30272-30272/com.efftronics.android.eEmployee E/ContentValues: run: image folder path is: /storage/emulated/0/FolderName/InsideFolderNameIFYOUWant
04-13 20:05:49.792 30272-30272/com.efftronics.android.eEmployee E/ContentValues: createImageFile: image file name is: imageName_1523630149792
Try this, It works for me:
private void openCamera()
{
try
{
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null)
{
try
{
// Create the File where the photo should go
File photoFile = createImageFile();
// Continue only if the File was successfully created
if (photoFile != null)
{
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CAPTURE_IMAGE_REQUEST_CODE);
}
else
{
Log.e(TAG, "openCamera: image was not captured.");
}
}
catch (Exception ex)
{
// Eor occurred while creating the File
ex.printStackTrace();
}
}
}
catch (Exception e)
{
Log.e(TAG, "openCamera: exception while opening camera:");
e.printStackTrace();
}
}
private String mCurrentPhotoPath;
private File createImageFile()
{
// Create an image file name
File sd = Environment.getExternalStorageDirectory();
File imageFolder = new File(sd.getAbsolutePath() + File.separator +
"FolderName" + File.separator + "InsideFolderNameIFYOUWant");
if (!imageFolder.exists())
{
if (imageFolder.mkdirs())
{
Log.e(TAG, "createImageFile: directory was created successfully.");
}
else
{
Log.e(TAG, "createImageFile: directory was not created.");
}
}
else
{
Log.e(TAG, "createImageFile: directory already exists.");
}
Log.e(TAG, "run: image folder path is: " + imageFolder.getAbsolutePath());
File image = null;
File mediaFile = new File(imageFolder + File.separator );
String imageFileName = "imageName_" + System.currentTimeMillis();
Log.e(TAG, "createImageFile: image file name is: " + imageFileName);
try
{
image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
mediaFile /* directory */);
}
catch (IOException e)
{
Log.e(TAG, "createImageFile: exception occurred while creating image file:\n");
e.printStackTrace();
}
if (image != null)
{
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
else
{
Log.e(TAG, "createImageFile: image was not created.");
return null;
}
}
Add this in your manifest file:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"/>
</provider>
Then create and xml resource directory and add and file_paths xml file and inside that add this:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="PathOfYourFolder" />
</paths>
And in your on activity result method just use the mCurrentPhotoPath to load the image into your image view. Use Picasso to do that.
Edit
My functions now look like this:
p
If uou want to save image in your external storage use Externalstoragepublicdirectory function.
This intent expects the EXTRA_OUTPUT location in Uri format, see https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE. Some devices may understand an absolute file path, but this is not the documented behavior.
You can use getExternalMediaDirs() to avoid many permission restrictions.
I have made some changes to your code:
Add this to you application level in your Manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
Then create file_paths.xml file:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-cache-path name="my_cache" path="." />
<external-path name="my_images" path="Pictures/" />
</paths>
Then in your code:
private static final String FILE_PROVIDER_AUTHORITY = "com.example.android.fileprovider";
private String mTempPhotoPath;
public void takePhoto() {
// Create the capture image intent
Intent imageCapture= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (imageCapture.resolveActivity(getPackageManager()) != null) {
// Create the temporary File where the photo should go
File photoFile = null;
try {
photoFile = createTempImageFile(this);
} catch (IOException ex) {
// Error occurred while creating the File
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
// Get the path of the temporary file
mTempPhotoPath = photoFile.getAbsolutePath();
// Get the content URI for the image file
Uri imageUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
photoFile);
// Add the URI so the camera can store the image
imageCapture.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
}
static File createTempImageFile(Context context) throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = context.getExternalCacheDir();
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
//To save image
String mCurrentPhotoPath = null;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/DCIM/Camera");
Log.d(TAG, "createImageFile: Saving image to:" + storageDir);
File image = new File(storageDir, imageFileName);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
//Return the saved image
return mCurrentPhotoPath ;
}
I am going to take a photo from Camera in Xamarin Android.
Here's what I did in Xamarin.
Start Camera Activity
private void CallTakePictureIntent ()
{
Intent takePictureIntent = new Intent (MediaStore.ActionImageCapture);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.ResolveActivity (PackageManager) != null) {
// Create the File where the photo should go
Java.IO.File photoFile = null;
try {
photoFile = ImageHelper.CreateImageFile (this);
} catch (Exception ex) {
System.Console.WriteLine (ex.ToString ());
}
// Continue only if the File was successfully created
if (photoFile != null) {
sURI photoURI = FileProvider.GetUriForFile (this, UIHelper.FileProvider, photoFile);
requestedAvatarUri = photoURI;
takePictureIntent.PutExtra (MediaStore.ExtraOutput, photoURI);
StartActivityForResult (takePictureIntent, REQUEST_TAKE_PICTURE);
}
}
}
Create temporary file.
public static Java.IO.File CreateImageFile (Context context)
{
// Create an image file name
string timeStamp = DateTime.Now.ToString ("yyyyMMdd_HHmmss");
string imageFileName = "JPEG_" + timeStamp + "_";
Java.IO.File storageDir = context.GetExternalFilesDir (Android.OS.Environment.DirectoryPictures);
Java.IO.File image = Java.IO.File.CreateTempFile (
imageFileName, /* p refix */
".jpg", /* suffix */
storageDir /* directory */
);
return image;
}
Android.Manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.masterbee.xamapp-dev.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
xml/file_paths.xml
<external-path name="external_images" path="Pictures/" />
I think I've done correctly, all things work except runtime exception in FileProvider.GetUriForFile() line.
Here's call trace.
enter image description here