2

This is my implicit intent to invoke image editing apps on the device:

startActivity(new Intent(Intent.ACTION_EDIT).setDataAndType(myUri,
     getMimeType(myUri)).setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | 
     Intent.FLAG_GRANT_WRITE_URI_PERMISSION));

And this is how I getMimeType:

public String getMimeType(Uri uri) {
    String mimeType = null;
    if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
        ContentResolver cr = getContentResolver();
        mimeType = cr.getType(uri);
    } else {
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
                .toString());
        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                fileExtension.toLowerCase());
    }
    return mimeType;
}

For some apps it crashes to load:

On the app Sketch_Camera only an invisible page loads up and disables interaction with my app.

On the app AirBrush it loads the app but crashes with this message "Failed to load image".

Is it related to minimum sdk version as mine is 16? I've tested this on minimum sdk version of 9 too and no change in result.

Is there anything else that I should add to this intent to work with all the apps?

I've tried putExtra too and it doesn't help:

.putExtra(Intent.ACTION_EDIT, myUri);

I've some gallery apps on my device and all of them launch Sketch_Camera and AirBrush without any problem.

What's happening here? I'm so confused after two days of struggling with this phenomena.

Eftekhari
  • 1,001
  • 1
  • 19
  • 37
  • 1
    What is the value of `myUri`? Why are you using `image/*` instead of the actual MIME type (as it is *your* content, so *you* know what the MIME type is)? – CommonsWare Jun 28 '16 at 10:55
  • myUri is a uri from an image file >> `Uri.fromFile(myFile)` and why I use `image/*` instead of actual MIME type? I picked the code up from stack. Now I've edited the question based on your guide. But still I get the same result. – Eftekhari Jun 28 '16 at 11:14
  • 1
    "myUri is a uri from an image file" -- and where is this file? `Intent.FLAG_GRANT_READ_URI_PERMISSION` and `Intent.FLAG_GRANT_WRITE_URI_PERMISSION` are useless in this case, as they do not pertain to `file` `Uri` values. – CommonsWare Jun 28 '16 at 11:36
  • "where is this file?" It's a file created from path of one media store file by querying `MediaStore.Images.Media.EXTERNAL_CONTENT_URI` – Eftekhari Jun 28 '16 at 11:53

1 Answers1

2

It's a file created from path of one media store file by querying MediaStore.Images.Media.EXTERNAL_CONTENT_URI

There is no guarantee that the other app has rights to this location, or even that your app has rights to this location. For example, the image could be on removable storage. Besides, the file Uri scheme is being banned for cross-app usage, anyway.

Use a content Uri instead. For example, in this sample app, I query MediaStore for videos. Given a Cursor named row positioned at a particular video, I generate the Uri for it via:

videoUri=
    ContentUris.withAppendedId(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI, row.getInt(row.getColumnIndex(MediaStore.Video.Media._ID)));

This Uri both works for my own purposes (e.g., hand to Picasso to get a thumbnail, hand to VideoView for playback) and for handing to third-party apps (e.g., ACTION_VIEW for playback).

Other than changing the base Uri to the one you queried against (MediaStore.Images.Media.EXTERNAL_CONTENT_URI), the same basic code should work for you.

Also, get rid of the flags from your Intent. Those are only for where the Intent points to your own ContentProvider, which is not the case in either your original code or with the Uri that you create from withAppendedId().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491