4

EDIT: I wanted to update what the problem really is. On a Samsung phone you have "Gallery", inside "Gallery" you can also see your google photos backups. This is the photo selection I'm trying to get at. Now on other apps (Close5) they simply display a message stating "That photo is not supported". But why? Why can't we get this url (https:/lh3.googleusercontent) to work?

E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /https:/lh3.googleusercontent.com/-Llgk8Mqk-rI/U8LK0SMnpWI/AAAAAAAAFk4/0cktb59DnL8GgblJ-IJIUBDuP9MQXCBPACHM/I/IMG_20140711_085012.jpg: open failed: ENOENT (No such file or directory)

You can all clearly see this is a real photo with a real url:

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

Everything works fine until I go to select from photos or a google photos image instead of from the gallery, I tried handling the exception (Sorry, that image isn't supported. Try another gallery!) but that seems incomplete. I tried looking at other solutions on here but none of them worked for google photos. Thanks!

Error is a null pointer with:

app E/BitmapFactory: Unable to decode stream: 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;

}
Jitesh Prajapati
  • 2,533
  • 4
  • 29
  • 51
Petro
  • 3,484
  • 3
  • 32
  • 59
  • check this http://stackoverflow.com/questions/35429799/file-not-found-when-using-file-after-selecting-it-android/35431842#35431842 – saeed Mar 10 '16 at 06:56
  • you are chosen wrong way to chose to getpath of selected image .... you just check this answer http://stackoverflow.com/questions/35429799/file-not-found-when-using-file-after-selecting-it-android/35431842#35431842 to get right path of selected image... – saeed Mar 10 '16 at 07:12
  • combined multiple answers, works on everything except google related photos – Petro Mar 10 '16 at 07:28
  • can you check in which line app going to crash .... ? – saeed Mar 10 '16 at 07:35
  • `Bitmap rotatedBitmap = Bitmap.createBitmap(original_bitmap, 0, 0, original_bitmap.getWidth(), original_bitmap.getHeight(), matrix, true);` – Petro Mar 10 '16 at 07:43
  • google related photos means ... which return what type of uri...? – saeed Mar 10 '16 at 08:07
  • `java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/0/1/content://media/external/images/media/14399/NO_TRANSFORM/1950798869 flg=0x1 (has clip) }} to activity {com.shufflebuyapp/sign_up.SignUpParent}: java.lang.NullPointerException` – Petro Mar 10 '16 at 18:56
  • http://stackoverflow.com/questions/30527045/choosing-photo-using-new-google-photos-app-is-broken just try this – saeed Mar 11 '16 at 03:02

4 Answers4

10

Try getPathFromInputStreamUri(), this will fix the content uri problem from google photo app

Kotlin (UPDATED)

fun getPathFromInputStreamUri(context: Context, uri: Uri): String? {
    var filePath: String? = null
    uri.authority?.let {
        try {
            context.contentResolver.openInputStream(uri).use {
                val photoFile: File? = createTemporalFileFrom(it)
                filePath = photoFile?.path
            }
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    return filePath
}

@Throws(IOException::class)
private fun createTemporalFileFrom(inputStream: InputStream?): File? {
    var targetFile: File? = null
    return if (inputStream == null) targetFile
    else {
        var read: Int
        val buffer = ByteArray(8 * 1024)
        targetFile = createTemporalFile()
        FileOutputStream(targetFile).use { out ->
            while (inputStream.read(buffer).also { read = it } != -1) {
                out.write(buffer, 0, read)
            }
            out.flush()
        }
        targetFile
    }
}

private fun createTemporalFile(): File = File(getDefaultDirectory(), "tempPicture.jpg")

Java

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");
}
Arindam Karmakar
  • 156
  • 1
  • 2
  • 11
3

The Uri might be like this content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh3.googleusercontent.com%2FL-3Jm0TaSqnuKkitli5mK0-d

& its not of your local device. Local device's Uri will be like this

content://media/external/images/media/49518

Because of this difference your uriToPath(Uri uri) is returning null.

So check the Uri first & accordingly fetch image from local device or server.

You can use DocumentsProvider API so you won't have to worry about the local & server's files.

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

But if you have some local photos in Photos app then on selecting those you will get the local Uri, which will give you the correct file path.

You can also download the photos (which are on Google server) in Photos app itself & later use it.

Source:

Community
  • 1
  • 1
Petro
  • 3,484
  • 3
  • 32
  • 59
1

I don't see the Cursor object being created to pick image from Gallery, try this code

@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();
            }


        }
    }
}

Dialog Box to let user choose options:

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();
}
Veeresh Charantimath
  • 4,641
  • 5
  • 27
  • 36
  • When I take a photo it works, but nothing populates in my imageview from gallery, I'll have to play around more. I'll give you a bump in rep for now, I'll try to figure out the rest in the morning + mark this correct. Thanks! – Petro Mar 10 '16 at 06:36
0

I had proble with google photos app to pick and crop image. I solved this problem this way

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

find my complete solution here in stackoverflow post

Gaurav
  • 1,965
  • 2
  • 16
  • 32