Android taking picture with FileProvider - android

I'm taking a picture on Android Nougat with FileProvider, that's my code
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mypackage.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
file_paths.xml:
<paths>
<files-path name="img" path="images/" />
</paths>
Java:
String fileName = "cameraOutput" + System.currentTimeMillis() + ".jpg";
File imagePath = new File(getContext().getFilesDir(), "images");
File file = new File(imagePath, fileName);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final Uri outputUri = FileProvider.getUriForFile(activity, "com.mypackage.fileprovider", file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
getContext().grantUriPermission(
"com.google.android.GoogleCamera",
outputUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
);
cameraIntent.setFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
activity.startActivityForResult(cameraIntent, ACTIVITY_REQUEST_CODE);
Camera activity starts, take picture successfully, but the Activity Result is not OK and the only thing I see in error logs is
CAM_StateSavePic: exception while saving result to URI: Optional.of(content://com.mypackage.fileprovider/img/cameraOutput1469383289530.jpg)
FileNotFoundException: Is a directory
EDIT
missed File#createNewFile();

The main thing to get camera and gallery URI working is provider paths.
you need to create a provider_paths.xml to /res/xml/ dir
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
In your manifest file add this lines between
<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>
One more thing, I've found that we need to set vmPolicy in Application class like this
#Override
public void onCreate() {
super.onCreate();
//Allowing Strict mode policy for Nougat support
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
Double check your camera and external storage permission in manifest file and there you go with nougat URI.
For more details check this link : Android N FileUriExposedException

if androidx was used in your project, you need replace dot(.) to slash(/).
<!--别用. 不然在androidx上面有问题-->
<external-path name="sdcard" path="/" />
works for me great!

Related

FileProvider : Install apk programatically - Failed to find configured root that contains

I am using FileProvider to install apk from my app. Followed many stackoverflow questions but still facing this issue
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.tssi.myapptour/files/download/myapp_newSigned.apk
My provider in manifest
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.tssi.myapptour.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
my file_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="download" path="download/" />
<!-- <external-path name="download" path="Android/data/com.tssi.myapptour/files/download/" />-->
</paths>
And my code for calling apk
String strApkToInstall = "myapp_newSigned.apk";
File fileApkToInstall = new File(getExternalFilesDir("download"), strApkToInstall);
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider",
fileApkToInstall);
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Your file is in getExternalFilesDir(). That does not match files-path in your FileProvider metadata. Either:
Switch to getFilesDir() (a much better solution from a security standpoint), or
Switch to external-files-path
See the FileProvider documentation for more about the mapping between filesystem locations and metadata entries.

My app crashed when open camera in Android 7.0

My app crashed when open camera in Android 7.0
File captureFilePath = new File(cachePath, CommonUtil.getDateTimeForFileName(System.currentTimeMillis())+".jpg");
Uri uri = Uri.fromFile(captureFilePath);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_CAPTURE_IMAGE);
CAPTURE_IMAGE_PATH = captureFilePath.getAbsolutePath();
If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
1) First Add a FileProvider tag in AndroidManifest.xml under tag as below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name=".GenericFileProvider"
android:authorities="${applicationId}.my.package.name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
</manifest>
2) Then create a provider_paths.xml file in res/xml folder. Folder may be needed to created if it doesn't exist.
<paths>
<external-path name="external_files" path="."/>
</paths>
3) Now edit your activity class file as below:
Uri uri = Uri.fromFile(captureFilePath);
to
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, captureFilePath);

How to open a directory(folder) in Android using file provider?

I want to open the downloads folder of external files directory by most of the file manager applications.
For this I tried this:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setDataAndType(uri, "*/*");
startActivity(Intent.createChooser(intent, "Open folder"));
And I added this provider in manifest file:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
Also there is provider_paths xml file content:
<paths>
<external-files-path
name="files"
path="." />
</paths>
But it opens the recent folder of the default Android file picker.
Please pay attention that I want to open a folder not a file.

FileProvider with external folder

I'm trying to open a file (using the FileProvider) that is stored in a private folder
File appFiles = new File(externalPath.getAbsolutePath() +
"/Android/data/com.my.nice.domain/files/Container/");
Then inside the appFiles i'm creating subfolder and store files inside the sub folder
my files_path.xml looks like this
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_path4"
path="Android/data/com.my.nice.domain/files/Container/"/>
</paths>
Relevant manifest xml code snippet
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.my.nice.domain.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
and this is how I'm using the FileProvider to open the files (to view them with the default viewer)
File f = new File(url);
String AUTHORITY="com.my.nice.domain.fileprovider";
Uri uri = FileProvider.getUriForFile(getApplicationContext(), AUTHORITY, f);
Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
but for some reason its not working, and I'm getting error saying that file not found
example for error message that I'm getting
File not found (content://com.my.nice.domain.fileprovider/my_path4/576feb25/535d8216.xlsx)
Any ideas on what am I doing wrong?

External application is stopped when using FileProvider for opening file from internal storage

I have some files in custom folder in the internal storage. I need to open the files using external application like Adobe. I planned to open using FileProvider. But the third party application is stopped when trying to open the the document. I really don't know what mistake I did in the code.
package name = "com.example.doc"
activities are in package = "com.example.doc.activities"
manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.doc.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
android:readPermission="com.example.doc.fileprovider.READ">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepath" />
</provider>
res/xml/filepath.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="files" path="." />
</paths>
activity
//tempfilePath = /data/data/com.example.doc/files/RBC/sample.docx
File file = new File(tempfilePath);
Uri exportUri = FileProvider.getUriForFile (this, "com.example.doc.fileprovider", file);
Intent docViewIntent = new Intent();
docViewIntent.setAction(Intent.ACTION_VIEW);
docViewIntent.setDataAndType(exportUri , extensionType);
docViewIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
docViewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(docViewIntent);
Do we need to specify any permission in manifest?
Any help would be appreciated..
Thanks
Jomia

Categories

Resources