Search code examples
androidandroid-intentonactivityresult

setContent() for finishing an Activity not working on API 16


I am building an app where I need to select pictures from gallery or take new one via the camera. I built three activities: one activity that shows selected/taken pictures, one to select pictures from memory as a gallery, and one to take new pictures with the camera. What I do is: when the user click a button to get more pictures, I open an intent chooser like this:

Intent galleryIntent = new Intent(Constants.INTENT_GALLERY);
Intent cameraIntent  = new Intent(Constants.INTENT_PHOTO_CAPTURE);

Intent chooserIntent 
            = Intent.createChooser(galleryIntent, getString(R.string.title_photo_chooser));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { cameraIntent });

startActivityForResult(chooserIntent, Constants.SUCCESS);

Then the gallery and the camera activity finish like so:

Intent intent = new Intent();

intent.putStringArrayListExtra(Constants.INTENT_KEY_PHOTO, selected);

setResult(RESULT_OK, intent);
finish();

And finally, the first activity, the viewer, gets the results like this:

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (resultCode == RESULT_OK){
        if( requestCode == Constants.SUCCESS ) {
            [...]
        }
    }
}

This has been proven successful on my cellphone with API 22. Unfortunately, when running on my tablet with API 16, in onActivityResult(), resultCode is never RESULT_OK, and intent is always null. I have seen many solutions like calling getParent().setResult(), but nothing seems to work.

Any tip would be useful. Thanks.

EDIT

I have analysed with a debugger the content of my activity in both version. Those states are the state of my Gallery activity just before the call to finish(). On API 22, I have this:

mParent = null
mResultCode = -1
mResultData = {Intent@5081} "Intent { (has extras) }"
    mAction = null
    mCategories = null
    mClipData = null
    mComponent = null
    mContentUserHint = -2
    mData = null
    mExtras = {Bundle@5134} "Bundle[{photo=[/storage/emulated/0/DCIM/Camera/....jpg, ...]}]"
    mFlags = 0
    mLaunchParams = {DualScreenLaunchParams@5135} "DualScreenLaunchParams { mScreen=UNKNOWN mFlags=0 }"
    mMultiWindowStyle = null
    mPackage = null
    mSelector = null
    mSourceBounds = null
    mType = null
    mWindowMode = 0
    mWindowPosition = null
    mWindowScale = 0.0
    shadow$_klass_ = {Class@1261} "class android.content.Intent"
    shadow$_monitor_ = -1875875432

On API 16, I have this:

mParent = null
mResultCode = -1
mResultData = {Intent@830041848224} "Intent { (has extras) }"
    mAction = null
    mCategories = null
    mClipData = null
    mComponent = null
    mData = null
    mExtras = {Bundle@830042231640} "Bundle[{photo=[/storage/sdcard0/Pictures/....jpeg, ...]}]"
    mType = null
    mPackage = null
    mSelector = null
    mSourceBounds = null
    mFlags = 0

There are differences but it seems setContent() did its job.


Solution

  • Finally, I got to the problem. The key was in the doc for startActivityForResult. It states:

    For example, if the activity you are launching uses the singleTask launch mode, it will not run in your task and thus you will immediately receive a cancel result.

    I was indeed using singleTask as a launch mode. I switched to singleTop and it worked. I am studying launch modes to have everything working out.