319

I'm very new on Android development.

I want to create and start an activity to show information about a game. I show that information I need a gameId.

How can I pass this game ID to the activity? The game ID is absolutely necessary so I don't want to create or start the activity if it doesn't have the ID.

It's like the activity has got only one constructor with one parameter.

How can I do that?

Thanks.

VansFannel
  • 45,055
  • 107
  • 359
  • 626

5 Answers5

548

Put an int which is your id into the new Intent.

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle b = new Bundle();
b.putInt("key", 1); //Your id
intent.putExtras(b); //Put your id to your next Intent
startActivity(intent);
finish();

Then grab the id in your new Activity:

Bundle b = getIntent().getExtras();
int value = -1; // or other values
if(b != null)
    value = b.getInt("key");
David
  • 15,894
  • 22
  • 55
  • 66
Wroclai
  • 26,835
  • 7
  • 76
  • 67
  • 45
    You may want to make sure b != null before you start grabbing from it – Andrew Oct 12 '10 at 15:03
  • How can "b" be null in second activity in this code? I get b is null on create method of second activity. – Murat Çorlu Aug 09 '11 at 23:18
  • 3
    B can be null, lets say you want to start this activity from another place and you do it the standard way, with no params. It will throw a NPE. You should always consider this params optional. – Gaspar de Elias Aug 16 '12 at 09:30
  • 58
    It is not necessary to create a new Bundle (and if you do [the documentation](http://developer.android.com/reference/android/content/Intent.html#putExtras%28android.os.Bundle%29) says you "must" use the package name to prefix your keys.) Simply use `intent.putExtra(String, Int)`. – Sam Oct 27 '12 at 19:32
  • 2
    One could argue that its better not to do a null check. https://en.wikipedia.org/wiki/Fail-fast. – setholopolus Apr 15 '18 at 23:11
  • @setholopolus One *could* argue that, but if the argument is optional then passing null is not an error. – Andreas Magnusson Apr 16 '18 at 11:29
  • @AndreasMagnusson I didn't realize the OP explicitly stated the argument is optional. Good call. – setholopolus Apr 17 '18 at 02:08
134

Just add extra data to the Intent you use to call your activity.

In the caller activity :

Intent i = new Intent(this, TheNextActivity.class);
i.putExtra("id", id);
startActivity(i);

Inside the onCreate() of the activity you call :

Bundle b = getIntent().getExtras();
int id = b.getInt("id");
Sam Hanley
  • 4,707
  • 7
  • 35
  • 63
DavGin
  • 8,205
  • 2
  • 19
  • 26
  • 1
    is it okay to pass in a custom object type ? – Amyth May 14 '15 at 10:46
  • 1
    @Amyth No, you have to use a bundle like in the accepted answer. – AtlasRider Oct 06 '16 at 20:39
  • See this @Amyth : http://stackoverflow.com/questions/14333449/passing-data-through-intent-using-serializable – Cold Jan 13 '17 at 12:38
  • This answer should have been the accepted one. The whole Bundle nonsense is unnecessary. – El Sushiboi Jul 15 '20 at 18:06
  • @Amyth looking at the signature of the API it looks like any custom types need to be parcelable or serialisable. Presumablly because the andriod activity API is designed on the assumptoin that the new activity may be in a differnet process. – plugwash Dec 04 '20 at 21:04
42

I like to do it with a static method in the second activity:

private static final String EXTRA_GAME_ID = "your.package.gameId";

public static void start(Context context, String gameId) {
    Intent intent = new Intent(context, SecondActivity.class);
    intent.putExtra(EXTRA_GAME_ID, gameId);
    context.startActivity(intent);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    ... 
    Intent intent = this.getIntent();
    String gameId = intent.getStringExtra(EXTRA_GAME_ID);
}

Then from your first activity (and for anywhere else), you just do:

SecondActivity.start(this, "the.game.id");
marcusshep
  • 1,916
  • 2
  • 18
  • 31
pomber
  • 23,132
  • 10
  • 81
  • 94
  • Exactly what I was looking for! Thank you – Lampione May 27 '16 at 09:27
  • 1
    In the onCreate method shouldn't `String gameId = intent.getStringExtra(EXTRA_EXTERNAL_ID);` be `String gameId = intent.getStringExtra(EXTRA_GAME_ID);` – marcusshep Nov 11 '16 at 16:36
  • Having statics will make Your testing very hard. – John Tribe Jan 27 '18 at 19:53
  • Is this a memory leak? Passing the context into a static method seems like a bad idea to me. Why not just return the intent and then start the activity using that intent from the first class? – AndroidDev Dec 17 '18 at 05:32
7

Kotlin code:

Start the SecondActivity:

startActivity(Intent(context, SecondActivity::class.java)
    .putExtra(SecondActivity.PARAM_GAME_ID, gameId))

Get the Id in SecondActivity:

class CaptureActivity : AppCompatActivity() {

    companion object {
        const val PARAM_GAME_ID = "PARAM_GAME_ID"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val gameId = intent.getStringExtra(PARAM_GAME_ID)
        // TODO use gameId
    }
}

where gameId is String? (can be null)

Francis
  • 6,788
  • 5
  • 47
  • 64
3

The existing answers (pass the data in the Intent passed to startActivity()) show the normal way to solve this problem. There is another solution that can be used in the odd case where you're creating an Activity that will be started by another app (for example, one of the edit activities in a Tasker plugin) and therefore do not control the Intent which launches the Activity.

You can create a base-class Activity that has a constructor with a parameter, then a derived class that has a default constructor which calls the base-class constructor with a value, as so:

class BaseActivity extends Activity
{
    public BaseActivity(String param)
    {
        // Do something with param
    }
}

class DerivedActivity extends BaseActivity
{
    public DerivedActivity()
    {
        super("parameter");
    }
}

If you need to generate the parameter to pass to the base-class constructor, simply replace the hard-coded value with a function call that returns the correct value to pass.

Trebor Rude
  • 1,904
  • 1
  • 21
  • 31