I have a strange problem when I try to share a my_file.html using ShareCompat.
As best practice I have created my own FileProvider but I get the error java.lang.IllegalArgumentException: Failed to find configured root that contains /forms/Proof_of_Life_Form.html I think I have set up all of the stuff correctly.
My XML I have created a provider for that.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.douglas.sample"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
This is my filepaths created in res/xml/filepaths
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path path="/forms" name="forms" />
</paths>
and also my method that is responsible to call share content.
public void shareContent() {
File file = new File("/forms/", fileName + ".html");
Uri uri = FileProvider.getUriForFile(getContext(), "com.douglas.sample", file);
Intent shareIntent = ShareCompat.IntentBuilder.from(getActivity())
.setType(getActivity().getContentResolver().getType(uri))
.setStream(uri)
.getIntent();
//Provide read access
shareIntent.setData(uri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_form)));
}
Finally my exception:
java.lang.IllegalArgumentException: Failed to find configured root that contains /forms/Proof_of_Life_Form.html
at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:719)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:404)
at com.douglas.sample.TabbedFormsFragment$2.run(TabbedFormsFragment.java:254)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Any Idea? thanks :D
It seems there are some little mistakes in your code.
Try the following:
<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/provider_paths"/>
</provider>
and then in your provider_paths.xml try:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!-- We would like to give access to the External Storage of the app.
external_files will expose the path app to storage/emulated/0/ and the
"." is to actually point the root folder. The final path of the Uri will start
from path above and whatever folder we defined. For application upgrades
will be external_files/Android/data/package name/files/updates/name of update apk.-->
<external-path
name="external_files"
path="."/>
</paths>
and then whereever you want to use it try:
String path = Uri.parse(your_file_uri).getPath();
FileProvider.getUriForFile(application, PROVIDER, new File(path)),my_file_type);
where my_file_type = e.g. "application/vnd.android.package-archive" for .apk file
Hope it helps!!!
Related
I am trying to send a list of files using tcp socket but i get this file provider error.
please help if anyone can. Thanks
Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains >/storage/708A-1A0F/- CHAIN YE DILLAN DA - MUHAMMAD UMAIR ZUBAIR QADRI - OFFICIAL HD VIDEO.mp4
at >androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:800)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:442)
File Path
Set<String> keys = BaseApplication.sendFileStates.keySet();
if (keys.size() > 0) {
for (String s : keys) {
File newFile = new File(s);
Uri contentUri = FileProvider.getUriForFile(this, "com.Jubilant.wifiproject", newFile);
uris.add(contentUri);
}
Log.d("contentUri", "onCreate: " + uris);
}
file_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="." />
<cache-path
name="external_cache"
path="."/>
<external-cache-path
name="external_cache_path"
path="."/>
<external-files-path
name="external_files_path"
path="."/>
<external-media-path
name="external_media_path"
path="."/>
<files-path
name="files_path"
path="."/>
</paths>
manifest.xml:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.Jubilant.wifiproject"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path" />
</provider>
FileProvider standard can not serve files from a removable micro sd card.
Sometimes it can when you add
<root name="root" path="." />
to your file_paths.xml file.
In other cases write your own file provider extending ContentProvider.
I have been working on CameraX API and storing captured image on Internal storage App data folder with path say storage/emulated/0/Android/data/packageName/Files/IMG_25052021_171806.jpg
Now i want to get content URI for this saved image. For this i have been using provider in Manifest.
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.abc.xyz.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepath" />
</provider>
with File path as
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="/" />
When i am calling FileProvider.getUriForFile(ImageCrop.this,"com.abc.xyz.fileprovider", pictureFile); it returning me Illegal Argument Exception
Please suggest !!!
You seem to be using getExternalFilesDir() for the filesystem location. If so, use <external-files-path>, not <files-path>, in your metadata XML resource. See the documentation for more.
So I am trying to create a pdf in my app and send that pdf as attachment to gmail app. All was good before android 11 scoped storage restrictions.
This are the files I am using :
provider_paths.xml :
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
AndroidManifest.xml :
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
This is the file that I am trying to add as attachment :
File filelocation = new File(context.getCacheDir() +"/", "Some#" + printBean.getId() + ".pdf");
Using the below to access Uri :
Uri path = FileProvider.getUriForFile(this, getPackageName()+".fileprovider",filelocation);
but when I am passing the Uri with the intent for opening gmail
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{new UserPreference(context).getUser().getEmail()});
if (path != null) emailIntent.putExtra(Intent.EXTRA_STREAM, path);
emailIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Mail PDF");
emailIntent.putExtra(Intent.EXTRA_EMAIL, new UserPreference(context).getUser().getEmail());
emailIntent.putExtra(Intent.EXTRA_TEXT, printBean);
context.startActivity(Intent.createChooser(emailIntent, context.getString(R.string.send_email)));
it gives me error "couldn't attach file".
Need Help.
Edit : Getting this exception in log :
ComposeActivity:Error adding attachment
ggx: FileNotFoundException when openAssetFileDescriptor.
at ggy.a(PG:6)
at ggy.a(PG:45)
at dod.a(PG:146)
at dnk.run(PG:2)
at dod.a(PG:184)
at dod.a(PG:153)
at dod.a(PG:452)
at dkb.a(Unknown Source:3)
at aezj.a(Unknown Source:5)
at agzq.a(PG:2)
at agzs.run(PG:9)
at ahcg.run(Unknown Source:7)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at aexk.run(PG:2)
at adjn.run(Unknown Source:3)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Well FiltUtils might be returning null. You can get the file like
val file = File(context.getCacheDir(), FILE_NAME) and afterwards pass
FileProvider.getUriForFile(requireContext(),YOUR_PROVIDER_PACKAGE ,file)
File provider will give you the uri then you can pass that inside intent of sharing file
I'm having really hard time trying to open downloaded apk
I'm trying to use FileProvider (https://developer.android.com/reference/android/support/v4/content/FileProvider), I've followed this steps but I think I'm doing something wrong. I change this code in different ways many times, but unsuccessful.
Here's what I have:
File downloaded in:
app.setPathUpdate(Environment.getExternalStorageDirectory() +
File.separator + "trovata/update/" +
this.getApplicationInfo().packageName + File.separator)
The code above make this outcome: /storage/emulated/0/trovata/update/br.com.trovata.milano.elite/
Here's what I'm doing:
SincronizacaoActivity.java
File FileAppInst = new File(app.getPathUpdate() + "atualizador");
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID+".provider", FileAppInst);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<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/filepaths" />
</provider>
filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="atualizador" path="/trovata/update/${applicationId}/"/>
</paths>
Error:
...
Caused by: java.lang.IllegalArgumentException: Failed to find configured
root that contains /storage/emulated/0/trovata/update/br.com.trovata.milano.elite/atualizador
...
Could you help me?
path="/trovata/update/${applicationId}/"
${applicationId} only turns into your application ID in AndroidManifest.xml. You cannot use manifest placeholders in resource files. So, replace ${applicationId} with your actual application ID.
In all the encounters with FileProvider it occurs that in most of the cases it only worked when the path was set to path=".".
Replace your filepaths.xml with this
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="atualizador" path="."/>
</paths>
And give it a try.
I'm creating a file with this path
File file = new File(getExternalFilesDir(null) + "/package.apk");
then I'm trying to send it using this code
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileProvider.getUriForFile(UpdateActivity.this, getPackageName() + ".provider", file), "application/vnd.android.package-archive");
Log.d("uri",FileProvider.getUriForFile(UpdateActivity.this, getPackageName() + ".provider", file).toString());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
my android manifest is
<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 version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="files" path="." />
</paths>
After running code I'm getting There was a problem parsing the package error but if I open the file using file manager from path Android/my.package.name/files/package.apk it's parsing so the URI I'm sending is incorrect then I tried to print it and the result is
content://my.package.name.provider/files/package.apk
what am I doing wrong?
You forgot to add FLAG_GRANT_READ_URI_PERMISSION on the Intent. As it stands, the Uri is valid, but the installer has no rights to access its content.
Also note that the stock Android installer only supports content schemes as of Android 7.0. Older Android devices are limited to file.