什么是最简单的方法从android.net.Uri对象持有一个文件:类型转换为java.io.File对象在Android?

我尝试了下面的方法,但不管用:

File file = new File(Environment.getExternalStorageDirectory(), "read.me");
Uri uri = Uri.fromFile(file);
File auxFile = new File(uri.toString());
assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());

当前回答

科特林 2022

suspend fun Context.createFileFromAsset(assetName: String, fileName: String): File? {
    return withContext(Dispatchers.IO) {
        runCatching {
            val stream = assets.open(assetName)
            val file = File(cacheDir.absolutePath, fileName)
            org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, file)
            file
        }.onFailure { Timber.e(it) }.getOrNull()
    }
}

处理完文件后,请确保对其调用.delete()。向@Mohsent致敬

其他回答

我是这样做的:

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);
}

所以基本上首先我尝试使用一个文件,即相机拍摄的照片,并保存在SD卡上。这对返回的图像不起作用: 意图photoPickerIntent =新的意图(Intent. action_pick); 在这种情况下,需要通过getRealPathFromURI()函数将Uri转换为真实路径。 所以结论是,这取决于你想转换为File的Uri类型。

一些库需要文件对象的过程,如改造,一些图像编辑器等。 将URI转换为文件对象或任何类似的东西,我们有一种方法,这是支持所有android旧版本和即将到来的版本。

步骤1:

你必须在FilesDir中创建一个新文件,这个文件对于其他与我们的文件和扩展名相同的应用程序是不可读的。

步骤2:

您必须通过使用InputStream复制URI的内容来创建一个文件。

File f = getFile(getApplicationContext(), uri);

public static File getFile(Context context, Uri uri) throws IOException {
    File destinationFilename = new File(context.getFilesDir().getPath() + File.separatorChar + queryName(context, uri));
    try (InputStream ins = context.getContentResolver().openInputStream(uri)) {
        createFileFromStream(ins, destinationFilename);
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
    return destinationFilename;
}

public static void createFileFromStream(InputStream ins, File destination) {
    try (OutputStream os = new FileOutputStream(destination)) {
        byte[] buffer = new byte[4096];
        int length;
        while ((length = ins.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        os.flush();
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
}

private static String queryName(Context context, Uri uri) {
    Cursor returnCursor =
            context.getContentResolver().query(uri, null, null, null, null);
    assert returnCursor != null;
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    returnCursor.moveToFirst();
    String name = returnCursor.getString(nameIndex);
    returnCursor.close();
    return name;
}

经过大量的搜索和尝试不同的方法,我发现这个方法适用于不同的Android版本: 首先复制这个函数:

    fun getRealPathFromUri(context: Context, contentUri: Uri): String {
        var cursor: Cursor? = null
        try {
            val proj: Array<String> = arrayOf(MediaStore.Images.Media.DATA)
            cursor = context.contentResolver.query(contentUri, proj, null, null, null)
            val columnIndex = cursor?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
            cursor?.moveToFirst()
            return columnIndex?.let { cursor?.getString(it) } ?: ""
        } finally {
            cursor?.close()
        }
    }

然后,生成一个像这样的文件:

File(getRealPathFromUri(context, uri))

你想要的是…

new File(uri.getPath());

... ,而不是……

new File(uri.toString());

笔记

对于android.net.Uri对象,它被命名为uri并完全按照问题中创建,uri. tostring()返回一个“file:///mnt/sdcard/myPicture.jpg”格式的字符串,而uri. getpath()返回一个“/mnt/sdcard/myPicture.jpg”格式的字符串。 我知道在Android系统中文件存储有一些细微差别。在这个回答中,我的意图是准确地回答提问者所问的问题,而不是深究其中的细微差别。

使用这个来写入文件,它为我工作时,gif的uri是由GBoard提供的,我必须在我的应用程序数据复制该gif。

    try {
      String destinationFilePath = getExternalFilesDir("gifs") + "/tempFile.txt";
      InputStream inputStream = getContentResolver().openInputStream(uri);
      OutputStream outputStream = new FileOutputStream(destinationFilePath);

      byte[] buffer = new byte[1024];
      int bytesRead;

      while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
      }

      inputStream.close();
      outputStream.close();
    }
    catch (Exception e) {
      e.printStackTrace();
    }