Android图库选择 - URI路径无效

时间:2014-08-14 19:25:47

标签: java android

我尝试在Android设备上的图库中实现多个图像选择。我按如下方式启动对话框:

Intent imageChoose = new Intent();
imageChoose.setType("image/*");
imageChoose.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
imageChoose.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(imageChoose, "Select Picture"), 1);

当我选择一个或多个图像' onActivityResult '触发,返回意图数据,uriString很奇怪。我已经在常规选择器意图与多选意图之间附加了数据的uriString变量之间的比较。我相信uriString的奇怪格式导致我的上传失败。任何的意见都将会有帮助。如果我发布更多信息,请告诉我。

Normal Picker Intent Data

Multi-select Picker Intent Data

编辑:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case PICK_FILE_ACTION:
                try {
                    if (data != null && data.getData() != null && resultCode == RESULT_OK) {
                        Uri selectedImageUri = data.getData();
                        String path = getRealPathFromUri(this, selectedImageUri);
                        filePickerCallback.onFilePicked(new File(path)); // sends file to upload code
                    }
                    else if (resultCode == RESULT_CANCELED) {
                        filePickerCallback.onCancelled();
                    }
                }
                catch (Exception e) {
                    Log.e(TAG, "Error getting file picker result", e);
                    filePickerCallback.onError();
                }
                break;

            case CAMERA_ACTION:
                try {
                    final File f = new File(mCurrentPhotoPath);
                    if (resultCode == RESULT_OK) {
                        onComplete = new Runnable() {
                            @Override
                            public void run() {
                                f.delete();
                            }
                        };
                        filePickerCallback.onFilePicked(f);
                    }
                    else if (resultCode == RESULT_CANCELED) {
                        f.delete();
                        filePickerCallback.onCancelled();
                    }
                }
                catch (Exception e) {
                    Log.e(TAG, "Error getting file picker result", e);
                    filePickerCallback.onError();
                }
                break;

            case MULTI_FILE_SELECT:
                try {
                    if (data != null && resultCode == RESULT_OK) {

                        ClipData clips = data.getClipData();

                        if(clips != null) {
                            for(int i = 0; i < clips.getItemCount(); i++) {
                                ClipData.Item item = clips.getItemAt(i);
                                Uri uri = item.getUri();
                                File imageFile = new File(uri.toString());
                                // process each file...
                            }
                        }
                        else {
                            // user only selected a single image
                            Uri uri = data.getData();
                            File imageFile = new File(uri.toString());
                            // process single file
                        }

                    } else if (resultCode == RESULT_CANCELED) {
                        filePickerCallback.onCancelled();
                    }
                } catch (Exception e) {
                    Log.e(TAG, "Error getting file picker result", e);
                    filePickerCallback.onError();
                }
                break;

            default:
                Log.w(TAG, "onActivityResult got unknown request code " + requestCode);
        }

        super.onActivityResult(requestCode, resultCode, data);
    }


public static String getRealPathFromUri(Activity activity, Uri contentUri) {
        if (contentUri.getScheme() != null && contentUri.getScheme().equals("file")) {
            return contentUri.getPath();
        }
        else {
            Cursor cursor = null;
            try {
                String[] filePathField = {MediaStore.Images.Media.DATA};
                cursor = activity.getContentResolver().query(contentUri, filePathField, null, null, null);
                if (cursor == null) {
                    throw new IllegalArgumentException("got null cursor when attempting to find path for external storage uri");
                }

                cursor.moveToFirst();
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                return cursor.getString(column_index);
            }
            finally {
                if (cursor != null) cursor.close();
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

Uri值不必指向您可以读取的本地文件资源。有各种可能的Uri方案,包括所有标准的互联网方案(例如http)。从内容选择器的角度来看,您将主要获得file://content://方案,并且随着时间的推移更多地返回批次

指向流的Uri方案的content://Uri方案的http://非常相似。既不一定指向某个本地文件。相反,您自己使用流本身{openInputStream() ContentResolver content://HttpUrlConnection http://getType()ContentResolvercontent://http:// 1 {} Uri content://上的http://,从http://的HTTP标头获取它,并为文件名制作自己的概念,因为可能没有一个可以从content://本身。

  

我喜欢深入研究这个令人费解的背后的原因

Uri流的存在与content://流存在的原因大致相同:进程间通信。碰巧大多数READ_EXTERNAL_STORAGE流用于在不同计算机之间传输数据,但情况并非如此。

在Android WRITE_EXTERNAL_STORAGE流的特定情况下,给定的http:// 可以指向可能在某处的外部存储上的普通文件如果您拥有相应的权限,则可以通过您的应用阅读。但是,content://流可以是:

  • 外部存储空间中的文件,但您没有{{1}}或{{1}},或

  • 来自应用程序的内部存储文件,该文件负责该文件(并且您无法访问其他应用程序&#39;内部存储空间),或

  • 需要解密的加密文件,或

  • 资产,原始资源,ZIP文件条目或其他需要从其他容器流式传输的内容,或

  • 存在于&#34;云中的文件&#34;提供商将在需要时下载到设备,或

  • 动态生成的内容,很多{{1}}流不必代表Web服务器上的某些物理文件

而且我确定还有其他情况,我并没有想到我的头脑。

简而言之,{{1}}是灵活的,而文件不是。