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.
Related
I'm struggling with FileProvider. I want to open a video in another app, but no matter what I try every single app says that the video can't be loaded.
private void passVideo2(String videoname) {
File videoPath = new File(Environment.getExternalStorageDirectory(), "video_folder");
File videoInternalPath = new File(this.getFilesDir(), videoname);
File newFile = new File(videoPath, videoname);
Uri uri = FileProvider.getUriForFile(this, "com.example.provider", newFile);
Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri);
viewIntent.setDataAndType(uri, getContentResolver().getType(uri));
viewIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
this.startActivity(viewIntent);
}
I've tried getting the video from the external and from the internal storage and I've tried different video formats and other file types like e.g. pdf and nothing seems to work
This is my provider_paths.xml
<paths>
<files-path name="files" path="/"/>
<external-path name="external" path="video_folder"/>
</paths>
and this is from the manifest
<provider
android:authorities="com.example.provider"
android:name="androidx.core.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
This is a repost from this question as it didn't get any answers
I am trying to capture Image using camera Intent and send it to server.
I have followed the official doc https://developer.android.com/training/camera/photobasics
But getting exception while using FileProvider to get the Uri from the filepath.
I am getting an exception
Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.app/files/Pictures/JPEG_20200310_160944_8900302509758571991.jpg
Code:
file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Android/data/com.example.app/files" />
</paths>
AndroidManifest.xml
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.app.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"/>
</provider>
CameraActivity.kt
private fun dispatchTakePictureIntent() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
takePictureIntent.resolveActivity(packageManager)?.also {
val photoFile: File? = try {
viewModel.createFile()
} catch (ex: IOException) {
// Error occurred while creating the File
null
}
photoFile?.also {
photoURI= FileProvider.getUriForFile(
this,
"com.example.app.fileprovider",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
}
}
}
}
Please help me figure out where I am wrong.
Although I have checked the possible answers on stackoverflow but unable to resolve it.
Replace:
path="Android/data/com.example.app/files"
with:
path="."
<external-files-path> already points to the location that you are identifying in path.
I am creating a app in which i am generating pdf and after this app showing PDF automatically. it is working wee in 6.1 android but not showing in android 7.1. my code is
public void showPDF() {
File pdfFile = new File(Environment.getExternalStorageDirectory() , "A_DailyRegiser.pdf");
try {
if (pdfFile.exists()) {
Uri path = Uri.fromFile(pdfFile);
Intent objIntent = new Intent(Intent.ACTION_VIEW);
objIntent.setDataAndType(path, "application/pdf");
// objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
objIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
objIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(objIntent);
} else {
Toast.makeText(dailycollection.this, "File NotFound",Toast.LENGTH_SHORT).show();
}
} catch (ActivityNotFoundException e) {
Toast.makeText(dailycollection.this,
"No Viewer Application Found", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
That's because of the new changes in Noughat API's Read more here
you are suggested to use the content:// scheme instead of file:// for this we can use the file provider API.
here is sample code:
<manifest>
...
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mydomain.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
...
</application>
define the scope of your access
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="images/"/>
Generating the Content URI for a File
File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);
Granting Temporary Permissions to a URI
Intent.setFlags() with either FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION or both.
read more here
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>
I am creating a PDF file and saving it in local storage. When trying to open it, it is working perfect in all devices except in Android N. I am able to open PDF file in Android N using FileProvider, but it is displaying as blank.
This is my URI
content://com.products.provider/external_storage_root/Android/data/com.products/in_17052017_170502_1_1001.pdf
This is my code
Uri path;
File pdfFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"
+ "Android" + "/" + "data" + "/" + "com.products" + "/" + file);
if (Build.VERSION.SDK_INT >= 24) {
path = FileProvider.getUriForFile(getActivity(), "com.products.provider", pdfFile);
} else {
path = Uri.fromFile(pdfFile);
}
// Setting the intent for pdf reader
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "Can't read pdf file", Toast.LENGTH_SHORT).show();
}
The problem is with how you are setting the flags on the intent
pdfIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Instead, try this:
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
pdfIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Grzegorz Matyszczak's solution worked for my case. I had a very similar setup to Sabya Sachi. More specifically this line allowed me to see the PDF file (URI from FileProvider.getURIForFile call):
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
More info on grantUriPermissions here, under android:grantUriPermissions section.
As I can see that you have used FileProvider for Nougat.
You have to add a FileProvider tag in AndroidManifest.xml.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mydomain.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
</provider>
A FileProvider can only generate a content URI for files in directories that you specify beforehand.To link this file to the FileProvider, add a element as a child of the element that defines the FileProvider.
<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/file_paths"/>
</provider>
You must specify a child element of for each directory that contains files for which you want content URIs. You can add them to a new file called res/xml/file_paths.xml. For example ,these XML elements specify two directories:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="images/"/>
<files-path name="my_docs" path="docs/"/>
</paths>
->you have to set your PDF directory path in file_paths.xml
For more detail refer this
Replace FileProvider class with MyFileProvider class:
path = MyFileProvider.getUriForFile(getActivity(), "com.products.provider", pdfFile);
where MyFileProvider should be a generic class which extends FileProvider:
public class MyFileProvider extends FileProvider {
}
Modify AndroidManifest by setting your MyFileProvider class location to android:name attribute in your provider section:
android:name=".utils.MyFileProvider"