-
Android Application Development: Day 1-6: Building a Music App - Part 3: Activity Lifecycles
Welcome to the next lesson of the Android application development series. In this lesson, we will be discussing how to receive Intents and retrieve information from them.
Before we begin, there was a slight error in the previous lesson. Open up activity_main.xml and make the following changes:
button3's android:text value should be "three" not "four." Likewise, button4's android:text value should be "four" not "three."
Here are the corrections:
activity_main.xml
Before we begin, there was a slight error in the previous lesson. Open up activity_main.xml and make the following changes:
button3's android:text value should be "three" not "four." Likewise, button4's android:text value should be "four" not "three."
Here are the corrections:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="19dp" android:layout_marginTop="19dp" android:text="One" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/button2" android:layout_marginLeft="19dp" android:layout_toRightOf="@+id/button1" android:text="Three" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="38dp" android:text="Two" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button2" android:layout_alignBottom="@+id/button2" android:layout_alignLeft="@+id/button3" android:text="Four" /> </RelativeLayout>
Now that that has been sorted out, let's move on to the next bit:
Recall that in the last lesson, we started a SecondActivity by using one of four buttons, each of which contained a button number that was bundled with the intent.
Now, we will be retrieving this button number in the SecondActivity and playing the corresponding song. We will be discussing the Activity Lifecycle along the way!
Let's start with the code:
Recall how we created an Intent (a message that holds data about a desired action) in Day 5 (MainActivity) (check that yours is identical, or it will not work. Eclipse, for some reason, changed the key "BUTTON NUMBER" during packaging, so if you are running downloaded code, you may have to fix this):
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("BUTTON NUMBER", buttonNum);
startActivity(intent);
Now, in the bottom of the onCreate() method of the SecondActivity class, we add the following:
Intent intent = getIntent();
int number = intent.getIntExtra("BUTTON NUMBER", 1);
(Make sure you import Intent).
Let's make sure that we understand what the two lines here are doing:
getIntent() will retrieve the Intent that was used to start the current Activity (screen). This means that the intent we created in Day 5 will be retrieved.
Next, we store in the integer "number" the button number of the pressed button, providing a default value of 1 in case it fails.
To make sure this is retrieving the intent correctly, let's try changing the TextView's value of the SecondActivity.
This should be familiar to you, as I have previously demonstrated this.
Open the activity_second.xml file.
We will add an ID to the textView:
android:id="@+id/textView"
Recall that in the last lesson, we started a SecondActivity by using one of four buttons, each of which contained a button number that was bundled with the intent.
Now, we will be retrieving this button number in the SecondActivity and playing the corresponding song. We will be discussing the Activity Lifecycle along the way!
Let's start with the code:
Recall how we created an Intent (a message that holds data about a desired action) in Day 5 (MainActivity) (check that yours is identical, or it will not work. Eclipse, for some reason, changed the key "BUTTON NUMBER" during packaging, so if you are running downloaded code, you may have to fix this):
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("BUTTON NUMBER", buttonNum);
startActivity(intent);
Now, in the bottom of the onCreate() method of the SecondActivity class, we add the following:
Intent intent = getIntent();
int number = intent.getIntExtra("BUTTON NUMBER", 1);
(Make sure you import Intent).
Let's make sure that we understand what the two lines here are doing:
getIntent() will retrieve the Intent that was used to start the current Activity (screen). This means that the intent we created in Day 5 will be retrieved.
Next, we store in the integer "number" the button number of the pressed button, providing a default value of 1 in case it fails.
To make sure this is retrieving the intent correctly, let's try changing the TextView's value of the SecondActivity.
This should be familiar to you, as I have previously demonstrated this.
Open the activity_second.xml file.
We will add an ID to the textView:
android:id="@+id/textView"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".SecondActivity" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
Now go back to SecondActivity class.
Add the following in the bottom of the onCreate() method:
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText(String.valueOf(number));
Starting to understand how the casting works? We retrieve an object (a View) by it's ID (R.id.textView) and cast it as a TextView, and store it as tv.
Then we set the value of tv to number, which is converted to a String (setText cannot take in integers). As number represents the button that was pressed in the previous screen, the MainActivity, it will now show that number as the TextView's value:
Add the following in the bottom of the onCreate() method:
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText(String.valueOf(number));
Starting to understand how the casting works? We retrieve an object (a View) by it's ID (R.id.textView) and cast it as a TextView, and store it as tv.
Then we set the value of tv to number, which is converted to a String (setText cannot take in integers). As number represents the button that was pressed in the previous screen, the MainActivity, it will now show that number as the TextView's value:
Ta-da! It works as intended. Now rather than simply print it out, we will ask Android to play a music file.
I will use four pieces of royalty free music. I am a big fan of Matt McFarland's music, so we will use his!
http://www.mattmcfarland.com/
I downloaded the following four songs:
1. Nintendo was Cool
2. The Uncertain Hero
3. Strangled
4. Finding Happiness
For your convenience, I am providing a .zip version of the file, but if you like the music, check out Matt's site above!
If you have slow internet, just use four small .mp3 files that you can find online, and name them song1, song2, song3, and song4.
I will use four pieces of royalty free music. I am a big fan of Matt McFarland's music, so we will use his!
http://www.mattmcfarland.com/
I downloaded the following four songs:
1. Nintendo was Cool
2. The Uncertain Hero
3. Strangled
4. Finding Happiness
For your convenience, I am providing a .zip version of the file, but if you like the music, check out Matt's site above!
If you have slow internet, just use four small .mp3 files that you can find online, and name them song1, song2, song3, and song4.

day_6_music.zip | |
File Size: | 18880 kb |
File Type: | zip |
Extract the four files (using Alzip or Winrar or your extraction program of choice), and place them into the following directory inside your Application project: res/raw/.
Create a raw folder if necessary, like so:
Create a raw folder if necessary, like so:
Placing the files: |
Just to refresh our auto-generated R class, which is the class that provides a Java ID for each file in the res folder, go to Project > Clean, and clean the project.
This should make sure that we can reference our four new files without errors. Now, open up SecondActivity again. In the onCreate() method, we want to start playing the music. We will begin by adding the following. 1. Below the class declaration: public class SecondActivity extends Activity { Add: private MediaPlayer mPlayer; private int currentSong = 0; A MediaPlayer is used to play songs/video. We are creating a new one called mPlayer. We do not initialize it yet, because we need to initialize it with the song information. currentSong will keep track of the song that is playing right now, so that when the application pauses (user presses home button), it will remember which song was playing, so that you can resume it! Let's talk about the Activity Lifecycle. Recall that onCreate() is called immediately when the Activity starts. So, we will play the music in our onCreate() method: This is what it will look like. |
SecondActivity onCreate()
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Intent intent = getIntent(); int number = intent.getIntExtra("BUTTON NUMBER", 1); TextView tv = (TextView) findViewById(R.id.textView); tv.setText(String.valueOf(number)); if (number == 1) { mPlayer = MediaPlayer.create(SecondActivity.this, R.raw.song1); currentSong = R.raw.song1; } else if (number == 2) { mPlayer = MediaPlayer.create(SecondActivity.this, R.raw.song2); currentSong = R.raw.song2; } else if (number == 3) { mPlayer = MediaPlayer.create(SecondActivity.this, R.raw.song3); currentSong = R.raw.song3; } else if (number == 4) { mPlayer = MediaPlayer.create(SecondActivity.this, R.raw.song4); currentSong = R.raw.song4; // Defaults are always a good idea: } else { mPlayer = MediaPlayer.create(SecondActivity.this, R.raw.song1); currentSong = R.raw.song1; } mPlayer.start(); }
We use a series of if statements to determine which song to play. We even add a default value just in case something goes wrong. After loading up the MediaPlayer with the desired song, we call:
mPlayer.start();
Pretty straight forward.
Now here's the tricky part. What if the user pauses the app? Right now, if the user gets a call or if the user presses the home button, the music will continue to play. That is because we are not Overriding an onPause() method. So let's add one.
mPlayer.start();
Pretty straight forward.
Now here's the tricky part. What if the user pauses the app? Right now, if the user gets a call or if the user presses the home button, the music will continue to play. That is because we are not Overriding an onPause() method. So let's add one.
SecondActivity onPause()
@Override protected void onPause() { super.onPause(); if (mPlayer.isPlaying()) { mPlayer.pause(); } }
The onPause() method is called whenever the application is hidden from the user. Typically this is when the user opens another Activity (or presses Back to return to MainActivity). We will first call super.onPause() (this is required, because there are certain calls in the Activity.class's onPause method - the method we are overriding - that must be called for proper system function).
Then we simply check if mPlayer is playing before we pause it.
Now the music will pause when the user leaves the app, but what if he or she returns to it? Then onCreate method will NOT be called, as the Activity is not being created for the first time. Then we need to add the following method: onResume().
Then we simply check if mPlayer is playing before we pause it.
Now the music will pause when the user leaves the app, but what if he or she returns to it? Then onCreate method will NOT be called, as the Activity is not being created for the first time. Then we need to add the following method: onResume().
SecondActivity onResume()
@Override protected void onResume() { super.onResume(); if (mPlayer == null) { mPlayer = MediaPlayer.create(SecondActivity.this, currentSong); } mPlayer.start(); }
First, we make sure that our mPlayer is not null. As we are juggling resources around in our mobile device, sometimes large memory objects may get lost. If it is null, we simply create a new one with the currentSong - the song that was playing when the app was paused.
Then we simply call .start() again to resume.
Finally, we must help the system clean up a little bit in case the application closes. It will be good practice for us to do our own clean up and make sure system resources are available for other apps, so let's do that:
Then we simply call .start() again to resume.
Finally, we must help the system clean up a little bit in case the application closes. It will be good practice for us to do our own clean up and make sure system resources are available for other apps, so let's do that:
SecondActivity onStop()
@Override protected void onStop() { super.onStop(); if (mPlayer.isPlaying()) { mPlayer.stop(); } }
Same thing here. We call the super.onStop(), as the superclass's onStop method must be called to call critical methods upon Stopping an application. We will check if the mPlayer is playing, and then stop it, and everything will be ready to be disposed by Android.
Now when we run the application, it will handle music properly. When we pause and exit, it will cleanly stop the music as necessary. Now you have your first working media application!
I hope that you have learned a thing or two about Android from making this application (and enjoyed it too)! Specifically, you should be familiar with retrieving a View by its id (findViewById), casting it as a TextView or Button, and modifying it dynamically. You should also understand how layouts can be edited graphically or in XML, and be able to use Intents to open a new Activity. Finally, you should have a basic understanding of how the Activity Lifecycle works, and will be able to build on that in future lessons.
What do you want to learn next? Suggestions are welcome in the Forums.
Now when we run the application, it will handle music properly. When we pause and exit, it will cleanly stop the music as necessary. Now you have your first working media application!
I hope that you have learned a thing or two about Android from making this application (and enjoyed it too)! Specifically, you should be familiar with retrieving a View by its id (findViewById), casting it as a TextView or Button, and modifying it dynamically. You should also understand how layouts can be edited graphically or in XML, and be able to use Intents to open a new Activity. Finally, you should have a basic understanding of how the Activity Lifecycle works, and will be able to build on that in future lessons.
What do you want to learn next? Suggestions are welcome in the Forums.

Source Code:

day_6_source.zip | |
File Size: | 57921 kb |
File Type: | zip |
comments powered by Disqus