为了账号安全,请及时绑定邮箱和手机立即绑定

在 Android 上从照片 URI 创建文件

在 Android 上从照片 URI 创建文件

紫衣仙女 2022-12-15 17:03:33
我有一个 Android 应用程序,需要让用户从图库中选择一些图片并将这些图片发送到后端(连同一些其他数据)。为了让用户选择我的片段中的图片:private void pickImages() {    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);    intent.setType("image/*");    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);    startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);}我在这里得到用户选择的照片的结果:@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {        if (data == null) {            //Display an error            Toast.makeText(getActivity(), "There was an error getting the pictures", Toast.LENGTH_LONG).show();           return;        }        ClipData clipData = data.getClipData();        String fileName = null, extension = null;        //if ClipData is null, then we have a regular file        if (clipData == null) {            //get the selected file uri            fileName = FileUtils.getPath(getActivity(), data.getData());            //obtain the extension of the file            int index = fileName.lastIndexOf('.');            if (index > 0) {                extension = fileName.substring(index + 1);                if (extension.equals("jpg") || extension.equals("png") || extension.equals("bmp") || extension.equals("jpeg"))                    isAttachedFile = true;            }        }        ArrayList<Uri> photosUris = new ArrayList<>();        //for each image in the list of images, add it to the filesUris        if (clipData != null) for (int i = 0; i < clipData.getItemCount(); i++) {            ClipData.Item item = clipData.getItemAt(i);            Uri uri = item.getUri();            switch (i) {                case 0:                    picture1Uri = uri;                    break;                case 1:                    picture2Uri = uri;                    break;            }            
查看完整描述

1 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

为了让用户选择我的片段中的图片:

此代码正在使用ACTION_GET_CONTENT. 特别是在 Android 7.0+ 上,通常 (and ACTION_OPEN_DOCUMENT) 将返回Uri带有content方案的值。您的代码假定您正在Uri使用一个方案获取值file,其中路径实际上具有意义。此外,您的代码假定用户正在选择您可以访问的文件系统上的文件,并且没有任何强制用户这样做的东西。ACTION_GET_CONTENT可以由内容为以下内容的应用程序支持:

  • 外部存储上的本地文件

  • 另一个应用程序内部存储上的本地文件

  • 可移动存储上的本地文件

  • 加密的本地文件,需要即时解密

  • BLOB保存在数据库列中的字节流

  • 互联网上的一段内容,需要先由其他应用下载

  • 即时生成的内容

  • ...等等

而不是使用RequestBody.create(),使用InputStreamRequestBody来自这个 OkHttp 问题的评论。您提供与以前相同的媒体类型,但您提供的不是 a File(您错误地创建),而是ContentResolver(来自getContentResolver()a 上的Context)和Uri.

这篇博文演示了如何使用InputStreamRequestBody(特别是原始的 Kotlin 端口)以这种方式上传内容。这篇博文提供了对同一问题和类似解决方案的另一种看法。


查看完整回答
反对 回复 2022-12-15
  • 1 回答
  • 0 关注
  • 158 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信