Aritra Roy
Aritra Roy

Reputation: 15625

startActivityForResult() not working for external Activity

This is not a duplicate question. I only found this question relevant but it doesn't have any working solution.

What I Have

I have two apps both created by me, App A and App B. My requirement is to open App B from App A on click of a button. Now, App B will do some processing and return a small status to App A. This should be possible isn't it?

What I Have Done

Intent intent = getActivity().getPackageManager().getLaunchIntentForPackage(Config._PACKAGE);
getActivity().startActivityForResult(intent, 6699);

This opens the App B perfectly. Now in App B,

 Intent returnIntent = new Intent();
 returnIntent.putExtra("STATUS", statusCode);
 setResult(RESULT_OK, returnIntent);
 finish();

And this is my onActivityResult() method on the Activity. I am starting the Activity from a Fragment though.

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.d(TAG, "ON ACTIVITY RESULT");

        if (requestCode == 6699) {

            if (resultCode == RESULT_OK) {

                Log.d(TAG, "RESULT OK");

            }
            if (resultCode == RESULT_CANCELED) {

                Log.d(TAG, "RESULT NOT OK");

            }
        }
    }

Problem

The onActivityResult() gets called just when I start the activity of App B with RESULT_CANCELLED. How is this possible? Is it because its a new task?

But when I call finish() on App B and it closes and takes me back to App A, but the onActivityResult() is not called this time? How can I solve this?

This is a very basic requirement and should have a solution.

Upvotes: 2

Views: 10693

Answers (2)

Aritra Roy
Aritra Roy

Reputation: 15625

I finally solved this problem.

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

This is what the docs says. Now the idea is that if the called activity is started on a new task, the result will be cancelled immediately. In my case, I am starting an activity from a different app altogether, which is always started in a new task, regardless of any launchMode or taskAffinity or flag.

Whenever I do something like this,

Intent intent = getActivity().getPackageManager().getLaunchIntentForPackage(Config._PACKAGE);
getActivity().startActivityForResult(intent, 6699);

this flag Intent.FLAG_ACTIVITY_NEW_TASK is automatically added by default. So, we need to clear all flags before starting the activity using,

intent.setFlags(0);

Use it before calling startActivity(). The solution was simple and tricky at the same time.

Upvotes: 4

PearsonArtPhoto
PearsonArtPhoto

Reputation: 39718

You really should add in a custom Intent Filter to make this happen. This will allow you to direct the flow for your task that you want Application B to do, separate from how you might use Application B. See Android docs Intent Filter for how to do this. Basically, you add a blurb into the manifest for Application B, something like this:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Application A will use something like this:

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

These of course will need to be customized for your application.

Upvotes: 1

Related Questions