How to get startActivityForResult on external Activity to work?
Asked Answered
C

3

5

Searching high and low has yielded no result for my problem. Hence I'm finally posting to plead for some assistance.

I have two app, both written by me. App A launches App B, passing in parameters through Intent.putExtra(). This works perfectly fine when App B is launched the parameters are passed nicely.

However, I can't find a way to return a response to App A. Using startActivityForResult() always gave me immediate onActivityResult() with RESULT_CANCELED. Upon further inspection, the logcat gave me a warning stating "Activity is launching as a new task, so cancelling activity result".

I tried making Activity of App B with different launch mode, action filters (android.intent.action.PICK), but nothing I do changed anything.

Am I trying to do the impossible? From what I understand, what I am attempting to do should be similar to using third-party activity to pick pictures from the device's photo gallery.

EDIT:

Ok, I tried removing the LAUNCHER category from Activity B but it still doesn't work. Here's my activity:

<activity android:name=".${CLASSNAME}" android:label="@string/app_name" android:configChanges="mcc|mnc|locale|keyboardHidden|orientation" android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.PICK" />
    </intent-filter>
</activity>

Has anybody actually got this to work? I'm beginning to suspect starting an activity that is of another app can never return results since it seems it'll always start a new task no matter what you put in the "intent-filter".

Courtland answered 12/8, 2012 at 2:32 Comment(4)
post the code you are using build and launch the intent for ActivityB. you should be able to put something like this: this.setResult(Activity.RESULT_OK, data); in the second Activity to return back to the first.Gar
can you post your manifest file? Maybe Activity B has some special <activity> tagWhall
Hmmm... Activity B had the <category android:name="android.intent.category.LAUNCHER" /> Does this cause problem? I'm not at my work machine right now. I'll try removing that and see if that works. The thing is from what I've read, starting an activity that is not part of the same package will always start in a new task? If that is the case, startActivityForResult wouldn't work for starting an external activity on another apk?Courtland
I've tried removing the LAUNCHER category thing. Didn't work either. I've edited my original post on my activity manifest.Courtland
R
16

Make sure that the Activity you are launching doesn't have android:launchMode set on it in the manifest and check the android:taskAffinity is not being used. See here:

http://developer.android.com/guide/topics/manifest/activity-element.html#aff

Make sure that the Intent you are using to launch the activity doesn't have FLAG_ACTIVITY_NEW_TASK set on it. See here:

http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK

In particular note: "This flag can not be used when the caller is requesting a result from the activity being launched."

If the activity is being launched as part of a new task then Android will immediately call the onActivityResult() with RESULT_CANCELED because an activity in one task can't return results to another task, only activities in the same task can do so.

Rech answered 27/3, 2013 at 20:29 Comment(0)
T
3

Having the same issue I took a look at source code, and why the NEW_TASK flag would be added.

Turns out if either the source activity A or target activity B are using a single instance launch mode, NEW_TASK flag is automatically added:

    if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        // The original activity who is starting us is running as a single
        // instance...  this new activity it is starting must go on its
        // own task.
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        // The activity being started is a single instance...  it always
        // gets launched into its own task.
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }

As you own both apps you should be able to ensure those launch modes are not defined in manifest or intent.

So far I couldn't find any other instance of the NEW_TASK flag being set unwillingly.

Tulatulip answered 13/5, 2014 at 8:23 Comment(0)
S
0

In your activity B, you should have something like this,

Intent intent = new Intent();
setResult(Activity.RESULT_OK, intent);
finish();

or can be,

setResult(Activity.RESULT_OK);
finish();

where you don't need to pass any data to activity A.

Otherwise it will always finishes with the result code Activity.RESULT_CANCELED;

If a child activity fails for any reason (such as crashing), the parent activity will receive a result with the code RESULT_CANCELED.

Hope this helps.

Strawflower answered 12/8, 2012 at 5:13 Comment(4)
I did implement that. The problem is that activity A called onActivityResult() even before Activity B ended. Logcat gives me "Activity is launching as a new task, so cancelling activity result". So it seemed Activity B is launched as a new task, which shouldn't be surprising since it's a different apk app? How are utility activities like image picker written?Courtland
@Courtland as you mentioned you have the launcher category it will start the activity as new task. So it will be launched completely independent from the activity which launched it. Remove that category style and try. developer.android.com/reference/android/content/…Strawflower
Ah.. ok. I'll give it a try and report back when I get back to my work machine. :-) ThanksCourtland
I've tried removing the LAUNCHER category thing. Didn't work either. I've edited my original post on my activity manifest.Courtland

© 2022 - 2024 — McMap. All rights reserved.