从图库或Google照片中选择图片失败

时间:2016-03-10 06:17:24

标签: java android android-gallery google-photos

  编辑:我想更新问题的真正原因。在三星   你有电话"画廊",里面"画廊"你也可以看到你的   谷歌照片备份。这是我试图获得的照片选择   在。现在在其他应用程序(Close5)上,他们只是显示一条消息说明   "不支持该照片"。但为什么?为什么我们不能得到这个网址   (/https:/lh3.googleusercontent)工作?

     

E / BitmapFactory:无法解码流:   java.io.FileNotFoundException:   /https:/lh3.googleusercontent.com/-Llgk8Mqk-rI/U8LK0SMnpWI/AAAAAAAAFk4/0cktb59DnL8GgblJ-IJIUBDuP9MQXCBPACHM/I/IMG_20140711_085012.jpg:   打开失败:ENOENT(没有这样的文件或目录)

你们都可以清楚地看到这是一张带有真实网址的真实照片:

的https:/lh3.googleusercontent.com/-Llgk8Mqk-rI/U8LK0SMnpWI/AAAAAAAAFk4/0cktb59DnL8GgblJ-IJIUBDuP9MQXCBPACHM/I/IMG_20140711_085012.jpg

一切正常,直到我从照片或谷歌照片图片中选择而不是从图库中选择,我尝试处理异常(Sorry, that image isn't supported. Try another gallery!),但这似乎不完整。我尝试在这里查看其他解决方案,但没有一个适用于谷歌照片。谢谢!

错误是一个空指针:

  

app E / BitmapFactory:无法解码流:   java.io.FileNotFoundException:/https:/lh3.googleusercontent

 @Override
    public void onActivityResult(int requestCode, int resultCode,
                                    Intent data) {
        if (resultCode != Activity.RESULT_CANCELED) {
                if (requestCode == 1) {
                    try{
                    String selectedImagePath = getAbsolutePath(data.getData());                          ((PostAdParentTabHost)getActivity()).getMap_of_picture_paths().put(1, selectedImagePath);                      
                    post_ad_camera_img_1.setImageBitmap(decodeSampledBitmapFromFileToCustomSize(selectedImagePath, 150, 150));
                    animation_master.fade(post_ad_camera_img_1);
                    }catch(Exception e){
                        e.printStackTrace();
                        ((PostAdParentTabHost)getActivity()).getMap_of_picture_paths().remove(requestCode);
                        Toast.makeText(getActivity(), "Sorry, that image isn't supported. Try another gallery! ", Toast.LENGTH_SHORT).show();
                    }

//------------------------------------------------------Methods:
public String getAbsolutePath(Uri uri) {
    Uri final_uri = uri;
        if (uri.getLastPathSegment().contains("googleusercontent.com")){
            final_uri = getImageUrlWithAuthority(getActivity(), uri);
            String[] projection = { MediaStore.MediaColumns.DATA };
            Cursor cursor = getActivity().getContentResolver().query(final_uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor
                        .getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            }else{

                return null;
            }
        }else{
        String[] projection = { MediaStore.MediaColumns.DATA };
        Cursor cursor = getActivity().getContentResolver().query(final_uri, projection, null, null, null);
        if (cursor != null) {
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }else{

            return null;
        }

    }

 public static Uri getImageUrlWithAuthority(Context context, Uri uri) {
    InputStream is = null;
    if (uri.getAuthority() != null) {
        try {
            is = context.getContentResolver().openInputStream(uri);
            Bitmap bmp = BitmapFactory.decodeStream(is);
            return writeToTempImageAndGetPathUri(context, bmp);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return null;
}

public static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

      public Uri setImageUri() {
        // Store image in dcim
        File file = new File(Environment.getExternalStorageDirectory()
                + "/DCIM/", "image" + new Date().getTime() + ".png");
        Uri imgUri = Uri.fromFile(file);
        this.image_as_uri_for_parcel = imgUri;
        this.imgPath = file.getAbsolutePath();
        return imgUri;

}

4 个答案:

答案 0 :(得分:2)

Uri可能就像这样content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh3.googleusercontent.com%2FL-3Jm0TaSqnuKkitli5mK0-d

&安培;它不是你的本地设备。本地设备的Uri将是这样的

内容://媒体/外部/图像/媒体/ 49518

由于这种差异,你的uriToPath(Uri uri)将返回null。

所以先检查一下Uri&因此从本地设备或服务器获取图像。

您可以使用DocumentsProvider API,这样您就不必担心本地&服务器的文件。

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
             getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
}

但是如果你在照片应用程序中有一些本地照片,那么在选择那些照片时你会获得当地的Uri,这将为你提供正确的文件路径。

您还可以在照片应用中自行下载照片(位于Google服务器上)&以后再用它。

来源:

答案 1 :(得分:1)

我没有看到创建Cursor对象来从Gallery中选择图像,请尝试使用此代码

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    callbackManager.onActivityResult(requestCode, resultCode, data);
    super.onActivityResult(requestCode, resultCode, data);

    //FROM CAMERA
    if (requestCode == 1) {
        if (resultCode == getActivity().RESULT_OK) {
            Bitmap bp = (Bitmap) data.getExtras().get("data");

            File fileDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Documents/Images/");


    }

    //FROM GALLERY
    else
    if (resultCode == getActivity().RESULT_OK && RESULT_LOAD_IMG == 2) {
        {
            File fileDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Documents/TWINE/");
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};

            // Get the cursor
            Cursor cursor = AppController.getInstance().getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            // Move to first row
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String imgDecodableString = cursor.getString(columnIndex);

            File fileGallery = new File(imgDecodableString);
            Bitmap bitmap = BitmapFactory.decodeFile(fileGallery.getAbsolutePath());


            cursor.close();

            // Set the Image in ImageView after decoding the String
            Log.d("Bitmap", "Bit");

            imageName = UUID.randomUUID().toString() + ".JPG";

            imagePath = fileDirectory + "/" + imageName;

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
            byte[] b = baos.toByteArray();

            File file = new File(fileDirectory, imageName);

            try {
                FileOutputStream out = new FileOutputStream(file);
                out.write(b);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }
}

允许用户选择选项的对话框:

private void selectImage() {
    final CharSequence[] items = { "Take Photo", "Choose from Gallery", "Cancel" };
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Add Photo!");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Take Photo")) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, 1);
            } else if (items[item].equals("Choose from Gallery")) {
                Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // Start the Intent
                startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}

答案 2 :(得分:1)

  

尝试 getPathFromInputStreamUri(),这将修复谷歌照片应用中的内容uri问题

public static String getPathFromInputStreamUri(Context context, Uri uri) {
    InputStream inputStream = null;
    String filePath = null;

    if (uri.getAuthority() != null) {
        try {
            inputStream = context.getContentResolver().openInputStream(uri);
            File photoFile = createTemporalFileFrom(inputStream);

            filePath = photoFile.getPath();

        } catch (FileNotFoundException e) {
            Logger.printStackTrace(e);
        } catch (IOException e) {
            Logger.printStackTrace(e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    return filePath;
}

private static File createTemporalFileFrom(InputStream inputStream) throws IOException {
    File targetFile = null;

    if (inputStream != null) {
        int read;
        byte[] buffer = new byte[8 * 1024];

        targetFile = createTemporalFile();
        OutputStream outputStream = new FileOutputStream(targetFile);

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

        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return targetFile;
}

private static File createTemporalFile() {
    return new File(Utils.getDefaultDirectory(), "tempPicture.jpg");
}

答案 3 :(得分:0)

我有谷歌照片应用程序挑选和裁剪图像的问题。 我用这种方式解决了这个问题

private void pickUserImage() { 

if (doHavePermission()) { 
    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    photoPickerIntent.setType("image/*");
    photoPickerIntent.putExtra("crop", "true");
    photoPickerIntent.putExtra("scale", true);
    photoPickerIntent.putExtra("outputX", 256);
    photoPickerIntent.putExtra("outputY", 256);
    photoPickerIntent.putExtra("aspectX", 1);
    photoPickerIntent.putExtra("aspectY", 1);
    photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
    startActivityForResult(photoPickerIntent, PICK_FROM_GALLERY);
    } 
}

在stackoverflow post中找到我的完整解决方案here