13

I am working on an activity and associated tasks that allow users to select an image to use as their profile picture from the Gallery. Once the selection is made the image is uploaded to a web server via its API. I have this working regular images from the gallery. However, if the image selected is from a Picasa Web Album nothing is returned.

I have done a lot of debugging and narrowed the problem down to this method.

public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    //cursor is null for picasa images
    if(cursor!=null)
    {
        int column_index = cursor
        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    else return null;
}

Picasa images return a null cursor. MediaStore.Images.Media.DATA is not null for them, however. It only returns an #id, so I am guessing that there is no actual bitmap data at the address. Are Picasa images stored locally on the device at all?

I also noticed from the documentation that MediaStore.Images.ImageColumns.PICASA_ID exists. This value exists for selected picasa images but not other gallery images. I was thinking I could use this value to get a URL for the image if it is not store locally but I can not find any information about it anywhere.

dbaugh
  • 203
  • 3
  • 7
  • Here is a complete, more accurate, working code for dsk 8-13: http://dimitar.me/how-to-get-picasa-images-using-the-image-picker-on-android-devices-running-any-os-version/ – Guy Jun 25 '12 at 10:10

2 Answers2

5

I have faced the exact same problem,
Finally the solution I found, was to launch an ACTION_GET_CONTENT intent instead of an ACTION_PICK, then make sure you provide a MediaStore.EXTRA_OUTPUT extra with an uri to a temporary file. Here is the code to start the intent :

public class YourActivity extends Activity {
    File mTempFile;
    int REQUEST_CODE_CHOOSE_PICTURE = 1;

    (...)
    public showImagePicker() { 
        mTempFile = getFileStreamPath("yourTempFile");
        mTempFile.getParentFile().mkdirs();
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
        intent.setType("image/*");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));
        intent.putExtra("outputFormat",Bitmap.CompressFormat.PNG.name());                       
        startActivityForResult(intent,REQUEST_CODE_CHOOSE_PICTURE);
    }

    (...)
}

You might need to mTempFile.createFile()

Then in onActivityResult, you will be able to get the image this way

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    case REQUEST_CODE_CHOOSE_PICTURE:
                Uri imageUri = data.getData();
                if (imageUri == null || imageUri.toString().length() == 0) {
                    imageUri = Uri.fromFile(mTempFile);
                    file = mTempFile;
                }
                                    if (file == null) {
                                       //use your current method here, for compatibility as some other picture chooser might not handle extra_output
                                    }
}

Hope this helps

Then you should delete your temporary file on finish (it is in internal storage as is, but you can use external storage, I guess it would be better).

darune
  • 959
  • 8
  • 13
  • What exactly is the file = mTempFile line doing? Where does file come from? Is that where the bitmap is stored? – dbaugh May 13 '11 at 20:10
  • it is initiated with : `mTempFile = getFileStreamPath("yourTempFile");` – darune May 14 '11 at 00:51
  • I understand the where mTempFile comes from. Where does the variable file come from? I don't see it set anywhere. – dbaugh May 14 '11 at 16:53
  • `getFileStreamPath("yourTempFile");` will create a file name 'yourTempFile' in your application directory (/data/app/package/files/yourTempFile). If you prefere you can initialize it with another path. this is just a simple way to get a file. The only thing that matter is to provide an uri to your intent so that you get the file filled when a picasa picture is chosen. – darune May 14 '11 at 17:42
  • So I have everything working. However, the Picasa images are being stored in "Downloads" within the Gallery after they have been selected. I tried calling a mTempFile.delete() after I get the bitmap I need but they still get saved. – dbaugh May 15 '11 at 19:56
  • didn't notice that, there might be a way to get the filename another way but, this seems so not polished and undocumented... – darune May 16 '11 at 09:43
  • yea this was definitely not an obvious fix. – dbaugh May 16 '11 at 19:41
  • I have used your code, mTempFile in my app is ever empty. Why? – Michel Foucault Jan 10 '12 at 22:50
  • are you using the stock galery as picture chooser ? – darune Jan 11 '12 at 17:16
  • I think this is broken on android 3.0 and up, see: http://code.google.com/p/android/issues/detail?id=21234 – sgarman Jan 31 '12 at 19:55
  • Does not work for me using a Picasa JPEG file on Android 2.3.3. I changed the output format to JPEG from PNG in the code above. The temp file provided in EXTRA_OUTPUT came out as 0 bytes. – Theo Feb 12 '12 at 05:14
  • Is there a way to do this while preserving the original filename of the file i'm copying? – android_student Mar 31 '15 at 20:39
1

Why are you using the managedQuery() method? That method is deprecated.

If you want to convert a Uri to a Bitmap object try this code:

public Bitmap getBitmap(Uri uri) {

    Bitmap orgImage = null;
    try {
        orgImage = BitmapFactory.decodeStream(getApplicationContext().getContentResolver().openInputStream(uri));
    } catch (FileNotFoundException e) {
        // do something if you want
    }
    return orgImage;
}
user
  • 86,916
  • 18
  • 197
  • 190
erkas
  • 11
  • 1
  • yes, this works for me.. when we get uri from intent it will save file in bitmap whether it comes from device gallery or from picasa image which in this case sends us "content://com.google.android.gallery3d". – Reshma Apr 08 '14 at 06:37