什么是最简单的方法从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());

当前回答

你可以使用这个函数从uri中获取文件在新的android和旧的

fun getFileFromUri(context: Context, uri: Uri?): File? {
    uri ?: return null
    uri.path ?: return null

    var newUriString = uri.toString()
    newUriString = newUriString.replace(
        "content://com.android.providers.downloads.documents/",
        "content://com.android.providers.media.documents/"
    )
    newUriString = newUriString.replace(
        "/msf%3A", "/image%3A"
    )
    val newUri = Uri.parse(newUriString)

    var realPath = String()
    val databaseUri: Uri
    val selection: String?
    val selectionArgs: Array<String>?
    if (newUri.path?.contains("/document/image:") == true) {
        databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        selection = "_id=?"
        selectionArgs = arrayOf(DocumentsContract.getDocumentId(newUri).split(":")[1])
    } else {
        databaseUri = newUri
        selection = null
        selectionArgs = null
    }
    try {
        val column = "_data"
        val projection = arrayOf(column)
        val cursor = context.contentResolver.query(
            databaseUri,
            projection,
            selection,
            selectionArgs,
            null
        )
        cursor?.let {
            if (it.moveToFirst()) {
                val columnIndex = cursor.getColumnIndexOrThrow(column)
                realPath = cursor.getString(columnIndex)
            }
            cursor.close()
        }
    } catch (e: Exception) {
        Log.i("GetFileUri Exception:", e.message ?: "")
    }
    val path = realPath.ifEmpty {
        when {
            newUri.path?.contains("/document/raw:") == true -> newUri.path?.replace(
                "/document/raw:",
                ""
            )
            newUri.path?.contains("/document/primary:") == true -> newUri.path?.replace(
                "/document/primary:",
                "/storage/emulated/0/"
            )
            else -> return null
        }
    }
    return if (path.isNullOrEmpty()) null else File(path)
}

其他回答

我是这样做的:

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类型。

对于那些在这里寻找图像解决方案的人,特别是在这里。

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

添加onActivityResult,获取docx或pdf文件

var imageUriPath = ""
imageUriPath =
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val split = (imageUri.path ? : "").split(":") //split the path.
    split[1]
  } else {
    imageUri.path ? : ""
  }
val file = File(imageUriPath)

@CommonsWare解释得很好。我们真的应该采用他提出的解决方案。

顺便说一下,当查询ContentResolver时,我们唯一可以依赖的信息是文件的名称和大小,如下所述: 检索文件信息| Android开发人员

正如您所看到的,这里有一个接口OpenableColumns,它只包含两个字段:DISPLAY_NAME和SIZE。

在我的例子中,我需要检索关于JPEG图像的EXIF信息,并在发送到服务器之前根据需要旋转它。为此,我使用ContentResolver和openInputStream()将文件内容复制到临时文件中。

在寻找了很长一段时间后,这对我来说是有效的:

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