Android: Using a File Provider on ExternalStorage - java

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.

Related

Failed to find configured root that contains /storage/708A-1A0F/-

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.

Unresolved Class 'FileProvider' in manifest.xml (Android Java)

I am building my first Java application. Its functionality includes taking camera images and saving them along with saving 'Project' information locally for said images to be associated with.
I believe I need to include the FileProvider to my code:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="devkit.blade.vuzix.com.blade_template_app"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path"></meta-data>
</provider>
In the above XML .FileProvider is not resolving and so I cant build the app. What's the problem here?
Also for context #xml/provider_path references this file:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="/storage/emulated/0" path="."/>
</paths>
I believe I need to include the FileProvider to my code
In your <provider> element in your manifest, try changing android.support.v4.content.FileProvider (the fully-qualified class name to an old edition of FileProvider) to androidx.core.content.FileProvider.
Adding this to my build.grade (app module) allowed it to be referenced correctly. If you are required to use API level 27 (pre androidX) this is the way!
implementation 'com.android.support:support-core-utils:27.0.0'

How to set file provider for images stored in app data folder

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.

Share content using ShareCompat

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!!!

Can't send file correct URI using FileProvider

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.

Categories