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>
Related
I am trying to share an video from one app to another, but show me an error that "failed to find configure root/data/data/app_name/cache/videos/external files". I can't understand why it's not passing the uri to another app.
can anyone help me to solve this problem
here is file provider path
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="videos/"/>
</paths>
<provider
android:name="androidx.core.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_provider_paths" />
</provider>
here is my code
File video = null;
shareVideos(video);
private void shareVideos(File video) {
Uri uri = getVideoToShare(video);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("videos/mp4");
context.startActivity(Intent.createChooser(intent, "Share Via"));
}
private Uri getVideoToShare(File video) {
File imagefolder = new File(context.getCacheDir(), "videos");
Uri uri = null;
try {
imagefolder.mkdirs();
File file = new File(imagefolder, "external_files");
FileOutputStream outputStream = new FileOutputStream(file);
outputStream.flush();
outputStream.close();
uri = FileProvider.getUriForFile(context, "com.myapp.fileprovider", file);
} catch (Exception e) {
Toast.makeText(context, "" + e.getMessage(), Toast.LENGTH_LONG).show();
}
return uri;
}
File imagefolder = new File(context.getCacheDir(), "videos");
You are storing your file in getCacheDir(). That requires a <cache-path> element in the FileProvider XML metadata resource. That is not what you have. You have:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="videos/"/>
</paths>
Change that to:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="external_files" path="videos/"/>
</paths>
I could not find a smart solution to my problem and that is why I decided to write to you good people. I have a question for your regarding FileProvider and ACTION_VIEW, namely, I save the html file this way:
File sdcard = getBaseContext().getExternalFilesDir(null);
File dir = new File(sdcard.getAbsolutePath() + “/MYDIR/“);
dir.mkdir();
File file = new File(dir, “MYFILE.html");
File recordFile = new File(sdcard.getAbsolutePath()+ "/MYDIR/" + "MYFILE.html");
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(returnedText.getText().toString().getBytes());
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
its path: storage/emulated/0/Android/data/com.myapp/files/MYDIR/MYFILE.html
This is how I call my html file:
File sdcard = getBaseContext().getExternalFilesDir(null);
Intent intent = new Intent(Intent.ACTION_VIEW);
File f = new File(sdcard.getAbsolutePath() + "/MYDIR" + "/MYFILE.html");
intent.setDataAndType(Uri.fromFile(f), "text/html");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|
Intent.FLAG_ACTIVITY_NO_HISTORY|
Intent.FLAG_ACTIVITY_NEW_TASK);
Intent.createChooser(intent, "File Browser");
startActivity(intent);
I want to call this MYFILE.html via Intent and open in HTML Viewer, I get this error:
ERR_ACCESS_DENIED
So I decided to try FileProvider, but I get a completely different path. What should I do, any specific idea??? Thanks in advance.
My FileProvider:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.myapp.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
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 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 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"