Android Application Development Cookbook - Second Edition - Sample Chapter

Published on December 2016 | Categories: Documents | Downloads: 34 | Comments: 0 | Views: 364
of 29
Download PDF   Embed   Report

Chapter No. 1 ActivitiesOver 100 recipes to help you solve the most common problems faced by Android Developers todayFor More Information : http://bit.ly/225cdRj

Comments

Content

Fr

ee

Android Application Development Cookbook Second Edition

What this book will do
for you...
Along with Marshmallow, get hands-on

working with Google's new Android
Studio IDE
Develop applications using the latest

Android framework while maintaining
backward-compatibility with the
support library
Create exciting and engaging applications

using knowledge gained from recipes on
graphics, animations, and multimedia
Work through succinct steps towards

specifics that will help you complete
your project faster
Keep your app responsive (and prevent

ANRs) with examples of the AsyncTask
class
Utilize Google Speech Recognition APIs

Inside the Cookbook...
 A straightforward and easy-to-follow format
 A selection of the most important tasks

and problems

 Carefully organized instructions to solve

problems efficiently

 Clear explanations of what you did
 Solutions that can be applied to solve

Android Application Development Cookbook

This cookbook will make it easy for you to jump to a topic of interest and get what you need to implement
the feature in your own application. If you are new to Android and learn best by doing, then this book will
provide many topics of interest.

Second Edition

The Android OS has the largest installation base of any operating system in the world; there has never
been a better time to learn Android development to write your own applications, or to make your own
contributions to the open source community!

real-world problems

Prices do not include
local sales tax or VAT
where applicable

P U B L I S H I N G

Visit www.PacktPub.com for books, eBooks,
code, downloads, and PacktLib.

Rick Boyer
Kyle Mew

community experience distilled

P U B L I S H I N G

m

pl
e

Quick answers to common problems

Android Application
Development Cookbook
Second Edition

for your app.
$ 44.99 US
£ 28.99 UK

Sa

Over 100 recipes to help you solve the most common problems
faced by Android Developers today

Rick Boyer

Kyle Mew

In this package, you will find:





The authors biography
A preview chapter from the book, Chapter 1 'Activities'
A synopsis of the book’s content
More information on Android Application Development Cookbook
Second Edition

About the Authors
Rick Boyer is a senior software engineer with over 20 years of experience, including desktop,
web, and mobile development. His first PDA ignited a passion for mobile development, which
has extended to Windows CE, Windows Phone, and now Android. In 2011, he left the corporate
world to start his own consulting business, NightSky Development. He now focuses exclusively
on Android and provides consulting and development for start-ups and small businesses. Feel
free to contact him through his page, www.eBoyer.Net.

Kyle Mew has been programming since the early eighties and has written for several
technology websites. He has also written three radio plays and two other books on
Android development.

Preface
Android was first released in 2007 after being acquired by Google, Inc. Initially, Android was
primarily used on a handset. Android 3.0 added features to take advantage of the growing
tablet market.
In 2014, Google announced that Android had over 1 billion active users! With over 1 million
applications available on Google Play, there's never been a more exciting time to join the
Android community!
As we begin 2016, we have the recently released Android 6.0 with exciting new features for
both users and developers.

What this book covers
Chapter 1, Activities, discusses Activities, which represent the fundamental building blocks for
most applications. See examples of the most common tasks, such as creating an activity and
passing control from one activity to another.
Chapter 2, Layouts, talks about Layout options; while Activities are fundamental to the UI,
the layout actually defines what the user sees on the screen. Learn the main layout options
available and best practices.
Chapter 3, Views, Widgets, and Styles, explores the basic UI object, from which all layouts
are built. Widgets include everything from buttons and textboxes to more complicated
NumberPicker and Calendar dialogs.
Chapter 4, Menus, teaches you how to use menus in Android. Learn how to create menus and
how to control their behavior at runtime.
Chapter 5, Exploring Fragments, AppWidgets, and the System UI, shows how to create more
flexible user interfaces by reusing UI components with Fragments. Take advantage of new OS
features with translucent system bars or even make the System UI go away completely with
Immersive Mode.

Preface
Chapter 6, Working with Data, helps you discover multiple methods that Android offers for
persisting data, and know when it is the best to use each option. The Loader class example
shows an efficient solution to present the data without tying up the UI Thread.
Chapter 7, Alerts and Notifications, shows multiple options for displaying notifications to your
users. Options range from alerts in your application, using the system notification, and the
Heads Up notification.
Chapter 8, Using the Touchscreen and Sensors, helps you learn the events for handling
the standard user interactions, such as button clicks, long presses, and gestures. Access
the device hardware sensors to determine orientation changes, device movement, and
compass bearing.
Chapter 9, Graphics and Animation, helps you bring your app to life with animations!
Take advantage of the many options Android offers for creating animations—from simple
bitmaps to custom property animations.
Chapter 10, A First Look at OpenGL ES, discusses the OpenGL; when you need
high-performance 2D and 3D graphics, turn to the Open Graphics library. Android
supports OpenGL, a cross-platform Graphics API.
Chapter 11, Multimedia, takes advantage of the hardware features for playing audio. Use
Android intents to call the default camera application or delve into the camera APIs to control
the camera directly.
Chapter 12, Telephony, Networks, and the Web, uses the Telephony functions to initiate a
phone call and to listen for incoming phone events. See how to send and receive SMS (text)
messages. Use the WebView in your application to display web pages and learn how to use
Volley to communicate directly with web services.
Chapter 13, Getting Location and Using Geofencing, shows you how to determine the user's
location and the best practices so your app doesn't drain the battery. Use the new Location
APIs to receive location updates and create Geofences.
Chapter 14, Getting Your App Ready for the Play Store, helps you polish your app for the Play
Store and learn how to implement more advanced features, such as alarms and AsyncTask for
background processing. See how to add Google Cloud Messaging (push notification) to your
app and take advantage of Google Sign-in.
Chapter 15, The Backend as a Service Options, explores what a Backend as a Service
provider can offer your app. Compare several top providers offering native Android support
and free subscription options.

Chapter 1

1

Activities
This chapter covers the following recipes:


Declaring an activity



Starting a new activity with an intent object



Switching between activities



Passing data to another activity



Returning a result from an activity



Saving an activity's state



Storing persistent activity data



Understanding the activity lifecycle

Introduction
The Android SDK provides a powerful tool to program mobile devices, and the best way to
master such a tool is to jump right in. Though you can read this book from beginning to end,
as it is a cookbook, it is specifically designed to allow you to jump to specific tasks and get
the results immediately.
Activities are the fundamental building block of most Android applications as the activity
class provides the interface between the application and screen. Most Android applications
will have at least one activity, if not several (but they are not required). A background service
application will not necessarily require an activity if there is no user interface.
This chapter explains how to declare and launch activities within an application and how to
manage several activities at once by sharing data between them, requesting results from
them, and calling one activity from within another.

1

Activities
This chapter also briefly explores the intent object, which is often used in conjunction with
activities. Intents can be used to transfer data between activities in your own application,
as well as in external applications, such as those included with the Android operating system
(a common example would be to use an intent to launch the default web browser).
To begin developing Android applications, head over to the Android Studio
page to download the new Android Studio IDE and the Android SDK bundle:
http://developer.android.com/sdk/index.html

Declaring an activity
Activities and other application components, such as services, are declared in the
AndroidManifest XML file. Declaring an activity is how we tell the system about our activity
and how it can be requested. For example, an application will usually indicate that at least
one activity should be visible as a desktop icon and serve as the main entry point to the
application.

Getting ready
Android Studio is the new tool used to develop Android applications, replacing the nowdeprecated Eclipse ADT solution. Android Studio will be used for all the recipes shown in this
book, so if you have not already installed it, visit the Android Studio website (the link has been
provided earlier) to install the IDE and the SDK bundle.

How to do it...
For this first example, we'll guide you through creating a new project. Android Studio provides a
Quick Start wizard, which makes the process extremely easy. Follow these steps to get started:
1. Launch Android Studio, which brings up the Welcome to Android Studio dialog.
2. Click on the Start a new Android Studio project option.
3. Enter an application name; for this example, we have used DeclareAnActivity.
Click on Next.
4. On the Add an Activity to Mobile dialog, click on the Blank Activity button, and then
click on Next.
5. On the Target Android Devices dialog, chose Android 6.0 (API 23) as the minimum
SDK (for this example, it really doesn't matter which API level you chose, as activities
have existed since API level 1, but choosing the latest release is considered to be the
best practice). Click on Next.

2

Chapter 1
6. Since we chose the Blank Activity option earlier, the Customize the Activity dialog is
shown. You can leave the defaults as provided, but note the default activity name is
MainActivity. Click on Finish.
After finishing the wizard, Android Studio will create the project files. For this recipe, the two
files that we will examine are MainActivity.java (which corresponds to the activity name
mentioned in Step 6) and AndroidManifest.xml.
If you take a look at the MainActivity.java file, you will realize that it's pretty basic. This is
because we chose the Blank Activity option (in Step 4). Now look at the AndroidManifest.
xml file. This is where we actually declare the activity. Within the <application> element is
the <activity> element:
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name=
"android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

When viewing this xml within Android Studio, you may notice that the label
element shows the actual text as defined in the strings.xml resource
file. This is just a small example of enhancements in the new IDE.

How it works...
Declaring an activity is a simple matter of declaring the <activity> element and specifying
the name of the activity class with the android:name attribute. By adding the <activity>
element to the Android Manifest, we are specifying our intention to include this component
within our application. Any activities (or any other component for that matter) that are not
declared in the manifest will not be included in the application. Attempting to access or utilize
an undeclared component will result in an exception being thrown at runtime.
In the preceding code, there is another attribute—android:label. This attribute indicates
the title shown on the screen as well as the icon label if this is the Launcher activity.
For a complete list of available application attributes, take a look at
this resource:
http://developer.android.com/guide/topics/
manifest/activity-element.html
3

Activities

Starting a new activity with an intent object
The Android application model can be seen as a service-oriented one, with activities as
components and intents as the messages sent between them. Here, an intent is used to start
an activity that displays the user's call log, but intents can be used to do many things and we
will encounter them throughout this book.

Getting ready
To keep things simple, we are going to use an intent object to start one of Android's built-in
applications rather than create a new one. This only requires a very basic application, so start
a new Android project with Android Studio and call it ActivityStarter.

How to do it...
Again, to keep the example simple so that we can focus on the task at hand, we will create a
function to show an intent in action and call this function from a button on our activity.
Once your new project is created in Android Studio, follow these steps:
1. Open the MainActivity.java class and add the following function:
public void launchIntent(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.packtpub.com/"));
startActivity(intent);
}

While you are typing this code, Android Studio will give this warning on View and
intent: Cannot resolve symbol 'Intent'.
This means that you need to add the library reference to the project. You can do this
manually by entering the following code in the import section:
import android.view.View;
import android.content.Intent;

Alternatively, just click on the words (in the red font), hit Alt + Enter, and let Android
Studio add the library reference for you.
2. Open the activity_main.xml file and add the following XML:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Launch Browser"
4

Chapter 1
android:id="@+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:onClick="launchIntent"/>

3. Now it's time to run the application and see the intent in action. You will need to
either create an Android emulator (in Android Studio, go to Tools | Android | AVD
Manager) or connect a physical device to your computer.
4. When you press the Launch Browser button, you will see the default web browser
open with the URL specified.

How it works...
Though simple, this app demonstrates much of the power behind the Android OS. The intent
object is just a message object. Intents can be used to communicate across your application's
components (such as services and broadcast receivers) as well as with other applications on
the device (as we did in this recipe).
To test on a physical device, you may need to install drivers for your device (the
drivers are specific to the hardware manufacturer). You will also need to enable
Developer Mode on your device. Enabling Developer Mode varies according to
the Android OS version. If you do not see the Developer Mode option in your
device settings, open the About Phone option and begin tapping Build Number.
After three taps, you should see a Toast message telling you that you are on your
way to be a developer. Four more taps will enable the option.

5

Activities
In this recipe, we created an intent object by specifying ACTION_VIEW as what we want to do
(our intention). You may have noticed that when you typed Intent and then the period, Android
Studio provided a pop-up list of possibilities (this is the autocomplete feature), like this:

ACTION_VIEW, along with a URL in the data, indicates that the intention is to view the website,

so the default browser is launched (different data could launch different apps). In this example,
our intent is just to view the URL, so we call the intent with just the startActivity() method.
There are other ways to call the intent depending on our needs. In the Returning a result from
an activity recipe, we will use the startActivityForResult() method.

There's more...
It's very common for Android users to download their favorite apps for web browsing, taking
photos, text messaging, and so on. Using intents, you can let your app utilize your user's
favorite apps instead of trying to reinvent all of this functionality.

See also
To start an activity from a menu selection, refer to the Handling menu selections recipe in
Chapter 4, Menus.

Switching between activities
Often we will want to activate one activity from within another activity. Although this is not
a difficult task, it will require a little more setting up to be done than the previous recipes
as it requires two activities. We will create two activity classes and declare them both in the
manifest. We'll also create a button, as we did in the previous recipe, to switch to the activity.

6

Chapter 1

Getting ready
We'll create a new project in Android Studio, just as we did in the previous recipes, and call
this one ActivitySwitcher. Android Studio will create the first activity, ActivityMain,
and automatically declare it in the manifest.

How to do it...
1. Since the Android Studio New Project wizard has already created the first activity,
we just need to create the second activity. Open the ActivitySwitcher project and
navigate to File | New | Activity | Blank Activity, as shown in this screenshot:

7

Activities
2. In the Customize the Activity dialog, you can leave the default Activity Name as it is,
which is Main2Activity, or change it to SecondActivity, as shown here:

3. Open the MainActivity.java file and add the following function:
public void onClickSwitchActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}

4. Now, open the activity_main.xml file located in the \res\layout folder and
add the following XML to create the button:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

8

Chapter 1
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:text="Launch SecondActivity"
android:onClick="onClickSwitchActivity"/>

5. You can actually run the code at this point and see the second activity come up.
We're going to go further and add a button to SecondActivity to close it, which
will bring us back to the first activity. Open the SecondActivity.java file and
add this function:
public void onClickClose(View view) {
finish();
}

6. Finally, add the Close button to the SecondActivity layout. Open the
activity_second.xml file and add the following <Button> element
just after the <TextView> element that was generated automatically:
<Button
android:id="@+id/buttonClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:onClick="onClickClose"/>

7.

Run the application on your device or emulator and see the buttons in action.

How it works...
The real work of this exercise is in the onClickSwitchActivity() method from Step 3.
This is where we declare the second activity for the intent using SecondActivity.class.
We went one step further by adding the close button to the second activity to show a common
real-world situation—launching a new activity, then closing it, and returning to the original
calling activity. This behavior is accomplished in the onClickClose() function. All it does
is call finish(), but that tells the system that we're done with the activity. Finish doesn't
actually return us to the calling activity or any specific activity for that matter; it just closes the
current activity and relies on the back stack. If we want a specific activity, we can again use
the intent object (we just change the class name while creating the intent).
This activity switching does not make a very exciting application. Our activity does nothing
but demonstrate how to switch from one activity to another, which of course will form a
fundamental aspect of almost any application that we develop.

9

Activities
If we had manually created the activities, we would need to add them to the manifest. By
using these steps, Android Studio has already taken care of the XML. To see what Android
Studio did, open the AndroidManifest.xml file and look at the <application> element:
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER/>
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="@string/title_activity_second">
</activity>

One thing to note in the preceding autogenerated code is that the second activity does not
have the <intent-filter> element. The main activity is generally the entry point when
starting the application. That's why MAIN and LAUNCHER are defined—so that the system
will know which activity to launch when the application starts.

See also


To learn more about embedding widgets such as the Button, visit Chapter 3, Views,
Widgets, and Styles.

Passing data to another activity
The intent object is defined as a messaging object. As a message object, its purpose is to
communicate with other components of the application. In this recipe, we'll show you how
to pass information with the intent and how to get it out again.

Getting ready
This recipe will pick up from where the previous one ended. We will call this project SendData.

How to do it...
Since this recipe is building on the previous recipe, most of the work is already done.
We'll add an EditText element to the main activity so that we have something to send to
SecondActivity. We'll use the (autogenerated) TextView view to display the message.
Here are the complete steps:
10

Chapter 1
1. Open activity_main.xml, remove the existing <TextView> element, and add
the following <EditText> element:
<EditText
android:id="@+id/editTextData"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

The <Button> element that we created in the previous recipe doesn't change.
2. Now, open the MainActivity.java file and change the
onClickSwitchActivity() method as follows:
public void onClickSwitchActivity(View view) {
EditText editText = (EditText)findViewById(R.id.editTextData);
String text = editText.getText().toString();
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra(Intent.EXTRA_TEXT,text);
startActivity(intent);
}

3. Next, open the activity_second.xml file and modify the<TextView> element to
include the ID attribute:
<TextView
android:id="@+id/textViewText"
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

4. The last change is to edit the second activity to look for this new data and display it
on the screen. Open SecondActivity.java and edit onCreate() as follows:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView textView = (TextView)findViewById(
R.id.textViewText);
if (getIntent()!=null && getIntent().hasExtra(
Intent.EXTRA_TEXT)) {
textView.setText(getIntent().getStringExtra(
Intent.EXTRA_TEXT));
}
}

5. Now run the project. Type some text on the main activity and press Launch Second
Activity to see it send the data.

11

Activities

How it works...
As expected, the intent object is doing all the work. We created an intent just as in the
previous recipe and then added some extra data. Did you notice the putExtra() method
call? In our example, we used the already defined Intent.EXTRA_TEXT as the identifier,
but we didn't have to. We can use any key we want (you've seen this concept before if you're
familiar with name/value pairs).
The key point about using name/value pairs is that you have to use the same name to get the
data back out. That's why we used the same key identifier when we read the extra data with
getStringExtra().
The second activity was launched with the intent that we created, so it's simply a matter of
getting the intent and checking for the data sent along with it. We do this in onCreate():
textView.setText(getIntent().getStringExtra(Intent.EXTRA_TEXT));

There's more...
We aren't limited to just sending String data. The intent object is very flexible and already
supports basic data types. Go back to Android Studio and click on the putExtra method.
Then hit Ctrl and the Spacebar. Android Studio will bring up the autocomplete list so that
you can see the different data types that you can store.

Returning a result from an activity
Being able to start one activity from another is all well and good, but we will often need
to know how the called activity has fared in its task or even which activity has been called.
The startActivityForResult() method provides the solution.

Getting ready
Returning a result from an activity is not very different from the way we just called the activity
in the previous recipes. You can either use the project from the previous recipe, or start a new
project and call it GettingResults. Either way, once you have a project with two activities
and the code needed to call the second activity, you're ready to begin.

How to do it...
There are only a few changes needed to get the results:
1. First of all, open MainActivity.java and add the following constant to the class:
public static final String REQUEST_RESULT="REQUEST_RESULT";
12

Chapter 1
2. Next, change the way the intent is called by modifying the
onClickSwitchActivity() method to expect a result:
public void onClickSwitchActivity(View view) {
EditText editText = (EditText)findViewById(
R.id.editTextData);
String text = editText.getText().toString();
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra(Intent.EXTRA_TEXT,text);
startActivityForResult(intent,1);
}

3. Then, add this new method to receive the result:
@Override
protected void onActivityResult(int requestCode, int
resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode==RESULT_OK) {
Toast.makeText(this, Integer.toString(
data.getIntExtra(REQUEST_RESULT, 0)),
Toast.LENGTH_LONG).show();
}
}

4. Finally, modify onClickClose in SecondActivity.java to set the return value
as follows:
public void onClickClose(View view) {
Intent returnIntent = new Intent();
returnIntent.putExtra(MainActivity.REQUEST_RESULT,42);
setResult(RESULT_OK, returnIntent);
finish();
}

How it works...
As you can see, getting the results back is relatively straightforward. We just call the
intent with startActivityForResult, so it knows that we want a result. We set up the
onActivityResult() callback handler to receive the results. Finally, we make sure that
the second activity returns a result with setResult() before closing the activity. In this
example, we are just setting a result with a static value. We just display what we receive to
demonstrate the concept.

13

Activities
It's good practice to check the result code to make sure that the user didn't cancel the
action. It's technically an integer, but the system uses it as a boolean value. Check for either
RESULT_OK or RESULT_CANCEL and proceed accordingly. In our example, the second activity
doesn't have a cancel button, so why bother to check? What if the user hits the back button?
The system will set the result code to RESULT_CANCEL and the intent to null, which will cause
our code to throw an exception.
We made use of the Toast object, which is a convenient pop-up message that can be used to
unobtrusively notify the user. It also functions as a handy method for debugging as it doesn't
need a special layout or screen space.

There's more...
Besides the result code, onActivityResults() also includes a Request Code. Are you
wondering where that came from? It is simply the integer value that was passed with the
startActivityForResult() call, which takes this form:
startActivityForResult(Intent intent, int requestCode);

We didn't check the request code because we knew we had only one result to handle—but
in trivial applications with several activities, this value can be used to identify where the
request originated.
If startActivityForResult() is called with a negative request code,
it will behave exactly as if it were a call to startActivity()—that is, it
will not return a result.

See also


To learn more about creating new activity classes, refer to the Switching between
activities recipe



For more information about Toasts, check out the Making a Toast recipe in Chapter 7,
Alerts and Notifications

Saving an activity's state
The mobile environment is very dynamic, with users changing tasks much more often than
on desktops. With generally fewer resources on a mobile device, it should be expected that
your application will be interrupted at some point. It's also very possible that the system will
shut down your app completely to give additional resources to the task at hand. It's the
nature of mobiles.

14

Chapter 1
A user might start typing something in your app, be interrupted by a phone call, or switch
over to another app to send a text message, and by the time they get back to your app, the
system may have closed it down completely to free up the memory. To provide the best user
experience, you need to expect such behavior and make it easier for your user to resume
from where they left off. The good thing is that the Android OS makes this easier by providing
callbacks to notify your app of state changes.
Simply rotating your device will cause the OS to destroy and recreate
your activity. This might seem a bit heavy-handed, but it's done for
good reason—it's very common to have different layouts for portrait and
landscape, so this ensures that your app is using the correct resources.

In this recipe, you'll see how to handle the onSaveInstanceState() and
onRestoreInstanceState() callbacks to save your application's state. We will
demonstrate this by creating a counter variable and increment it each time the Count
button is pressed. We will also have an EditText and a TextView widget to see their
default behavior.

Getting ready
Create a new project in Android Studio and name it StateSaver. We need only a single
activity, so the autogenerated main activity is sufficient. However, we will need a few widgets,
including EditText, Button, and TextView. Their layout (in activity_main.xml) will
look like this:
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Count"
android:onClick="onClickCounter"/>
<TextView
android:id="@+id/textViewCounter"

15

Activities
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button"/>

How to do it...
Perform the following set of steps:
1. To keep track of the counter, we need to add a global variable to the project, along
with a key for saving and restoring. Add the following code to the MainActivity.
java class:
static final String KEY_COUNTER = "COUNTER";
private int mCounter=0;

2. Then add the code needed to handle the button press; it increments the counter and
displays the result in the TextView widget:
public void onClickCounter(View view) {
mCounter++;
((TextView)findViewById(R.id.textViewCounter)).setText(
"Counter: " + Integer.toString(mCounter));
}

3. To receive notifications of application state change, we need to add the
onSaveInstanceState() and onRestoreInstanceState() methods
to our application. Open MainActivity.java and add the following:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_COUNTER,mCounter);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCounter=savedInstanceState.getInt(KEY_COUNTER);
}

4. Run the program and try changing the orientation to see how it behaves (if you're
using the emulator, Ctrl + F11 will rotate the device).

16

Chapter 1

How it works...
All activities go through multiple states during their lifetime. By setting up callbacks to handle
the events, we can have our code save important information before the activity is destroyed.
Step 3 is where the actual saving and restoring occurs. The system sends a
Bundle (a data object that also uses name/value pairs) to the methods. We use
the onSaveInstanceState() callback to save the data and pull it out in the
onRestoreInstanceState() callback.
But wait! Did you try typing text in the EditText view before rotating the device? If so, you'd
have noticed that the text was also restored, but we don't have any code to handle that view.
By default, the system will automatically save the state, provided it has a unique ID (not all
views automatically have their state saved, such as the TextView, but we can manually save
it if we want).
Note that if you want Android to automatically save and restore the state of
a view, it must have a unique ID (specified with the android:id= attribute
in the layout). Beware; not all view types automatically save and restore the
state of a view.

There's more...
The onRestoreInstanceState() callback is not the only place where the state can be
restored. Look at the signature of onCreate():
onCreate(Bundle savedInstanceState)

Both methods receive the same Bundle instance named savedInstanceState. You
could move the restore code to the onCreate() method and it would work the same.
But one catch is that the savedInstanceState bundle will be null if there is no data,
such as during the initial creation of the activity. If you want to move the code from the
onRestoreInstanceState() callback, just check to make sure that the data is not
null, as follows:
if (savedInstanceState!=null) {
mCounter = savedInstanceState.getInt(KEY_COUNTER);
}

See also


The Storing persistent activity data recipe will introduce persistent storage.



Take a look at Chapter 6, Working with Data, for more examples on Android activities.



The Understanding the activity lifecycle recipe explains the Android Activity Lifecycle.
17

Activities

Storing persistent activity data
Being able to store information about our activities on a temporary basis is very useful, but more
often than not, we will want our application to remember information across multiple sessions.
Android supports SQLite, but that could be a lot of overhead for simple data, such as the
user's name or a high score. Fortunately, Android also provides a lightweight option for these
scenarios, with SharedPreferences.

Getting ready
You can either use the project from the previous recipe or start a new project and call it
PersistentData (in a real-world application, you'll likely be doing both anyway). In the
previous recipe, we saved mCounter in the session state. In this recipe, we'll add a new
method to handle onPause() and save mCounter to SharedPreferences. We'll
restore the value in onCreate().

How to do it...
We have only two changes to make, and both are in MainActivity.java:
1. Add the following onPause() method to save the data before the activity closes:
@Override
protected void onPause() {
super.onPause();
SharedPreferences settings = getPreferences(
MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putInt(KEY_COUNTER, mCounter);
editor.commit();
}

2. Then add the following code at the end of onCreate() to restore the counter:
SharedPreferences settings = getPreferences(MODE_PRIVATE);
int defaultCounter = 0;
mCounter = settings.getInt(KEY_COUNTER, defaultCounter);

3. Run the program and try it out.

18

Chapter 1

How it works...
As you can see, this is very similar to saving state data, because it also uses name/
value pairs. Here, we just stored an int, but we can just as easily store one of the other
primitive data types. Each data type has equivalent getters and setters, for example,
SharedPreferences.getBoolean() or SharedPreferences.setString().
Saving our data requires the services of SharedPreferences.Editor. This is evoked
with edit() and accepts remove() and clear() procedures as well as setters such as
putInt(). Note that we must conclude any storing that we do here with the commit()
statement.

There's more...
There is a slightly more sophisticated variant of the getPreferences() accessor:
getSharedPreferences(). It can be used to store multiple preference sets.

Using more than one preference file
Using getSharedPreferences() is no different from using its counterpart, but it allows for
more than one preference file. It takes the following form:
getSharedPreferences(String name, int mode)

Here, name is the file. The mode can be either MODE_PRIVATE, MODE_WORLD_READABLE, or
MODE_WORLD_WRITABLE and describes the file's access levels.

See also


Chapter 6, Working with Data, for more examples on data storage

Understanding the activity lifecycle
The Android OS is a dangerous place for an activity. The demand for resources on a
battery-operated platform is managed quite ruthlessly by the system. Our activities can
be dumped from memory when it's running low, without even a moment's notice and along
with any data they contain. Therefore, it is essential to understand the activity lifecycle.

19

Activities
The following diagram shows the stages through which an activity passes during its lifetime:

Activity Starts

User Navigates
Back to the
Activity

onCreate()

onStart()

onRestart()

onResume()
Process
is Killed

Activity is
Running

Another Activity
Comes to
the Foreground
Other
Applications
Need Memory

onPause()

Activity Returns
to the
Foreground

Activity is no
longer visible

onStop()

Activity Returns
to the
Foreground

onDestroy()

Activity is
Shut Down

Along with the stages, the diagram also shows the methods that can be overridden. As you
can see, we've already utilized most of these methods in the preceding recipes. Hopefully,
getting the big picture will help in your understanding.

20

Chapter 1

Getting ready
Create a new project in Android Studio with a Blank Activity, and call it ActivityLifecycle.
We will use the (autogenerated) TextView method to display the state information.

How to do it...
To see the application move through the various stages, we will create methods for all
the stages:
1. Open activity_main.xml and add an ID to the autogenerated TextView:
android:id="@+id/textViewState"

2. The remaining steps will be in MainActivity.java. Add the following global
declaration:
private TextView mTextViewState;

3. Modify the onCreate() method to save TextView and set the initial text:
mTextViewState = (TextView)findViewById(R.id.textViewState);
mTextViewState.setText("onCreate()\n");

4. Add the following methods to handle the remaining events:
@Override
protected void onStart() {
super.onStart();
mTextViewState.append("onStart()\n");
}
@Override
protected void onResume() {
super.onResume();
mTextViewState.append("onResume()\n");
}
@Override
protected void onPause() {
super.onPause();
mTextViewState.append("onPause()\n");
}
@Override

21

Activities
protected void onStop() {
super.onStop();
mTextViewState.append("onStop()\n");
}
@Override
protected void onRestart() {
super.onRestart();
mTextViewState.append("onRestart()\n");
}
@Override
protected void onDestroy() {
super.onDestroy();
mTextViewState.append("onDestroy()\n");
}

5. Run the application and observe what happens when the activity is interrupted by
pressing the Back and Home keys. Try other actions, such as task switching, to see
how they impact your application.

How it works...
Our activity can exist in one of these three states: active, paused, or stopped. There is also
a fourth state, destroyed, but we can safely ignore it:


An activity is in the active state when its interface is available for the user. It
persists from onResume() until onPause(), which is brought about when another
activity comes to the foreground. If this new activity does not entirely obscure our
activity, then ours will remain in the paused state until the new activity is finished
or dismissed. It will then immediately call onResume() and continue.



When a newly started activity fills the screen or makes our activity invisible, then
our activity will enter the stopped state, and the resumption will always invoke
a call to onRestart().



When an activity is in either the paused or stopped state, the operating system
can (and will) remove it from the memory when the memory is low or when other
applications demand it.

22

Chapter 1


It is worth noting that we never actually see the results of the onDestroy() method,
as the activity is removed by this point. If you want to explore these methods further,
then it is well worth employing Activity.isFinishing() to see whether the activity
is really finishing before onDestroy() is executed, as seen in the following snippet:
@Override
public void onPause() {
super.onPause();
mTextView.append("onPause()\n ");
if (isFinishing()){
mTextView.append(" ... finishing");
}
}

When implementing these methods, always call the
superclass before doing any work.

There's more...
Shutting down an activity
To shut down an activity, directly call its finish() method, which in turn calls onDestroy().
To perform the same action from a child activity, use finishFromChild(Activity
child), where child is the calling subactivity.
It is often useful to know whether an activity is being shut down or merely paused, and the
isFinishing(boolean) method returns a value that indicates which of these two states
the activity is in.

23

Get more information Android Application Development Cookbook

Where to buy this book
You can buy Android Application Development Cookbook Second Edition from the
Packt Publishing website.
Alternatively, you can buy the book from Amazon, BN.com, Computer Manuals and most internet
book retailers.
Click here for ordering and shipping details.

www.PacktPub.com

Stay Connected:

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close