Convertir le fichier: Uri En fichier dans Android
Quel est le moyen le plus simple de convertir à partir d'un file:
android.net.Uri
à un File
Dans Android?
Essayé ce qui suit mais cela ne fonctionne pas:
final File file = new File(Environment.getExternalStorageDirectory(), "read.me");
Uri uri = Uri.fromFile(file);
File auxFile = new File(uri.toString());
assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());
15 réponses
Ce que vous voulez est...
new File(uri.getPath());
... et pas...
new File(uri.toString());
NOTE: uri.toString()
renvoie une chaîne au format: "file:///mnt/sdcard/myPicture.jpg"
, alors que uri.getPath()
renvoie une chaîne au format: "/mnt/sdcard/myPicture.jpg"
.
Après avoir cherché pendant longtemps, c'est ce qui a fonctionné pour moi:
File file = new File(getPath(uri));
public String getPath(Uri uri)
{
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if (cursor == null) return null;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String s=cursor.getString(column_index);
cursor.close();
return s;
}
EDIT: Désolé, j'aurais dû tester mieux avant. Cela devrait fonctionner:
new File(new URI(androidURI.toString()));
URI est java. net. URI.
Rien de tout cela ne fonctionne pour moi. J'ai trouvé que c'était la solution de travail. Mais mon cas est spécifique aux images.
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Utiliser
InputStream inputStream = getContentResolver().openInputStream(uri);
Directement et copiez le fichier. Voir aussi:
Https://developer.android.com/guide/topics/providers/document-provider.html
Avec Kotlin, c'est encore plus facile:
val file = File(uri.path)
Ou si vous utilisez extensions Kotlin pour Android :
val file = uri.toFile()
J'ai fait ceci comme suit:
try {
readImageInformation(new File(contentUri.getPath()));
} catch (IOException e) {
readImageInformation(new File(getRealPathFromURI(context,
contentUri)));
}
public static String getRealPathFromURI(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj,
null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Donc, fondamentalement, j'essaie d'abord d'utiliser un fichier, c'est-à-dire une photo prise par un appareil photo et enregistrée sur une carte SD. Cela ne fonctionne pas pour l'image renvoyée par:
Intention photoPickerIntent = Nouvelle intention ( intention.ACTION_PICK);
Dans ce cas, il est nécessaire de convertir L'Uri en chemin réel par la fonction getRealPathFromURI()
.
Donc, la conclusion est que cela dépend du type D'Uri que vous voulez convertir en Fichier.
@CommonsWare a très bien expliqué toutes les choses. Et nous devrions vraiment utiliser la solution qu'il a proposée.
En passant, seules les informations sur lesquelles nous pourrions Compter lors de l'interrogation ContentResolver
sont le nom et la taille d'un fichier comme mentionné ici:
récupération des informations du fichier / Développeurs Android
Comme vous pouvez le voir, il existe une interface OpenableColumns
qui ne contient que deux champs: DISPLAY_NAME et SIZE.
Dans mon cas, j'avais besoin de récupérer des informations EXIF sur une image JPEG et de la faire pivoter si nécessaire avant d'Envoyer à un serveur. Pour ce faire, j'ai copié un contenu de fichier dans un fichier temporaire en utilisant ContentResolver
et openInputStream()
La Meilleure Solution
Créez une classe Java FileUtil simple et utilisez-la pour créer, copier et renommer le fichier
Je suis utiliser uri.toString()
et uri.getPath()
mais ne fonctionne pas pour moi.
J'ai finalement trouvé cette solution.
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtil {
private static final int EOF = -1;
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
private FileUtil() {
}
public static File from(Context context, Uri uri) throws IOException {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
String fileName = getFileName(context, uri);
String[] splitName = splitFileName(fileName);
File tempFile = File.createTempFile(splitName[0], splitName[1]);
tempFile = rename(tempFile, fileName);
tempFile.deleteOnExit();
FileOutputStream out = null;
try {
out = new FileOutputStream(tempFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream != null) {
copy(inputStream, out);
inputStream.close();
}
if (out != null) {
out.close();
}
return tempFile;
}
private static String[] splitFileName(String fileName) {
String name = fileName;
String extension = "";
int i = fileName.lastIndexOf(".");
if (i != -1) {
name = fileName.substring(0, i);
extension = fileName.substring(i);
}
return new String[]{name, extension};
}
private static String getFileName(Context context, Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf(File.separator);
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
private static File rename(File file, String newName) {
File newFile = new File(file.getParent(), newName);
if (!newFile.equals(file)) {
if (newFile.exists() && newFile.delete()) {
Log.d("FileUtil", "Delete old " + newName + " file");
}
if (file.renameTo(newFile)) {
Log.d("FileUtil", "Rename file to " + newName);
}
}
return newFile;
}
private static long copy(InputStream input, OutputStream output) throws IOException {
long count = 0;
int n;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}
Classe utilisateur FileUtil dans votre code
try {
File file = FileUtil.from(MainActivity.this,fileUri);
Log.d("file", "File...:::: uti - "+file .getPath()+" file -" + file + " : " + file .exists());
} catch (IOException e) {
e.printStackTrace();
}
Vous pouvez obtenir le fichier à partir de L'Uri du fichier en utilisant la méthode suivante. Il a DocumentFile pour le paramètre mais vous pouvez le changer facilement. Le moyen le plus simple de tester cette méthode pour créer un uri de fichier en utilisant DocumentFile.fromFile(Environment.getExternalStorageDirectory());
qui a un Uri file:///storage/emulated/0
/**
* Gets File from DocumentFile if Uri is file:///
*
* @param documentFile Document file that contains Uri to create File from
* @return File with absolute path to the physical file on device memory
*/
public static File getFileFromDocumentFile(DocumentFile documentFile) {
try {
File file = new File(URI.create(documentFile.getUri().toString()));
return file;
} catch (Exception e) {
return null;
}
}
Au lieu de créer des fichiers à partir D'Uri, utilisez DocumentFile.fromTreeUri(Context, Uri)
ou DocumentFile.fromSingleri(Context, Uri)
pour créer ou supprimer des fichiers et pour les flux, Utilisez getContentResolver().openOutputStream(documentFile.getUri())
et getContentResolver().openInputStream(documentFile.getUri())
pour écrire ou lire des fichiers.
Chaîne publique getRealPathFromURI(uri uri) {
String result;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor == null) {
result = uri.getPath();
cursor.close();
return result;
}
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
return result;
}
Puis en utilisant pour obtenir le fichier de L'URI:
File finalFile = newFile(getRealPathFromURI(uri));
- L'ESPOIR PEUT VOUS AIDER - - - -
Android + Kotlin
-
Ajouter une dépendance pour les extensions Android Kotlin:
implementation 'androidx.core:core-ktx:{latestVersion}'
-
Récupère le fichier de l'uri:
uri.toFile()
Android + Java
Il suffit de passer en haut ;)
Par le code suivant, je suis en mesure d'obtenir le fichier PDF partagé de l'application adobe en tant que flux et d'enregistrer dans le chemin de l'application android
Android.Net.Uri fileuri =
(Android.Net.Uri)Intent.GetParcelableExtra(Intent.ExtraStream);
fileuri i am getting as {content://com.adobe.reader.fileprovider/root_external/
data/data/com.adobe.reader/files/Downloads/sample.pdf}
string filePath = fileuri.Path;
filePath I am gettings as root_external/data/data/com.adobe.reader/files/Download/sample.pdf
using (var stream = ContentResolver.OpenInputStream(fileuri))
{
byte[] fileByteArray = ToByteArray(stream); //only once you can read bytes from stream second time onwards it has zero bytes
string fileDestinationPath ="<path of your destination> "
convertByteArrayToPDF(fileByteArray, fileDestinationPath);//here pdf copied to your destination path
}
public static byte[] ToByteArray(Stream stream)
{
var bytes = new List<byte>();
int b;
while ((b = stream.ReadByte()) != -1)
bytes.Add((byte)b);
return bytes.ToArray();
}
public static string convertByteArrayToPDF(byte[] pdfByteArray, string filePath)
{
try
{
Java.IO.File data = new Java.IO.File(filePath);
Java.IO.OutputStream outPut = new Java.IO.FileOutputStream(data);
outPut.Write(pdfByteArray);
return data.AbsolutePath;
}
catch (System.Exception ex)
{
return string.Empty;
}
}
Pour les gens qui sont ici à la recherche d'une solution pour les images en particulier, c'est ici.
private Bitmap getBitmapFromUri(Uri contentUri) {
String path = null;
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
path = cursor.getString(columnIndex);
}
cursor.close();
Bitmap bitmap = BitmapFactory.decodeFile(path);
return bitmap;
}
Fichier imageToUpload = nouveau fichier (nouvel URI (androidURI.ToString())); fonctionne s'il s'agit d'un fichier que vous avez créé dans le stockage externe.
Par exemple fichier: / / / storage / emulated / 0 / (un répertoire et un nom de fichier)