Android- 我该如何将android.net.Uri对象转换为java.net.URI对象?

65

我正在尝试获取用户从图片库中选择的图像的FileInputStream对象。这是由android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI返回的android URI

content://media/external/images/media/3
当我尝试从这个对象构造一个Java URI对象时,我收到一个IllegalArgumentException异常,异常描述为“URI中预期的文件方案:content://media/external/images/media/3”,而Android URI显示方案为content。 更新:原问题未找到解决方案。但是,如果您想要图片库中图像的字节流,可以使用此代码。
Bitmap bitmap = Media.getBitmap(getContentResolver(), imageUri);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bytes.toByteArray());
5个回答

61
你可以使用 Android 的 Uri 对象的 toString 方法,并与 Java 的 URI 类的基于 String 的构造函数结合使用。
android.net.Uri auri = new android.net.Uri(what ever);
java.net.URI juri = new java.net.URI(auri.toString());

安卓URI | Java URI


4
谢谢。我试过了,但是会出现一个异常(java.net.URI应该有一个有效的方案)。 - lostInTransit
14
如果URI中含有需要编码的字符(例如空格),则该方法是错误的,并且将在运行时失败。android.net.Uri.toString()方法可以解码已编码的字符,而如果您尝试使用未编码的字符串构造它,则java.net.URI会抛出异常。正确的解决方案是:huri = new java.net.URI(URLEncoder.encode(auri.toString(), "UTF-8"));。请注意不要改变原文意思,并尽可能使翻译通俗易懂。 - Jeffrey Blattman
@Jeffrey:在我的Android 4.1.2设备上,Uri.toString()返回编码字符。 - Rémy DAVID
4
@RémyDAVID 不是这样的。我刚试了一下,对于一个含有空格的 a.n.Uri,空格并没有被编码。你可以自己试试看:Uri.parse("content://foo.bar.com/0?file=my goodness").toString()。你是对的,Javadocs 中确实说它返回一个已编码的字符串,但并没有说明使用了何种编码方式。 - Jeffrey Blattman

43

我找到了正确的方法从内容URI中打开InputStream:

InputStream fileInputStream=yourContext.getContentResolver().openInputStream(uri);

就是这样了!


2
谢谢!太简单了,我知道它肯定在某个地方。被接受的答案可能在某些情况下有效,但似乎并不安全/适用于所有情况。 - plainjimbo
非常感谢!!!当您需要从内置图库中选择的图像获取byte[]时,它非常有效! - Alex Bush
这会强制关闭我的应用程序并打开没有源附加的Binder.class。我正在发送Contacts.CONTENT_VCF_URI。 - tasomaniac

3

2

我投票支持jgilrincon的回答。由于声望不高,我无法评论,这里提供一些额外信息 - 您可以使用Apache Cordova项目中的FileHelper.java,它具有处理从Uri字符串获取文件所需的函数,同时考虑了mediastore(和应用程序资产文件夹)。

特别是该方法提供了从Uri获取InputStream的功能:

public static InputStream getInputStreamFromUriString(String uriString, Activity cordova)

0

由于字符串构造不起作用,您是否尝试自己构造它?

android.net.URI auri = new android.net.URI(what ever);
java.net.URI juri = new java.net.URI(auri.getSchema(),
                                     auri.getSchemaSpecificPart(),
                                     auri.getFragment());

你可能还想仔细检查一下从Android URI类中获取的数据是否有效。我在另一个答案中列出的文档讨论了它几乎不进行任何错误检查。如果实际上存在错误,该类将输出垃圾并且不会抛出任何异常。这很可能是Java类执行验证时抛出异常的原因。

谢谢Brian。URI是由Android自己返回的。它包含手机相册中图像的路径,因此无法对图像进行任何操作。我会尝试在问题中发布URI。 - lostInTransit
我想你是指getScheme和getSchemeSpecificPart,对吗? - Piotr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接