Question

I am building a simple image gallery app for android. I want the users to be able to pick images from it when they want to add an image to an SMS, an email, a chat application ... I have used intent filters in order to make my app appear in the app chooser menu when a user wants to add an image :

        <intent-filter>
            <action android:name="android.intent.action.GET_CONTENT" />
            <category android:name="android.intent.category.OPENABLE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*" />
            <data android:mimeType="vnd.android.cursor.dir/image" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PICK" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*" />
            <data android:mimeType="vnd.android.cursor.dir/image" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

Then the user is able to select an image, but I am looking for the best way to respond with it to the caller app.

I've been trying by storing the image as a temp file and sending the URI of that file

    public void respondWithImage(Bitmap bitmap){
    try {
        //If needed create temp folder
        File folder = new File(Environment.getExternalStorageDirectory() + "/temp/");
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File nomediaFile = new File(folder, ".nomedia");
        if (!nomediaFile.exists()) {
            nomediaFile.createNewFile();
        }

        //Create temp image file
        FileOutputStream out = new FileOutputStream(
                Environment.getExternalStorageDirectory()
                        + "/temp/temp.png");
        bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
        File bitmapFile = new File(
                Environment.getExternalStorageDirectory()
                        + "/temp/temp.png");

        //Tell parent activity to respond with the image
        if (bitmapFile.exists()) {
            Intent localIntent = new Intent().setData(Uri
                    .fromFile(bitmapFile));
            parentActivity.setResult(Activity.RESULT_OK, localIntent);
        } else {
            parentActivity.setResult(Activity.RESULT_CANCELED);
        }
        parentActivity.finish();

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("error", "Error writing data");
    }
}

This works but I wonder what it would do if the phone has no sdcard. I can't try that option because i got a GS3 which apparently considers its own memory as an ext card (correct me if I'm wrong)

I have also tried to send back an URI which points to a drawable resource (PNG file) from within my app, (it wouldnt be a problem in my case to have images in app resources) but it makes the calling app (MMS) crash and I don't catch the error in debugger.

What is the correct way to do that?

Was it helpful?

Solution

This works but I wonder what it would do if the phone has no sdcard

You are not using an "sdcard".

I can't try that option because i got a GS3 which apparently considers its own memory as an ext card (correct me if I'm wrong)

External storage normally is on-board flash, typically on the same partition that internal storage resides upon. While the documentation for external storage is not great, you may wish to review it.

I have also tried to send back an URI which points to a drawable resource (PNG file) from within my app... but it makes the calling app (MMS) crash and I don't catch the error in debugger.

You will not catch a crash from some third-party app in the debugger, as you are debugging your app, not the third-party app. LogCat may contain a stack trace, though.

What is the correct way to do that?

Use FileProvider, or perhaps my StreamProvider, to offer a ContentProvider for serving up your images. Your Uri would then be a content:// Uri. This should be supported by most apps, as images routinely come from content providers (e.g., email attachments).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top