I got to use FileProvider in order to install an apk. Everything works well now but I don't really understand the behaviour FileProvider follows in order to choose the correct path defined inside the provider_paths.xml. Here's my code:
Manifest.xml
<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/provider_paths"/>
</provider>
main_activity.java
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
intent = new Intent(Intent.ACTION_VIEW);
File apk = new File("/sdcard/example.apk");
String fileType = "application/vnd.android.package-archive";
intent.setDataAndType(Uri.fromFile(apk), fileType);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} else {
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
File directory = new File(Environment.getExternalStorageDirectory().toString());
File apk = new File(directory, "example.apk");
Uri fileUri = FileProvider.getUriForFile(this, valoresGenerales.appContext.getPackageName() + ".provider", apk);
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(apk.getName()));
intent.setDataAndType(fileUri, type);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivity(intent);
provider_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
<files-path name="files_path" path="Download"/>
</paths>
What does make FileProvider choose between external_path or files_path (or whatever defined in the file) depends on?
Related
I'm trying to follow these instructions https://developer.android.com/reference/android/support/v4/content/FileProvider for opening an image with Intent from internal folder.
My path image is '/data/data/com.saffru.colombo.cartellaclinica/files/imgs/IMG-20200422-WA0001.jpg'
In my Manifest I added the provider as follow
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.saffru.colombo.cartellaclinica.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
My provider_paths.xml is
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
<files-path name="my_images" path="img/"/>
<cache-path name="img" path="img" />
</paths>
In my Activity I've an Imageview where I show the Bitmap image and with a click a user can open this image, but it doesn't work. Here my code
File file = new File(pathFile);
File imagePath = new File(getFilesDir(), "img");
File newFile = new File(imagePath, file.getName());
Uri contentUri = FileProvider.getUriForFile(ViewEsameActivity.this,
"com.saffru.colombo.cartellaclinica.fileprovider", newFile);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
//Uri uri = Uri.parse("content://" + file.getAbsolutePath());
grantUriPermission("com.saffru.colombo.cartellaclinica" +
".fileprovider", contentUri,
FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(contentUri,"image/*");
intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Once the Gallery application is opened I receive the error 'File format isn't supported or file are corrupted'
I am new in android and working on one android project in which I have to display a chosen pdf from the device either from internal storage(Priority) or from external Storage. I am enclosing the used code below.
private void openLocalPDF(File pdffile) {
File file = new File(Environment.getExternalStorageDirectory(), pdffile.getName());
Uri path = PdfFileProvider.getUriForFile(activity.getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", file);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
target.setDataAndType(path, "application/pdf");
Intent intent = Intent.createChooser(target, "Open File");
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "Please install some pdf viewer app", Toast.LENGTH_LONG).show();
}
You should create a Provider Class and extends with FileProvider. and register in manifest and also if you using targetSdkVersion 29 add this permission AndroidManifest.xml android:requestLegacyExternalStorage="true"
<provider
android:authorities="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true"
android:name=".provider.GenericFileProvider">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
And add a provider_paths.xml file in xml folder :
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
And use this method
public static void openFile(Context context, File file) {
Uri path = GenericFileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(path, "application/pdf);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
}
}
I hope this will help you.
Follow below steps:
Step - 1: Create provider_paths.xml in your xml directory
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Step - 2: Add FileProvider in your AndroidManifest.xml file
<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/provider_paths" />
</provider>
Step - 3: Since your file is in internal/external storage use getExternalStorageDirectory()
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(path, "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent intent = Intent.createChooser(target, "Open File");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "Please install some pdf viewer app", Toast.LENGTH_LONG).show();
}
I'm doing app to share a png image to facebook and all, the code works fine in my Huawei Honor 8 and crashes with the google pixel 2.
code:
showLoading("Saving...");
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + ""
+ System.currentTimeMillis() + ".png");
photoEditorView.getSource().setImageURI(Uri.fromFile(f));
Uri contentUri = Uri.fromFile(f);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/png");
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "title");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
share.putExtra(Intent.EXTRA_STREAM, contentUri);
startActivity(Intent.createChooser(share, "Share Image!"));
Try this code,
File nFile = new File(selectedImagePath);
Uri mmuri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mmuri = getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider",nFile);
} else{
mmuri = Uri.fromFile(nFile);
}
using mmuri uri for sending image.
add in manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="your package name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
in res make xml folder and create provider_paths.xml file and add below code.
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
<root-path
name="external_files"
path="/storage/" />
</paths>
I try to open PDF file in Oreo but it does not open. I don't get any error. What is the issue? PDF file does not open. Only black screen is shown. In logcat no errors show. What is wrong?
How Can I resolve this issue? I referred many links but did not get solution. I also tried many codes but no help.
My Code is:
File file11 = new File(Environment.getExternalStorageDirectory().
getAbsolutePath(),
"AtmiyaImages/" + nameoffile1);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT>24){
Uri uri=FileProvider.getUriForFile(AssignmentActivity.this,
getPackageName()+".provider",file11);
target.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
target.putExtra(Intent.EXTRA_STREAM,uri);
target.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
target.setType("application/pdf");
Intent intent=Intent.createChooser(target,"Open File");
try
{
startActivity(intent);
}
catch(ActivityNotFoundException e)
{
Toast.makeText(AssignmentActivity.this,"No Apps
can performs This acttion",Toast.LENGTH_LONG).show();
}
}
else
{
target.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
target.setDataAndType(Uri.fromFile(file11),"application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent=Intent.createChooser(target,"Open File");
try
{
startActivity(intent);
}
catch(ActivityNotFoundException e)
{
Toast.makeText(AssignmentActivity.this,"No Apps can performs This
acttion",Toast.LENGTH_LONG).show();
}
}
In Manifest I also add
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.infinity.infoway.atmiya.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
And My Xml code is:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="Phonestorage"
path="/storage/emulated/0/AtmiyaImages"/>
</paths>
Replace your path value with "." - Look at below:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Inside Manifest, "provider" code is like this, your one is also true.
<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/provider_paths" />
</provider>
For access proper file path follow this code:
File pdfFile = new File(getExternalFilesDir(GlobalUtils.AppFolder), fileName);
Uri path = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", pdfFile);
Log.e("create pdf uri path==>", "" + path);
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
finish();
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(),
"There is no any PDF Viewer",
Toast.LENGTH_SHORT).show();
finish();
}
Hope this will help you.
Some tweaks to Bhoomika's answer worked for me
xml/providers_path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="files" path="."/>
</paths>
AndroidManifest.xml
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="APPLICATION_ID.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
A Kotlin Extension function to open the PDF from an activity
fun Activity.openPdf(filename: String?) {
val file = File(filesDir, filename)
if(file.exists()) {
Intent(Intent.ACTION_VIEW).apply {
setDataAndType(FileProvider.getUriForFile(this#openPdf, BuildConfig.APPLICATION_ID + ".provider", file), "application/pdf")
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
startActivity(this)
} catch (e: Exception) {
showErrorDialog(unable_to_open_doc)
}
}
} else {
showErrorDialog(file_doesnt_exist)
}
}
I'm trying to open downloaded pdf file trough implicit intent using FileProvider.
I'm using DownloadManager for downloading pdf file from remote server, It's working fine. Which is store at it's destination.
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadURL));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(false);
request.setTitle(mFilename);
request.setDescription("Downloading...");
request.setVisibleInDownloadsUi(true);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/FOLDER_NAME/" + mFilename);
After Finishing Download i want to open it.
public void OpenPdfFile(){
File sharedFile = new File(Environment.DIRECTORY_DOWNLOADS, "/FOLDER_NAME/" + mFilename);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID+ ".provider", sharedFile);
intent.setDataAndType(uri, "application/pdf");
PackageManager pm = mContext.getPackageManager();
if (intent.resolveActivity(pm) != null) {
mContext.startActivity(intent);
}
}
in Manifest file
<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/provider_paths"/>
</provider>
and the provider_paths.xml as like
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external-path" path="." />
</paths>
it troughs me this error
java.lang.IllegalArgumentException: Failed to find configured root that contains /Download/FOLDER_NAME/demo_presentationfile.PDF
Any suggestions ?
File sharedFile = new File(Environment.DIRECTORY_DOWNLOADS, "/FOLDER_NAME/" + mFilename);
That evaluates to an impossible file system path. Which you would see if you inspected the value of sharedFile.getAbsolutePath().
Change to:
File sharedFile = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "FOLDER_NAME/" + mFilename);