4

I have three activities that I can call A, B and C. I want to pass information between the three like this: A-->B-->C-->A. In A I want to check if there is a bundle passed (the first time, start-up, there won't be one for example). The data is passed from A-B with a normal bundle. From B-->C I use this:

Intent i = new Intent(getApplicationContext(), FlashcardView.class);
             i.putExtra("rattning", rattning);
             i.putExtra("noqs", noqs);
             i.putExtra("categoryid", categoryid);
             CreateTestView.this.finish();
             startActivityForResult(i, 0);

It is received and then sent onwards to A like this:

  Intent data = new Intent(FlashcardView.this, MenuView.class);
                       data.putExtra("point", point);
                       data.putExtra("noqs", noqs);
                       setResult(RESULT_OK, data);
                       finish();

It is received at A like this:

 @Override 
   protected void onActivityResult( int req, int resp, Intent data ) {
        super.onActivityResult(req, resp, data);
        // process your received "data" from GameActivity ...
        Bundle b = getIntent().getExtras();
        noqs = b.getInt("noqs");
        point = b.getInt("point");
        mTvCat.setText("hhhhhh"+point+noqs);
        publishOnFacebook(point,noqs);
    }

It seems though like the bundle is lost on the way from C-->A. When I passed it back from C-->B there was no problem. I think this happens cause B is the activity that starts C, and therefore C falls back to B, not A. I made a go-around by calling finish() on B, so C goes back to A instead. BUt in doing this I lose the bundle. Or at least I think so.

Has anyone seen this before? Is there a better way of doing this? How can I prevent losing the bundle on a passing between more than two activities? THanks!

Edit:

Edit: Here is the error code on receiving the broadcast:

  03-07 12:57:59.394: ERROR/AndroidRuntime(803): java.lang.RuntimeException: Error receiving broadcast Intent { act=my_action (has extras) } in com.crystalcodeab.Flashcard.MenuView$1@47681ad0
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher$Args.run(ActivityThread.java:981)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at android.os.Handler.handleCallback(Handler.java:587)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at android.os.Looper.loop(Looper.java:143)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at android.app.ActivityThread.main(ActivityThread.java:5068)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at java.lang.reflect.Method.invokeNative(Native Method)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at java.lang.reflect.Method.invoke(Method.java:521)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at dalvik.system.NativeStart.main(Native Method)
03-07 12:57:59.394: ERROR/AndroidRuntime(803): Caused by: java.lang.NullPointerException
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at com.crystalcodeab.Flashcard.MenuView$1.onReceive(MenuView.java:56)
03-07 12:57:59.394: ERROR/AndroidRuntime(803):     at 
kakka47
  • 3,479
  • 8
  • 44
  • 52

3 Answers3

5

I think the problem lies in how you finish activity B. When you finish Activity B, the result from B is sent back to A and the Activity is gone. C has no way of knowing it should return its result to A, as it is only aware of Activity B.

My suggestion to you is that you should use a BroadcastReceiver in Activity A. Then in Activity C you can send a Broadcast with the data you wish to be received by A:

In A:

IntentFilter filter = new IntentFilter("my.action");
BroadcastReceiver receiver = new BroadcastReceiver() {
  public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals("my.action")) {
      // Do my stuff
    }
  }
}
registerReceiver(receiver, filter);

In C:

Intent data = new Intent("my.action");
data.putExtra("point", point);
data.putExtra("noqs", noqs);
sendBroadcast(data);
Eric Nordvik
  • 14,656
  • 8
  • 42
  • 50
  • This sounds right. But I still get a NullPointerException in A, the same as I did before. Is there a way to specify where the broadcast is going? Or is it "in the air" until a receiver is registered? – kakka47 Mar 07 '11 at 11:34
  • Could you post the line from logcat showing the NullPointerException? A broadcast is just sent into the air for anyone with the matching intentfilter to receive. You cannot specify where the broadcast is to be sent other than that. – Eric Nordvik Mar 07 '11 at 11:55
  • I read just now in the Developer docs that broadcast receiver doesn't have to be specified. I might have added the intent filters in an erroneous way, or not specified the receiver in the manifest correctly. – kakka47 Mar 07 '11 at 12:02
  • You do not need to specify a BroadcastReceiver in your manifest. It's perfectly ok to add the receiver in onCreate or some other method in your Activity. – Eric Nordvik Mar 07 '11 at 12:19
  • Now it works! Thanks a lot. If anyone else sees this question: I had to retrieve the intent like this: noqs = intent.getIntExtra("noqs", noqs); – kakka47 Mar 07 '11 at 16:46
  • Hi, I tried in the exact same way. But the receiver isn't getting invoked. am I missing something? My application is having [this Layout](http://stackoverflow.com/questions/14274110/how-to-validate-input-data-in-a-tab-on-tab-change). I want to pass my data from `tab#1 Activity` to `New Activity #2` using your example. The receiver is under `onCreate` Method of the `New Activity #2` and I am sending the broadcast from a button's `onClickListener` in `onCreate method` of `tab#1 activity`. – beerBear Jan 11 '13 at 09:02
0

You may wish to use Fragments instead of activities in your game and manage the state transition within the FragmentManager instead of trying to use the Activity stack. It seems like it might be a bit easier to manage.

Norman H
  • 2,248
  • 24
  • 27
0

When you finish activity B, why are you using a new Intent instead of the getIntent() method?

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
Sunil Pandey
  • 7,042
  • 7
  • 35
  • 48
  • I use a getIntent in B, collect the parameters sent from A. Then I start a new Intent and send parameters to C from B. Here I use the parameters, gather up new ones and want to send these to A. – kakka47 Mar 07 '11 at 10:07
  • see when u r at activity c which is called by B. if you are finishing activity c then onActivityResult of B will be called not of A. so proper way is to first finish activity C and then on onActivityResult of B call getIntent().getBundle() and then pass it to A and then finish B – Sunil Pandey Mar 07 '11 at 10:17
  • Yes I understand the logic of this. But it is a game and I don't want the user to pass activity B again. Maybe there is a way to do this without it showing visually? – kakka47 Mar 07 '11 at 10:39