I get this error: failed to find configured root that contains /storage/emulated/0/android/data/
There are some similar questions but they are using other location for storing files.
I am using:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) method and this is the code I'm using to open camera:
private void TakePicture() {
photoFile = FileManager.generateFileStampedPhotoFile();
PicturesHelper.TryTakePictureWithAnIntent(this, photoFile, REQUEST_IMAGE_CAPTURE);
}
public static File generateFileStampedPhotoFile()
{
Uri photoFileUri=null;
File photoFile=null;
File outputDir=getPhotoDirectory();
if(outputDir!=null)
{
String timeStamp=new SimpleDateFormat("yyyyMMDD_HHmmss").format(new Date());
String photoFileName="IMG_"+timeStamp+".jpg";
photoFile=new File(outputDir,photoFileName);
// photoFileUri=Uri.fromFile(photoFile);
}
return photoFile;
}
public static void TryTakePictureWithAnIntent(Activity context,File
photoFile,int requestCode)
{
Intent takePictureIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(takePictureIntent.resolveActivity(context.getPackageManager())!=null) //if user has camera?
{
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(context,
"com.myapp.fileprovider",
photoFile);
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
context.startActivityForResult(takePictureIntent, requestCode);
}
}
}
public static File getPhotoDirectory()
{
File outputDir=null;
String externalStorageState=Environment.getExternalStorageState();
if(externalStorageState.equals(Environment.MEDIA_MOUNTED)) {
File pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
outputDir=new File(new File(pictureDir,"Adriagate"),"Online");
if(!outputDir.exists())//V.P. if directory/ies not exist/s it will be created. mksdrs method follows file structure and creates directory by direcory if needed
{
if(!outputDir.mkdirs())
{
return null;
}
}
}
return outputDir;
}
I have put provider inside AndroidManifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
And this is file_paths.xml file:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files name="Whatever_Nothing_Works"/>
You are storing your images in Environment.getExternalStoragePublicDirectory(). That is not one of the supported roots for FileProvider. Plus, your XML has <external-files>, and that is not a supported element for FileProvider (valid ones all end in -path).
Options include:
Changing the location of where you are storing the images to one of the locations supported by FileProvider and adjusting your XML to match
Switching to my StreamProvider and using <external-public-path dir="Pictures">
Changing your XML to <external-path name="whatever" path="Pictures"> and hope for the best
Add this in Menifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Replace in file_paths.xml with
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
Your file is stored under getExternalFilesDir(). That maps to <external-files-path>, not <files-path>
Related
This question already has answers here:
how to fix an authority error in android studio
(2 answers)
Couldn't find meta-data for provider with authority
(16 answers)
Closed 3 years ago.
I am trying to develop an app that takes photos, and later that uploads them to a database. Right now I am stucked at taking a good quality photo. As I read before, to get a better quality photo you need to save it in your directories. I am following the Google Take Photos
from developers instructions, and after adding all the methods and provider and so on, I get the error :
Couldn't find meta-data for provider with authority com.example.navigationdrawerfinal.
I've left the name of my app so everyone can see that I changed it in manifest too.
Manifest:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.navigationdrawerfinal.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
file_paths.xml :
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.navigationdrawerfinal/files/Pictures" />
</paths>
and the code where I use it:
private void dispatchTakePictureIntent() {
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.navigationdrawerfinal",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
poza_neincarcata.setVisibility(View.GONE);
poza_tick.setVisibility(View.VISIBLE);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
As indicated by the error (emphasis is mine):
Couldn't find meta-data for provider with authority com.example.navigationdrawerfinal.
This is because you've specified the incorrect FileProvider needed for the photoURI variable you've defined - it should exactly be the same as the FileProvider you've defined in your manifest file, case-sensitive:
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.navigationdrawerfinal.fileprovider", // Over here
photoFile);
By the way, it's a good idea to follow the Java guidelines by naming your classes in PascalCase format.
For e.g.:
FileProvider vs fileprovider
MainActivity vs mainActivity
etc.
in our manifest change like this
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
I'm trying to share file from remote location, but I'm getting the following exception:
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/31AB-1310/Android/data/com.example.myapp/cache/EasyImage/a9c926ea-4dce-44b7-94e9-a5dca6b91a5d-450242437.jpg
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
at pl.aprilapps.easyphotopicker.EasyImage.createCameraPictureFile(EasyImage.java:54)
at pl.aprilapps.easyphotopicker.EasyImage.createChooserIntent(EasyImage.java:109)
My FileProvider code has the following manifest entry:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
</provider>
My res/xml/filpaths.xml file:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files" path="." />
</paths>
My Activity.java file :
private void shareCurrentData(String filepath) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
ArrayList<Uri> files = new ArrayList<Uri>();
if (intent.resolveActivity(getPackageManager()) != null) {
try {
File shareFile= new File(filepath);
Uri shareUri =FileProvider.getUriForFile(this, AUTHORITY,shareFile);
//files.add(textUri);
files.add(shareUri);
} catch (Exception ex) {
System.out.println(ex);
}
intent.putExtra(Intent.EXTRA_STREAM, files);
startActivity(Intent.createChooser(intent,"Share using....."));
}
}
I just cant understand what raises the exception because everything seems to fit.
/storage/31AB-1310/Android/data/com.example.myapp/cache/EasyImage/a9c926ea-4dce-44b7-94e9-a5dca6b91a5d-450242437.jpg
A path like that usually comes from removable storage. FileProvider does not support removable storage.
So, focus on ensuring that filepath is on external storage, not removable storage.
I am capturing images from android application and saving images in external storage using Fileprovider. But it is giving me an exception as follow
java.lang.IllegalArgumentException:
Failed to find configured root that contains /data/data/com.rocketstove/files/SAMS/JMC-R-1256655/application_form_first.jpg
I have configured provider in androidManifest like this
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
I have also add following line in file_paths
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
</paths>
In java code
if (Build.VERSION.SDK_INT >= 23) {
File imagePath = new File(getActivity().getFilesDir(), "SAMS");
if (!imagePath.exists()) {
imagePath.mkdir();
}
imagePath = new File(getActivity().getFilesDir() + "/SAMS", rocketId);
if (!imagePath.exists()) {
imagePath.mkdir();
}
File imageFile = new File(imagePath.getPath(), filename);
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String authority = getActivity().getApplicationContext().getPackageName() + ".fileprovider";
Uri uri = FileProvider.getUriForFile(getActivity(), authority, imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivity(intent);
}
Edit
file_paths
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="external_files" path="Android/data/com.rocketstove.files/"/>
</paths>
Java code
if (Build.VERSION.SDK_INT >= 23) {
File file
=getActivity().getExternalFilesDir(null);
File imagePath = new File(file , rocketId);
if (!imagePath.exists()) {
imagePath.mkdir();
}
File imageFile = new File(imagePath.getPath(), filename);
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
String authority = getActivity().getApplicationContext().getPackageName() + ".fileprovider";
Uri uri = FileProvider.getUriForFile(getActivity(), authority, imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivity(intent);
}
Error
ava.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.rocketstove/files/JMC-R-4555555/application_form_first.jpg
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:719)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:404)
I have also add following line in file_paths
You have external-path. The documentation states that this:
Represents files in the root of the external storage area. The root path of this subdirectory is the same as the value returned by Environment.getExternalStorageDirectory().
That is not where your File points to.
Change external-path to files-path, since your Java code uses getFilesDir().
I'm struggling with FileProvider. Even following this Google documentation and this post that is pretty much the same as my problem.
So I'm trying to open a pdf file from external storage. The directory is "Download/nst". I provided the path in file_paths.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="br.com.myapp.bomapp"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"/>
</provider>
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="Download" path="Download/" />
</paths>
This is how I get pdf path:
private File getPdfFile(long workOrderId){
File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS+"/nst/"+workOrderId);
String[] filesNames = downloads.list(
new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return name.endsWith(".pdf");
}
}
);
if(filesNames.length > 0){
return new File(downloads, filesNames[0]);
}
return null;
}
And this is how I open pdf:
File pdf = getPdfFile(workOrder.getId());
if(pdf == null){
view.showError(context.getString(R.string.error_no_pdf_found));
return;
}
Intent target = new Intent(Intent.ACTION_VIEW);
Uri fileUri;
if(Build.VERSION.SDK_INT >= 24){
fileUri = FileProvider.getUriForFile(context, "br.com.myapp.bomapp", pdf);
target.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
else{
fileUri = Uri.fromFile(pdf);
}
target.setDataAndType(fileUri,"application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(target, "Open File");
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
view.showError(context.getString(R.string.error_no_pdf_reader_found));
}
Notice I'm using Intent.FLAG_GRANT_READ_URI_PERMISSION.
When debugging the getPdfFile method returns this path for me:
new File(downloads, fileNames[0])": "fileNames[0]=/storage/emulated/0/Download/nst/12345/myName.pdf"
And FileProvider gets me this:
"fileUri = content://br.com.myapp.bomapp/Download/nst/12345/myFile.pdf"
When 12345 is a sub directory which the file is located.
After the file directory is passed to FileProvider it opens the file but screen gets black because file is not there.
But when it is opened with Uril.fromFile the file is shown.
Am I doing something wrong?
I am trying to make an app that takes a photo and displays it using emulator instead of a device. I followed the steps from this android doc:
Part 1) Here is my code where it gets stucks : file = FileProvider.getUriForFile(this, "edu.android.notetakingapplication.provider", createFileDir());
This part is in the Mainxml
if (!mediaStorageDir.exists()){
if (!mediaStorageDir.mkdirs()){
Log.d("NoteTaking", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
}
Here is my app manifest file's provider section
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="edu.android.notetakingapplication.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
and provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="Android/data/edu.android.notetakingapplication/files/Pictures"/>
</paths>
Part 2) If i keep provider_paths as this
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
I am able to open camera app, take photo and view it on the same page, but, here is the catch, I am storing the path into database and trying to retrieve all the images on a page. Here is when it gives an error:
Unable to decode stream: java.io.FileNotFoundException: /external_files/Pictures/NoteTaking/IMG_20170226_230608.jpg (No such file or directory)
Try this surely it will work:
Uri mImageCaptureUri;
private void operCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && mImageCaptureUri != null && resultCode != 0) {
if (mImageCaptureUri != null) {
String path1 = mImageCaptureUri.getPath();
if (path1 != null) {
File file1 = new File(path1);
Uri capturedUri = Uri.fromFile(file1);//here you get the URI
//you can easily get the path from URI if you need
}
}
}
}
Unable to decode stream: java.io.FileNotFoundException: /external_files/Pictures/NoteTaking/IMG_20170226_230608.jpg (No such file or directory). Of course you get that error as it is a non valid path for File object or a file stream. You are saving the uri in a wrong way to the database. You better save File:getAbsoluthePath() instead of Uri:getPath().