Block 2
Block 2
Android
Block
2
ANDROID MOBILE APP DEVELOPMENT
Unit 9 7
Testing and Debugging
Unit 10 19
Integrating Multimedia
Unit 11 33
Saving Data on Android Devices
Unit 12 49
Locating and Sensing
Unit 13 67
Connectivity and the Cloud
Unit 14 75
Publish to Android Market
Unit 15 81
Android App Performance
Unit 16 97
Security Issues
Course Coordinator
Prof.P.V.Suresh
SOCIS, IGNOU, New Delhi-110068
Copyright : CC-BY-SA
The content is adopted to IGNOU CRC format. Wherever needed, content for
Check Your Progress is made (2021)
Prof.P.V.Suresh
SOCIS, IGNOU, New Delhi-110068
The Open University of Sri Lanka (OUSL) is the premier Open and Distance
learning institution in thecountry where students can pursue their studies through
Open and Distance Learning (ODL) methodologies. Degrees awarded by OUSL
are treated as equivalent to the degrees awarded by other national universities in
Sri Lanka by the University Grants Commission of Sri Lanka.
Authors:
W.U. Erandaka (Lecturer, Dept. of Textile & Apparel Tech, Units 11 and 12
OUSL)
W.W.A.I.D. Wickramasinghe (Demonstrator, Dept. of ECE, Units 13 and 14
OUSL)
H.U.W. Ratnayake (Senior Lecturer, Dept. of ECE, OUSL) Units 15 and 16
Content Editors:
Language Editor:
Reviewer:
Video Presenters:
Screen casters:
This Course comprises of 2 blocks. The blocks may be increased in future as per
need.
9.0 INTRODUCTION
This unit emphasizes the importance of the application testing and debugging. It
provides you an opportunity to identify errors and faults in a developed application. It
also introduces how to use testing tools and techniques to test Android Application
and how to apply measures to rectify identified errors and faults.
9.1 OBJECTIVES
After studying this unit, you should be able to :
Testing is one of the phases in software development life cycle that requires
substantial amount of time before releasing software to users. To find the software
bugs we use the process of executing a program or application. We have to test the
software with test data to verify that a given set of input to a given function produces
7
Testing and Debugging the expected result. There are two testing approaches; static and dynamic testing. An
introduction to static and dynamic testing is given in the next section
With dynamic testing methods software is executed using a set of inputs and its output
and then compared with the expected results. There are various levels of dynamic
testing techniques. Some of them are unit testing, integration testing, system testing
and acceptance testing. Here we will be only focusing on how different dynamic
testing techniques can be used in an Android application.
Now you know that techniques can be used in testing software. Let’s learn how to test
an Android application using above techniques.
In addition, Amazon and various other companies maintain device farms to test
applications with automation as well as manual testing.
An Android application should be tested for its functionality, user interfaces,
performance etc. based on the generated test cases. It is application developers’
responsibility to perform the unit tests and a separate testing team will be responsible
of performing certain other types of testing such as functional testing, integration
testing, acceptance testing etc.
Unit tests are the fundamental tests in your app testing strategy. By creating and
running unit tests against your code, you can easily verify that the logic of individual
units is correct. Running unit tests after every build helps you to quickly catch and fix
software regressions introduced by code changes to your app.
A unit test generally exercises the functionality of the smallest possible unit of code
(which could be a method, class, or component) in a repeatable way. You should build
unit tests when you need to verify the logic of specific code in your app. For example,
if you are unit testing a class, your test might check that the class is in the right state.
8
Typically, the unit of code is tested in. After completing this section, you will be able Android Mobile App
to perform unit testing for your application. Development
Android unit tests are based on JUnit and to test Android apps, you typically create
these types of automated unit tests:
Local tests: Unit tests that run on your local machine only. These tests are
compiled to run locally on the Java Virtual Machine (JVM) to minimize
execution time. Use this approach to run unit tests that have no dependencies
on the Android framework or have dependencies that can be filled by using
mock objects.
Instrumented tests: Unit tests that run on an Android device or emulator.
These tests have access to instrumentation information, such as theContext for
the app under test. Use this approach to run unit tests that have Android
dependencies which cannot be easily filled by using mock objects.
You should write your unit or integration test class as a JUnit 4test class in JUnit
framework. This framework offers a convenient way to perform common setup,
teardown, and assertion operations in your test.
In your Android Studio project, you must store the source files for instrumented tests
at module-name/src/androidTests/java/. This directory already exists when you create
a new project.
Before you begin, you should download the Android Testing Support Library Setup,
which provides APIs that allow you to quickly build and run instrumented test code
for your apps. The Testing Support Library includes a JUnit 4 test runner
(AndroidJUnitRunner) and APIs for functional UI tests (Espressoand UI Automator).
You also need to configure the Android testing dependencies for your project to use
the test runner and the rules APIs provided by the Testing Support Library. To
simplify your test development, you should also include the Hamcrest library, which
lets you create more flexible assertions using the Hamcrest matcher APIs.
In your app's top-level build.gradle file, you need to specify these libraries as
dependencies:
dependencies {
androidTestCompile 'com.android.support:support-
annotations:24.0.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
// Optional -- Hamcrest library
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
9
Testing and Debugging // Optional -- UI testing with Espresso
androidTestCompile
'com.android.support.test.espresso:espresso-core:2.2.2'
// Optional -- UI testing with UI Automator
androidTestCompile
'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
}
To use JUnit 4 test classes, make sure to specify AndroidJUnitRunner as the default
test instrumentation runner in your project by including the following setting in your
app's module-level build.gradle file:
android {
defaultConfig {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
}
A basic JUnit 4 test class is a Java class that contains one or more test methods. A test
method begins with the @Test annotation and contains the code to exercise and verify
a single functionality (that is, a logical unit) in the component that you want to test.
The code snippet below shows an example JUnit 4 integration test that uses the
Espresso APIs to perform a click action on a UI element, and check whether an
expected string is displayed.
@RunWith(AndroidJUnit4.class)
@LargeTest
publicclassMainActivityInstrumentationTest{
@Rule
publicActivityTestRule mActivityRule
=newActivityTestRule<>(MainActivity.class);
@Test
publicvoid sayHello(){
onView(withText("Sayhello!")).perform(click());
onView(withId(R.id.textView)).check(matches(withText("He
llo, World!")));
}
}
In your JUnit 4 test class, you can call out sections in your test code for special
processing by using the following annotations:
@Before: Use this annotation to specify a block of code that contains test setup
operations. The test class invokes this code block before each test. You can have
multiple @Before methods but the order in which the test class calls these methods is
not guaranteed.
@After: This annotation specifies a block of code that contains test tear-down
operations. The test class calls this code block after every test method. You can define
10
multiple @After operations in your test code. Use this annotation to release any Android Mobile App
resources from memory. Development
@Test: Use this annotation to mark a test method. A single test class can contain
multiple test methods, each prefixed with this annotation.
@Rule: Rules allow you to flexibly add or redefine the behavior of each test method
in a reusable way. In Android testing, use this annotation together with one of the test
rule classes that the Android Testing Support Library provides, such as
ActivityTestRule or ServiceTestRule.
@BeforeClass: Use this annotation to specify static methods for each test class to
invoke only once. This testing step is useful for expensive operations such as
connecting to a database.
@AfterClass: Use this annotation to specify static methods for the test class to invoke
only after all tests in the class have run. This testing step is useful for releasing any
resources allocated in the @BeforeClass block.
@Test(timeout=): Some annotations support the ability to pass in elements for which
you can set values. For example, you can specify a timeout period for the test. If the
test starts but does not complete within the given timeout period, it automatically fails.
You must specify the timeout period in milliseconds, for example:
@Test(timeout=5000).
Unit tests that run on an Android device or emulator can take advantage of the
Android framework APIs and supporting APIs, such as the Android Testing Support
Library. You should create instrumented unit tests if your tests need access to
instrumentation information (such as the target app's Context) or if they require the
real implementation of an Android framework component (such as a Parcelable or
SharedPreferences object). These tests have access to Instrumentation information,
such as the Context of the app you are testing. Use these tests when your tests have
Android dependencies that mock objects cannot satisfy.
Because instrumented tests are built into a stand-alone APK, they must have an
AndroidManifest.xml file. However, Gradle automatically generates this file during
the build so it is not visible in your project source set. You can add your own manifest
file if necessary, such as to specify a different value for `minSdkVersion` or register
run listeners just for your tests. When building your app, Gradle merges multiple
manifest files into one manifest.
Your instrumented unit test class should be written as a JUnit 4 test class. To learn
more about creating JUnit 4 test classes and using JUnit 4 assertions and annotations,
see Create a Local Unit Test Class.
11
Testing and Debugging Android Testing Support Library as your default test runner. This step is described in
more detail in Getting Started with Testing.
The following example shows how you might write an instrumented unit test to test
that the Parcelable interface is implemented correctly for the LogHistory class:
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
importstatic org.hamcrest.Matchers.is;
importstatic org.junit.Assert.assertThat;
@RunWith(AndroidJUnit4.class)
@SmallTest
publicclassLogHistoryAndroidUnitTest{
@Before
publicvoid createLogHistory(){
mLogHistory =newLogHistory();
}
@Test
publicvoid logHistory_ParcelableWriteRead(){
// Set up the Parcelable object to send and receive.
mLogHistory.addEntry(TEST_STRING, TEST_LONG);
A test suite is contained in a test package, similar to the main application package. By
convention, the test suite package name usually ends with the suite suffix (e.g.
com.example.android.testing.mysample.suite).
To create a test suite for your unit tests, import the JUnit RunWith and Suite classes.
In your test suite, add the @RunWith(Suite.class)and [email protected]()
annotations. In the @Suite.SuiteClasses()annotation, list the individual test classes or
test suites as arguments.
The following example shows how you might implement a test suite called
UnitTestSuite that groups and runs the CalculatorInstrumentation- Test and
CalculatorAddParameterizedTest test classes together.
import
com.example.android.testing.mysample.CalculatorAddParameterized
Test;
import
com.example.android.testing.mysample.CalculatorInstrumentationT
est;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
o To run a single test, open the Project window, and then right-click a test and
click Run .
o To test all methods in a class, right-click a class or method in the test file and
click Run .
o To run all tests in a directory, right-click on the directory and select Run
tests .
13
Testing and Debugging The Android Plugin for Gradle compiles the instrumented test code located in the
default directory (src/androidTest/java/), builds a test APK and production APK,
installs both APKs on the connected device or emulator, and runs the tests. Android
Studio then displays the results of the instrumented test execution in the Run window.
Note: While running or debugging instrumented tests, Android Studio does not inject
the additional methods required for Instant Run and turns the feature off.
Instant Run
Introduced in Android Studio 2.0, Instant Run is a behavior for the Run and
Debug commands that significantly reduces the time between updates to your
app. Although your first build may take longer to complete, Instant Run pushes
subsequent updates to your app without building a new APK, so changes are visible
much more quickly.
Instant Run is supported only when you deploy the debug build variant, use Android
Plugin for Gradle version 2.0.0 or higher, and set minSdkVersion to 15 or higher in
your app's module-level build.gradle file. For the best performance,
set minSdkVersion to 21 or higher.
Instant Run pushes updated code and resources to your connected device or emulator
by performing a hot swap, warm swap, or cold swap. It automatically determines the
type of swap to perform based on the type of change you made.
In this video you will be shown how to setup testing environment and
how to write a unit test. You may watch this video and do activity 9.2.
URL: https://tinyurl.com/yaatacny
14
Android Mobile App
9.5.2 Check Your Progress
Development
Create an Android application “MyApp” with a class “ConversionUtil” to
perform the given two functionalities.
To convert centimeters into inches [write a method
ConvertCmtoInch()]
To convert inches into centimeters [write a method
ConvertInchtoCm()]
Then write local unit tests to check whether the written functionalities
provide the expected output. Use the values given as inputs and expected
output to test the method.
It is the procedure of finding defects in a source code and removing them. Android
Studio includes a debugger that allows you to debug apps running on the Android
Emulator or a connected Android device. With the Android Studio debugger, you can:
To start debugging, click Debug in the toolbar. Android Studio builds an APK,
signs it with a debug key, installs it on your selected device, then runs it and opens
the Debug window.
If no devices appear in the Select Deployment Target window after you click Debug,
then you need to either connect a device or click Create New Emulator to setup the
Android Emulator.
15
Testing and Debugging Logcat is a command-line tool that dumps a log of system messages, including stack
traces when the device throws an error and messages that you have written from your
app with the Log class.
This page is about the command-line logcat tool, but you can also view log messages
from the Logcat window in Android Studio. For information about viewing and
filtering logs from Android Studio
You can run logcat as an adb command or directly in a shell prompt of your emulator
or connected device. To view log output using adb, navigate to your SDK platform-
tools/ directory and execute:
$ adb logcat
$ adb shell
# logcat
● Log.e (error)
● Log.w(warning)
● Log.i(information)
● Log.d (debug)
● Log.v (verbose)
You should never compile versbose logs into your app, except during development.
Debug logs are compiled in but stripped at runtime, while error, warning and info logs
are always kept.
For each log method, the first parameter should be a unique tag and the second
parameter is the message. The tag of a system log message is a short string indicating
the system component from which the message originates (for
example, ActivityManager ). Your tag can be any string that you find helpful, such as
the name of the current class.
A good convention is to declare a TAG constant in your class to use in the first
parameter. For example, you might create an information log message as follows:
...
Note: Tag names greater than 23 characters are truncated in the logcat output.
16
Android Mobile App
9.8 SUMMARY Development
https://developer.android.com/studio/test?authuser=1
https://developer.android.com/training/testing
https://www.softwaretestinghelp.com/android-app-testing/
17
Testing and Debugging
18
UNIT 10 INTEGRATING MULTIMEDIA
10.0 Introduction
10.1 Objectives
10.2 Introduction to Multimedia
10.3 Audio and Video Integration into Android Application Development
10.3.1 Video-V10: Multimedia for Android Interactive Application
Development
10.3.2 Check Your Progress
10.3.3 Check Your Progress
10.4 Camera functions in Android Application Development
10.4.1 Check Your Progress
10.5 Supported Media Formats
10.6 Summary
10.7 Further readings
10.0 INTRODUCTION
This unit offers you with knowledge on how to integrate multimedia to Android
applications. Further the unit discusses how to utilize multimedia to enhance the
performance by selecting appropriate media formats for audio, video and images. You
need to watch the provided video to get an insight of how different multimedia are
being used in selected applications.
10.1 OBJECTIVES
MediaPlayer and AudioManager are two classes available to play sound and video in
the Android framework. MediaPlayer class is the primary API for playing sound and
audio while AudioManager class is used to manage audio sources and audio output on
a device. MediaCodec and MediaExtractor classes are provided for building custom
media players. The open source project, ExoPlayer, is a solution between these two
options, providing a pre-built player that you can extend.
URL: https://tinyurl.com/y7bj7mys
Media Player
An object of this class can fetch, decode, and play both audio and video with minimal
setup. It supports several different media sources including local resources, Internet
URIs, external URIs. Here is an example of how to play audio that's available as a
local raw resource saved in your application's res/raw/ directory:
20
Android Mobile App
Development
Here is an example on how you might play from a URI available locally in the system
(that you obtained through a Content Resolver, for instance):
Playing from a remote URL via HTTP streaming looks like this:
The state based representation of the MediaPlayer is shown in Figure10.1. The state
diagram clarifies which methods move the MediaPlayer from one state to another. For
example, when you create a new MediaPlayer, it is in the Idle state. Then, you should
initialize it by calling setDataSource(), bringing it to the Initialized state. Next, you
have to prepare it using either the prepare() or prepareAsync() method. When the
MediaPlayer is done preparing, it will then enter the Prepared state, which indicates
that start() can be called to make it play the media. Then, you can move between the
Started, Paused and PlaybackCompleted states by calling such methods as start(),
pause() and seekTo(), amongst others. Once you call stop(), MediaPlayer cannot call
start() again until you prepare it again.
21
Integrating Multimedia MediaPlayer consumes valuable system resources. Therefore, you should always take
extra precautions to make sure you are not hanging on to a MediaPlayer instance
longer than necessary. When you are done with it, you should always call release() to
make sure any system resources allocated to it are properly released.
22
Android Mobile App
10.3.2 Check Your Progress
Development
List five valid or invalid state transitions from the MediaPlayer by
studying the state diagram shown in Figure10.1.
Depending on the user preference the loudness of the audio output should be
manageable. Volume control should be available for the user by using the hardware or
software volume controls of their device, bluetooth headset, or headphones. Apart
from volume control, the user should also be able to have control on the playback
videos. The control functions such as, the play, stop, pause, skip, and previous media
playback keys should perform their respective actions on the audio stream used by the
application you develop.
Audio streams - In order to control the audio output, the Android applications use
different “streams”. An audio stream enables an application to independently and
distinctly apply controls depending on the user preferences. The first step to creating a
predictable audio experience is understanding which audio stream your app will use.
For example, Android maintains a separate audio stream called STREAM_MUSIC for
playing music, alarms, notifications, the incoming call ringer, system sounds, in-call
volume, and DTMF tones. Most of the Android audio streams are restricted to system
events.
The hardware volume control button, generally adjust the ringer volume of the mobile
phone. For example, you do not want the ringer volume to be adjusted by pressing
hardware volume control key while playing a game, but the user only wants to
increase the volume of the sounds played by the game. For this type of preferences, it
is necessary to identify which audio stream to control. Android provides the
setVolumeControlStream() method to direct volume key presses to the audio stream
that is specified. Having identified the audio stream used in the application, this
should be set as the volume stream target. This setting should be coded early in your
application’s lifecycle as it is only needed to be called once, typically within the
onCreate() method (of the Activity or Fragment that controls your media). This
ensures that whenever your app is visible, the volume controls function as the user
expects. The code snippet looks like this:
Once this is coded, when the user press the hardware volume keys on the device, the
control affect the audio stream you specify whenever the target activity or fragment is
visible.
On certain mobile devices, the hardware playback control buttons are available or
even externally connected through wireless handsets. When the user presses one of
these buttons, the Android application notifies it as a ACTION_MEDIA_BUTTON
23
Integrating Multimedia action. In order to respond to these actions, as the receiving end, a BroadcastReceiver
should be registered (or declared). The code snippet would look like this:
Once the receiver is defined, the appropriate response can only be generated if the
receiver knows which playback button was pressed. To identify the button, Intent is
used. Then, in order to provide the appropriate response action, KeyEvent class is
used. An example is shown below.
To avoid every music app playing at the same time, Android uses audio focus to allow
only apps that hold the audio focus to play audio. Before your app starts playing any
audio, it should hold the audio focus for the stream it will be using. This is done with
a call to requestAudioFocus(). AUDIOFOCUS_REQUEST_GRA NTED is returned
if the request is successful.
You must specify which stream you are using and whether you expect to require
transient or permanent audio focus. Request transient focus when you expect to play
audio for only a short time (for example when playing navigation instructions).
Request permanent audio focus when you plan to play audio for the foreseeable future
(for example, when playing music).
The following snippet requests permanent audio focus on the music audio stream. You
should request the audio focus immediately before you begin playback, such as when
the user presses play or the background music for the next game level begins.
24
Android Mobile App
Development
Once you have finished playback call abandonAudioFocus(). To notify the system
that it is no longer require focus and unregisters the
associated.OnAudioFocusChangeListener. In the case of abandoning transient focus,
this allows any interrupted app to continue playback.
Ducking is the process of lowering your audio stream output volume to make transient
audio from another app easier to hear without totally disrupting the audio from your
own application. In the following code snippet lowers the volume on our media player
object when we temporarily lose focus, then returns it to its previous level when we
regain focus.
25
Integrating Multimedia A loss of audio focus is the most important broadcast to react to. A temporary loss of
audio focus should result in your app silencing its audio stream, but otherwise
maintaining the same state. You should continue to monitor changes in audio focus
and be prepared to resume playback where it was paused once you have regained the
focus. If the audio focus loss is permanent, it is assumed that another application is
now being used to listen to audio and your app should effectively end itself. In
practical terms, that means stopping playback, removing media button listeners—
allowing the new audio player to exclusively handle those events—and abandoning
your audio focus. At that point, you would expect a user action (pressing play in your
app) to be required before you resume playing audio.
Next, we will discuss the camera function usage in Android application development.
The Android framework includes support for various cameras and camera features
available on mobile devices to capture pictures and videos in your applications.
26
Android Mobile App
Development
Next, the camera features are loaded. Once the camera is ready to capture the picture
or the video SurfaceView is used to obtain preview of the live image. Then, a layout is
specified as a container for the preview through FrameLayout. Next,
Camera.takePicture() method is used to capture a picture and MediaRecorder class is
used to capture a video. Configuration of the MediaRecorder is vital. Example code
with the steps for configuration is shown below. Also, note that MediaRecorder can be
used to create videos from captured photos. Time lapse video allows users to create
video clips that combine pictures taken a few seconds or minutes apart. This feature
uses MediaRecorder to record the images for a time lapse sequence.
27
Integrating Multimedia Camera is a resource that is shared by many applications on a device. Your
application can make use of the camera after getting an instance of Camera, and you
must be particularly careful to release the camera object when your application stops
using it, and as soon as your application is paused (Activity.onPause()). If your
application does not properly release the camera, all subsequent attempts to access the
camera, including those by your own application, will fail and may cause your or
other applications to shut down.
It is also important to note that existing camera applications can be invoked through
the Intent class to capture pictures and videos. The following example demonstrates
how to construct an image capture intent and execute it.
28
The following example demonstrates how to construct a video capture intent and Android Mobile App
execute it. Development
The general steps for creating a custom camera interface for your application are as
follows: (***STEPS instead of bullets -> FLOW CHART)
Detect and Access Camera - Create code to check for the existence of
cameras and request access.
Create a Preview Class - Create a camera preview class that extends
SurfaceView and implements the SurfaceHolder interface. This class
previews the live images from the camera.
Build a Preview Layout - Once you have the camera preview class, create a
view layout that incorporates the preview and the user interface controls you
want.
Setup Listeners for Capture - Connect listeners for your interface controls
to start image or video capture in response to user actions, such as pressing a
button.
Capture and Save Files - Setup the code for capturing pictures or videos and
saving the output.
Release the Camera - After using the camera, your application must properly
release it for use by other applications.
Next, we will discuss the different formats/codes supported for images, audio and
video files in the Android platform.
29
Integrating Multimedia
10.5 SUPPORTED MEDIA FORMATS
Different codecs are supported with encoding parameters. These parameters include,
resolution, bit-rate, and type of channel. Here we have summarized (in Table10.1), the
codec support provided for image, audio and video. It is important to note that some
mobile devices may provide support for additional formats/codecs not listed explicitly
in Table10.1.
Table10.1: Core Media Support in Android for Audio, Video and Images.
(Source: Content summarized based on the information given in
https://developer.android.com/guide/appendix/media-formats.html)
Audio ● AAC LC
● HE-AACv1 (AAC+)
● HE-AACv2 (enhanced AAC+)
● AMR-NB
● AMR-WB
● FLAC
● MP3
● MIDI
● Vorbis
● Opus
● wavw
Video ● H.263
● H.264 AVC
● H.265 HEVC
● MPEG-4 SP
● VP8
● VP9
Images ● JPEG
● GIF
● BMP
● PNG
● WebP
30
Android Mobile App
10.6 SUMMARY Development
31
Integrating Multimedia
32
UNIT 11 SAVING DATA ON ANDROID
DEVICES
11.0 Introduction
11.1 Objectives
11.2 Android Storage Options
11.3 Shared Preferences
11.3.1 Check Your Progress
11.4 Internal Storage
11.5 External Storage
11.5.1 Check Your Progress
11.6 Saving Data in SQLite Databases
11.6.1 Check Your Progress
11.7 Summary
11.8 Further readings
11.0 INTRODUCTION
In this unit you will learn about different methods to store data locally in Android.
You will learn about how to use these different options and when to use them.
You will further learn about data management using SQLite. The videos available for
this unit will guide you on these data related operations.
On the completion of this unit you will be able to integrate data management
functionality to Android applications that you develop.
11.1 OBJECTIVES
33
Saving Data on Android
Devices 11.2 ANDROID STORAGE OPTIONS
Android provides several options for you to save persistent application data. The
solution you choose depends on your specific needs, such as whether the data should
be private to your application or accessible to other applications (and the user) and
how much space your data requires.
The SharedPreferences class provides a general framework that allows you to save
and retrieve persistent key-value pairs of primitive data types. You can use
SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings.
This data will persist across user units (even if your application is killed). These data
will only be removed only by uninstalling the application from the device or clearing
the Application data via Settings menu. Also, data saved in Shared Preferences are
private to this application only and not accessible by anyway for any other application
on the device. We will discuss how and when to use shared preferences below.
If you need to save simple data for your application, the simplest and straight forward
method is to use Shared Preferences. It is generally used to save simple data like
integer, double, boolean, and short text. As Example, it is used to save application
settings or user login info.
To get a SharedPreferences object for your application, use one of two methods:
getPreferences() - Use this method if you need only one preferences file for your
Activity. Because this will be the only preferences file for your Activity, it is not
required to provide a name.
34
Pass the keys and values you want to write with methods such as putInt() and Android Mobile App
putString(). Then call commit() to save the changes. For example: Development
SharedPreferences sharedPref =
getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score),
newHighScore);
editor.commit();
To retrieve values from a shared preferences file, call methods such as getInt() and
getString(), providing the key for the value you want, and optionally a default value to
return if the key isn't present. For example:
SharedPreferences sharedPref =
getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue =
getResources().getInteger(R.string.saved_high_score_default);
long highScore =
sharedPref.getInt(getString(R.string.saved_high_score),
defaultValue);
Here is an example that saves a preference for silent keypress mode in a calculator:
35
Saving Data on Android Delete Shared Preference Data
Devices
You have two options to delete data persisted as Shared Preference;
sharedPrefEditor.commit();
sharedPrefEditor.commit();
The next section will discuss about the internal storage options available with
Android.
You can save files directly on the device's internal storage. By default, files saved to
the internal storage are private to your application and other applications cannot
access them (nor can the user). When the user uninstalls your application, these files
are removed. Data will be removed only by uninstalling the application from the
device.
When saving a file to internal storage, you can acquire the appropriate directory as a
File by calling one of two methods:
The amount of data in Internal Storage depends on the device. Therefore do not try to
save a large persistent file because it may crash your application if there is not enough
space available on the device. Preferably, keep any data under 1M such as text files or
xml files.
The following steps show how to create and write a private file to the internal storage:
Step 1 - Call openFileOutput() with the name of the file and the operating mode. This
returns a FileOutputStream.
For example:
MODE_PRIVATE will create the file (or replace a file of the same name) and make it
private to your application. Other modes available are: MODE_APPEND,
MODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE.
Step 1 - Call openFileInput() and pass it the name of the file to read. This returns a
FileInputStream.
Tip: If you want to save a static file in your application at compile time, save the file
in your project res/raw/ directory. You can open it with openRawResource(), passing
the R.raw.<filename> resource ID. This method returns an InputStream that you can
use to read the file (but you cannot write to the original file).
The following examples shows how to delete a file from the internal storage.
37
Saving Data on Android
Devices
File fileDir = getFilesDir();
file.delete();
If you would like to cache some data, rather than store it persistently, you should use
getCacheDir() to open a ‘File’ that represents the internal directory where your
application should save temporary cache files.
When the device is low on internal storage space, Android may delete these cache
files to recover space. However, you should not rely on the system to clean up these
files for you. You should always maintain the cache files yourself and stay within a
reasonable limit of space consumed, such as 1MB. When the user uninstalls your
application, these files are removed.
Every Android-compatible device supports a shared "external storage" that you can
use to save files. This can be a removable storage media (such as an SD card) or an
internal (non-removable) storage. Files saved to the external storage are world-
readable and can be modified by the user when they enable USB mass storage to
transfer files on a computer. We will see how and when to use the external storage
along with checking the availability of the media device and managing the visibility
your files to other apps.
Use External Storage whenever you need to save large files such as audio or video
files and can be retrieved by repeatedly. Also you can use this if want your files to be
shared through different application like statistics files.
In order to read or write files on the external storage, your app must acquire the
READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE system
permissions.
<manifest ...>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
If you need to both read and write files, then you need to request only the
WRITE_EXTERNAL_STORAGE permission, because it implicitly requires read access
as well.
38
Caution: Currently, all apps have the ability to read the external storage without a Android Mobile App
special permission. However, this is going to be changed in a future release. If your Development
app needs to read the external storage (but not write to it), then you will need to
declare the READ_EXTERNAL_STORAGE permission. To ensure that your app
continues to work as expected, you should declare this permission now, before the
change takes effect.
<manifest ...>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
You do not need any permissions to save files on the internal storage. Your
application always has permission to read and write files in its internal storage
directory.
Before you do any work with the external storage, you should always call
getExternalStorageState() to check whether a compatible media is available. The
media might be mounted to a computer, read-only, or in some other state. For
example, here are a couple methods you can use to check the availability:
The getExternalStorageState() method returns other states that you might want to
check, such as whether the media is being shared (connected to a computer), is
missing entirely, has been removed badly, etc. You can use these to notify the user
with more information when your application needs to access the media.
39
Saving Data on Android If you know ahead of time how much data you are saving, you can find out whether
Devices sufficient space is available without causing an IOException by calling
getFreeSpace() or getTotalSpace(). These methods provide the current available space
and the total space in the storage volume, respectively.
Saving files that can be shared with other apps
You may require sharing files across other apps. Sometimes, you may want to hide
your files from others. We will now see how to share with or hide your files from
other apps.
To hide your files, include an empty file named .nomedia in your external files
directory (note the dot prefix in the filename). This prevents media scanner from
reading your media files and providing them to other apps through the MediaStore
content provider. However, if your files are truly private to your app, you should save
them in an app-private directory.
Generally, new files that the user may acquire through your app should be saved to a
"public" location on the device where other apps can access them and the user can
easily copy them from the device. When doing so, you should use to one of the shared
public directories, such as Music/, Pictures/, and Ringtones/.
For example, here is a method that creates a directory for a new photo album in the
public pictures directory:
If you want to save files that are private to your app, you can acquire the appropriate
directory by calling getExternalFilesDir() and ‘passing’ it a name indicating the type
of directory you would like. Each directory created this way is added to a parent
directory that encapsulates all your app's external storage files, which the system
deletes when the user uninstalls your app.For example, here's a method you can use to
create a directory for an individual photo album:
40
public File getAlbumStorageDir(Context context, String Android Mobile App
albumName) { Development
// Get the directory for the app's private pictures directory.
If none of the pre-defined sub-directory names suit your files, you can instead call
getExternalFilesDir() and pass null. This returns the root directory for your app's
private directory on the external storage.
To open a ‘File’ that represents the external storage directory where you should save
cache files, call getExternalCacheDir(). If the user uninstalls your application, these
files will be automatically deleted.
Delete a File
You should always delete files that you no longer need. The most straightforward way
to delete a file is to have the opened file reference call delete() on itself.
myFile.delete();
If the file is saved on internal storage, you can also ask the Context to locate and
delete a file by calling deleteFile():
myContext.deleteFile(fileName);
Note: When the user uninstalls your app, the Android system deletes the following:
The next section will discuss about how to save data in SQLite databases, read the
stored data when required and manipulating the stored data as per your requirement.
Saving data to a database is ideal for repeating or structured data, such as contact
information. This class assumes helps you get started with SQLite databases on
Android. The APIs you will need to use a database on Android are available in the
android.database.sqlite package. We will discuss how and when to use databases as a
storage option.
You can use databases to store user data as per your app requirement. Otherwise, it
does not have a specific reason to use a database.
One of the main principles of SQL databases is the schema: a formal declaration of
how the database is organized. The schema is reflected in the SQL statements that you
use to create your database. You may find it helpful to create a companion class,
known as a contract class, which explicitly specifies the layout of your schema in a
systematic and self-documenting way.
A contract class is a container for constants that define names for URIs, tables, and
columns. The contract class allows you to use the same constants across all the other
classes in the same package. This let you change a column name in one place and
have it propagate throughout your code.
A good way to organize a contract class is to put definitions that are global to your
whole database in the root level of the class. Then create an inner class for each table
that enumerates its columns.
Note: By implementing the BaseColumns interface, your inner class can inherit a
primary key field called _ID that some Android classes such as cursor adaptors will
expect it to have. It is not required, but this can help your database work harmoniously
with the Android framework.
For example, this snippet defines the table name and column names for a single table:
42
public final class FeedReaderContract { Android Mobile App
// To prevent someone from accidentallyinstantiating the Development
// contract class,give it an empty constructor.
public FeedReaderContract() {}
Once you have defined how your database looks, you should implement methods that
create and maintain the database and tables. Here are some typical statements that
create and delete a table:
Just like files that you save on the device's internal storage, Android stores your
database in private disk space associated with the application. Your data is secure,
because by default this area is not accessible to other applications.
A useful set of APIs is available in the SQLiteOpenHelper class. When you use this
class to obtain references to your database, the system performs the potentially long-
running operations of creating and updating the database only when needed and not
during app startup. All you need to do is call getWritableDatabase() or
getReadableDatabase().
Note: Because they can be long-running, be sure that you call getWritableDatabase()
or getReadableDatabase() in a background thread, such as with AsyncTask or
IntentService.
43
Saving Data on Android For example, here is an implementation of SQLiteOpenHelper that uses some of the
Devices commands shown above:
Insert data into the database by passing a ContentValues object to the insert() method:
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id);
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_CONTENT, content);
// Insert the new row, returning the primary key value of the new //row
long newRowId;
newRowId = db.insert(
FeedEntry.TABLE_NAME,
FeedEntry.COLUMN_NAME_NULLABLE,
values);
The first argument for insert() is simply the table name. The second argument
provides the name of a column in which the framework can insert NULL in the event
44
that the ContentValues is empty (if you instead set this to "null", then the framework Android Mobile App
will not insert a row when there are no values). Development
To read from a database, use the query() method, passing it your selection criteria and
desired columns. The method combines elements of insert() and update(), except the
column list defines the data you want to fetch, rather than the data to insert. The
results of the query are returned to you in a Cursor object.
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor c = db.query(
FeedEntry.TABLE_NAME, // The table to query
projection, // The columns to return
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
To look at a row in the cursor, use one of the Cursor move methods, which you must
always call before you begin reading values. Generally, you should start by calling
moveToFirst(), which places the "read position" on the first entry in the results. For
each row, you can read a column's value by calling one of the Cursor get methods,
such as getString() or getLong(). For each of the get methods, you must pass the index
position of the column you desire, which you can get by calling getColumnIndex() or
getColumnIndexOrThrow().
For example:
cursor.moveToFirst();
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
Note: You can execute SQLite queries using the SQLiteDatabase query() methods,
which accept various query parameters, such as the table to query, the projection,
selection, columns, grouping, and others. For complex queries, such as those that
45
Saving Data on Android require column aliases, you should use SQLiteQueryBuilder, which provides several
Devices convenient methods for building queries.
To delete rows from a table, you need to provide selection criteria that identify the
rows. The database API provides a mechanism for creating selection criteria that
protects against SQL injection. The mechanism divides the selection specification into
a selection clause and selection arguments. The clause defines the columns to look at,
and also allows you to combine column tests. The arguments are values to test against
that are bound into the clause. Because the result is not handled the same as a regular
SQL statement, it is immune to SQL injection.
Update a Database
When you need to modify a subset of your database values, use the update() method.
Updating the table combines the content values syntax of insert() with the where
syntax of delete().
SQLiteDatabase db = mDbHelper.getReadableDatabase();
With that we have come to the end of this unit and now you are in a position to use
data management on your apps.
46
Android Mobile App
11.7 SUMMARY Development
In this unit we discussed about the four of the five methods used to
persist data on Android devices. They are namely; Shared preferences,
Internal storage, external storage and external database. We also learnt
about when to use each of these options and how we can use them in
apps. The important things to keep in your mind is that the privacy
level of the files/data and the size of the data.
https://developer.android.com/training/location/index.html
https://developer.android.com/training/data-storage
https://www.sqlite.org/index.html
47
Saving Data on Android
Devices
48
UNIT 12 LOCATING AND SENSING
12.0 Introduction
12.1 Objectives
12.2 Introduction to Sensors
12.3 Android Sensor Framework
12.4 Identifying Sensors and sensor Capabilities
12.4.1 Check Your Progress
12.5 Monitoring Sensor Events
12.6 Sensor Coordinate System
12.7 Best Practices for Accessing and Using Sensors
12.8 Commonly Used Sensors
12.8.1 Check Your Progress
12.9 Making Your App Location-Aware
12.10 Getting the Last Known Location
12.11 Changing Location Settings
12.12 Receiving Location Updates
12.13 Adding Google Maps to Your App
12.13.1 Check Your Progress
12.14 Summary
12.15 Further readings
12.0 INTRODUCTION
In this unit you will be introduced to various sensors available in an Android device.
The availability of a particular sensor depends on the device you use. You will learn
how to use these sensors accessing relevant API’s to obtain data and use them in
applications.
You will also learn about Google Maps and how location awareness can be achieved
in applications.
A video is incorporated in this unit to help you to understand more about sensors and
Google map.
12.1 OBJECTIVES
After studying this unit, you should be able to :
49
Locating and Sensing
12.2 INTRODUCTION TO SENSORS
Most Android devices have built-in sensors that measure motion, orientation, position,
and various environmental conditions. These sensors are capable of providing raw
data with high precision and accuracy, and are useful if you want to monitor three-
dimensional device movement or positioning, or you want to monitor changes in the
ambient environment near a device.
Some of these sensors are hardware-based and some are software-based. Hardware-
based sensors are physical components built into a handset or tablet device. They
derive their data by directly measuring specific environmental properties, such as
acceleration, geomagnetic field strength, or angular change. Software-based sensors
are not physical devices, although they mimic hardware-based sensors. Software-
based sensors derive their data from one or more of the hardware-based sensors and
are sometimes called virtual sensors or synthetic sensors. The linear acceleration
sensor and the gravity sensor are examples of software-based sensors. Appendix 12.1
summarizes the sensor types that are supported by the Android platform.
The sensor framework provides several classes and interfaces that help you perform a
wide variety of sensor-related tasks. For example, you can use the sensor framework
to do the following:
The sensor framework is part ofAndroid. Hardware package includes the following
classes and interfaces:
50
Sensor Manager Android Mobile App
Development
You can use this class to create an instance of the sensor service. This class provides
various methods for accessing and listing sensors, registering and unregistering sensor
event listeners, and acquiring orientation information. This class also provides several
sensor constants that are used to report sensor accuracy, set data acquisition rates, and
calibrate sensors.
Sensor
You can use this class to create an instance of a specific sensor. This class provides
various methods that let you determine a sensor's capabilities.
Sensor Event
The system uses this class to create a sensor event object, which provides information
about a sensor event. A sensor event object includes the following information: the
raw sensor data, the type of sensor that generated the event, the accuracy of the data,
and the timestamp for the event.
You can use this interface to create two callback methods that receive notifications
(sensor events) when sensor values change or when sensor accuracy changes.
In the next section we will learn how to identify different sensors available on a
device and the capabilities of each sensor.
Identifying sensors and sensor capabilities at runtime is useful if your application has
features that rely on specific sensor types or capabilities. For example, you may want
to identify all of the sensors that are present on a device and disable any application
features that rely on sensors that are not present. Likewise, you may want to identify
all of the sensors of a given type so you can choose the sensor implementation that has
the optimum performance for your application.
To identify the sensors that are on a device you first need to get a reference to the
sensor service. To do this, you create an instance of the ‘SensorManager’ class by
calling the getSystemService() method and passing in the SENSOR_SERVICE
argument.
List<Sensor> deviceSensors =
mSensorManager.getSensorList(Sensor.TYPE_ALL);
51
Locating and Sensing If you want to list all of the sensors of a given type, you could use another constant
instead of TYPE_ALL such as TYPE_GYROSCOPE,
TYPE_LINEAR_ACCELERATION, or TYPE_GRAVITY.
You can also determine whether a specific type of sensor exists on a device by using
the getDefaultSensor() method. If a default sensor does not exist for a given type of
sensor, the method call returns null, which means the device does not have that type of
sensor. The following code checks whether there's a magnetometer on a device:
In addition to listing the sensors that are on a device, you can use the public methods
of the Sensor class to determine the capabilities and attributes of individual sensors.
For example, you can use the getResolution() and getMaximumRange() methods to
obtain a sensor's resolution and maximum range of measurement. You can also use
the getPower() method to obtain a sensor's power requirements.
Now that we have learnt how to identify sensors and their capabilities, it is time to
learn how to monitor sensor events. The next section will discuss about monitoring
sensor events.
A sensor event occurs every time a sensor detects a change in the parameters it is
measuring. A sensor event provides you with four pieces of information: the name of
the sensor that triggered the event, the timestamp for the event, the accuracy of the
event, and the raw sensor data that triggered the event.
To monitor raw sensor data you need to implement two callback methods that are
exposed through the SensorEventListener interface: onAccuracyChanged() and
onSensorChanged(). The Android system calls these methods whenever the following
occurs:
52
In this case the system invokes the onAccuracyChanged() method, providing you with Android Mobile App
a reference to the Sensor object that changed and the new accuracy of the sensor. Development
A sensor reports a new value.
In this case the system invokes the onSensorChanged() method, providing you with a
SensorEvent object. A SensorEvent object contains information about the new sensor
data, including: the accuracy of the data, the sensor that generated the data, the
timestamp at which the data was generated, and the new data that the sensor recorded.
The following code shows how to use the onSensorChanged() method to monitor data
from the light sensor. This example displays the raw sensor data in a TextView that is
defined in the main.xml file as sensor_data.
@Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager = (SensorManager)
getSystemService(Context.SENSOR_SERVICE);
mLight =
mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
@Override
public final void onAccuracyChanged(Sensor sensor, int
accuracy) {
// Do something here if sensor accuracy changes.
}
@Override
public final void onSensorChanged(SensorEvent event) {
// The light sensor returns a single value.
// Many sensors return 3 values, one for each axis.
float lux = event.values[0];
// Do something with this sensor value.
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mLight,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}
53
Locating and Sensing In this example, the default data delay (SENSOR_DELAY_NORMAL) is specified
when the registerListener() method is invoked. The data delay (or sampling rate)
controls the interval at which sensor events are sent to your application via the
onSensorChanged() callback method.
In general, the sensor framework uses a standard 3-axis coordinate system to express
data values. For most sensors, the coordinate system is defined relative to the device's
screen when the device is held in its default orientation (Figure 12.1).
The most important point to understand about this coordinate system is that the axes
are not swapped when the device's screen orientation changes—that is, the sensor's
coordinate system never changes as the device moves.
Another point to understand is that your application must not assume that a device's
natural (default) orientation is portrait. The natural orientation for many tablet devices
is landscape. And the sensor coordinate system is always based on the natural
orientation of a device.
In the next section, we will discuss about the best practices for accessing and using
sensors.
Under this topic we will be explaining some of the best practices that you should
follow when accessing and using sensors.
54
Be sure to unregister a sensor's listener when you have finished using the sensor or Android Mobile App
when the sensor activity pauses. If a sensor listener is registered and its activity is Development
paused, the sensor will continue to acquire data and use battery resources unless you
unregister the sensor. Also there could be some exception the application runtime, if
activity get destroyed without unregistering the sensor manager. The following code
snippet shows how to use the onPause() method to unregister a listener:
The default Androidemulator cannot emulate sensors. You should test your sensor
code on a physical device or emulator which capable to emulate the sensors as well.
There are, however, sensor simulators that you can use to simulate sensor output.
Sensor data can change at a high rate, which means the system may call the
onSensorChanged(SensorEvent) method quite often. As a best practice, you should do
as little as possible within the onSensorChanged(SensorEvent) method so you don't
block it. If your application requires you to do any data filtering or reduction of sensor
data, you should perform that work outside of the onSensorChanged(SensorEvent)
method.
Always verify that a sensor exists on a device before you attempt to acquire data from
it. Don't assume that a sensor exists simply because it's a frequently-used sensor.
Device manufacturers are not required to provide any particular sensors in their
devices.
When you register a sensor with the registerListener() method, be sure you choose a
delivery rate that is suitable for your application or use-case. Sensors can provide data
at very high rates. Allowing the system to send extra data that you don't need wastes
system resources and uses battery power.
There are many different types of sensors. Under this topic we will be explaining
some of the commonly used sensors accelerometer, Gravity Sensor, Gyroscope and
Proximity Sensor.
55
Locating and Sensing Accelerometer
An acceleration sensor measures the acceleration applied to the device, including the
force of gravity. The following code shows you how to get an instance of the default
acceleration sensor:
It should be noted that the force of gravity(g) is always influencing the measured
acceleration. For this reason, when the device is sitting on a table (and not
accelerating), the accelerometer reads a magnitude of g = 9.81 m/s2. Similarly, when
the device is in free fall and therefore rapidly accelerating toward the ground at 9.81
m/s2, its accelerometer reads a magnitude of g = 0 m/s2. Therefore, to measure the
real acceleration of the device, the contribution of the force of gravity must be
removed from the accelerometer data. This can be achieved by applying a high-pass
filter. Conversely, a low-pass filter can be used to isolate the force of gravity. The
following example shows how you can do this:
In general, the accelerometer is a good sensor to use if you are monitoring device
motion. Almost every Android-powered handset and tablet has an accelerometer, and
it uses about 10 times less power than the other motion sensors. One drawback is that
you might have to implement low-pass and high-pass filters to eliminate gravitational
forces and reduce noise.
Gravity Sensor
56
The gravity sensor provides a three dimensional vector indicating the direction and Android Mobile App
magnitude of gravity. The following code shows you how to get an instance of the Development
default gravity sensor:
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager)
getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
The units are the same as those used by the acceleration sensor (m/s2), and the
coordinate system is the same as the one used by the acceleration sensor
Gyroscope
The gyroscope measures the rate of rotation in rad/s around a device's x, y, and z axis.
The following code shows you how to get an instance of the default gyroscope:
The sensor's coordinate system is the same as the one used for the acceleration sensor.
Rotation is positive in the counter-clockwise direction.
Standard gyroscopes provide raw rotational data without any filtering or correction for
noise and drift (bias). In practice, gyroscope noise and drift will introduce errors that
need to be compensated for. You usually determine the drift (bias) and noise by
monitoring other sensors, such as the gravity sensor or accelerometer.
Proximity Sensor
The proximity sensor lets you determine how far away an object is from a device. The
following code shows you how to get an instance of the default proximity sensor:
The proximity sensor is usually used to determine how far away a person's head is
from the face of a handset device (for example, when a user is making or receiving a
phone call). Most proximity sensors return the absolute distance, in cm, but some
return only near and far values. The following code shows you how to use the
proximity sensor:
@Override
public final void onAccuracyChanged(Sensor sensor, int
accuracy) {
// Do something here if sensor accuracy changes.
}
@Override
public final void onSensorChanged(SensorEvent event) {
float distance = event.values[0];
// Do something with this sensor data.
}
@Override
protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mProximity,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
// Be sure to unregister the sensor when the activity
pauses.
super.onPause();
mSensorManager.unregisterListener(this);
}
}
58
Android Mobile App
12.9 MAKING YOUR APP LOCATION-AWARE Development
One of the unique features of mobile applications is location awareness. Mobile users
take their devices with them everywhere, and adding location awareness to your app
offers users a more contextual experience. The location APIs available in Google Play
services facilitate adding location awareness to your app with automated location
tracking, geofencing (a facility that monitors whether a device is near to a location of
interest), and activity recognition.
Android offers two ways to add location awareness to your apps; one through the
Google Play services location APIs and the other is through the Android framework
location API. However, the former is preferred over the latter as a way of adding
location awareness to your app.
In this section, we will discuss how to use the Google Play services location APIs in
your app to get the current location, and get periodic location updates. In addition the
same API’s can be used to maintain addresses and geofences. However, we will not
discuss about addresses and geofences here.
Apps that use location services must request location permissions. Android offers two
location permissions: ACCESS_COARSE_LOCATION and
ACCESS_FINE_LOCATION. The permission you choose determines the accuracy of
the location returned by the API. If you specify ACCESS_COARSE_LOCATION,
the API returns a location with an accuracy approximately equivalent to a city block.
To connect to the API, you need to create an instance of the Google Play services API
client. For details about using the client, see the guide to Accessing Google APIs.
In your activity's onCreate() method, create an instance of Google API Client, using
the GoogleApiClient.Builder class to add the LocationServices API, as the following
code snippet shows.
To connect, call connect() from the activity's onStart() method. To disconnect, call
disconnect() from the activity's onStop() method. The following snippet shows an
example of how to use both of these methods.
59
Locating and Sensing In the next section we will discuss about how to obtain the last known location of a
particular Android device.
Use the fused location provider to retrieve the device's last known location. The fused
location provider manages the underlying location technology and provides a simple
API so that you can specify requirements at a high level, like high accuracy or low
power. It also optimizes the device's use of battery power.
This service requires only coarse location. Request this permission with the uses-
permission element in your app manifest, as the following code snippet shows:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.basiclocations
ample" >
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>
To request the last known location, call the getLastLocation() method, passing it your
instance of the GoogleApiClient object. Do this in the onConnected() callback
provided by Google API Client, which is called when the client is ready. The
following code snippet illustrates the request and a simple handling of the response:
The getLastLocation() method returns a Location object from which you can retrieve
the latitude and longitude coordinates of a geographic location.
Now that we are aware of how to get the location details, we can discuss about
changing location settings. Next section will discuss about changing location settings.
60
Android Mobile App
12.11 CHANGING LOCATION SETTINGS Development
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" pac
kage="com.google.android.gms.location.sample.locationupdates" >
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>
Update interval
setInterval() - This method sets the rate in milliseconds at which your app prefers to
receive location updates.
setFastestInterval() - This method sets the fastest rate in milliseconds at which your
app can handle location updates. You need to set this rate because other apps also
affect the rate at which updates are sent. The Google Play services location APIs send
out updates at the fastest rate that any app has requested with setInterval(). If this rate
is faster than your app can handle, you may encounter problems with UI flicker or
data overflow. To prevent this, call setFastestInterval() to set an upper limit to the
update rate.
Priority
setPriority() - This method sets the priority of the request, which gives the Google
Play services location services a strong hint about which location sources to use. The
following values are supported:
61
Locating and Sensing PRIORITY_LOW_POWER - Use this setting to request city-level precision,
which is an accuracy of approximately 10 kilometers. This is considered a
coarse level of accuracy, and is likely to consume less power.
PRIORITY_NO_POWER - Use this setting if you need negligible impact on
power consumption, but want to receive location updates when available.
With this setting, your app does not trigger any location updates, but receives
locations triggered by other apps.
Create the location request and set the parameters as shown in this code
sample:
PendingResult<LocationSettingsResult> result
= LocationServices.SettingsApi.checkLocationSettings(mG
oogleClient,builder.build());
When the PendingResult returns, your app can check the location settings by looking
at the status code from the LocationSettingsResult object. To get even more details
about the the current state of the relevant location settings, your app can call the
LocationSettingsResult object's getLocationSettingsStates() method.
To determine whether the location settings are appropriate for the location request,
check the status code from the LocationSettingsResult object. A status code of
RESOLUTION_REQUIRED indicates that the settings must be changed. To prompt
the user for permission to modify the location settings, call
startResolutionForResult(Activity, int). This method brings up a dialog asking for the
user's permission to modify location settings. The following code snippet shows how
to check the location settings, and how to call startResolutionForResult(Activity, int).
result.setResultCallback(new
ResultCallback<LocationSettingsResult>()) {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
62
final LocationSettingsStates = Android Mobile App
result.getLocationSettingsStates(); Development
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The
client can
// initialize location requests here.
...
break;
case
LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied, but
this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling
startResolutionForResult(),
// and check the result in
onActivityResult().
status.startResolutionForResult(
OuterClass.this,
REQUEST_CHECK_SETTINGS);
} catch (SendIntentException e) {
// Ignore the error.
}
break;
case
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied.
However, we have no way
// to fix the settings so we won't show the
dialog.
...
break;
}
}
});
If your app can continuously track location, it can deliver more relevant information
to the user. For example, if your app helps the user find their way while walking or
driving, or if your app tracks the location of assets, it needs to get the location of the
device at regular intervals. As well as the geographical location (latitude and
longitude), you may want to give the user further information such as the bearing
(horizontal direction of travel), altitude, or velocity of the device. This information,
and more, is available in the Location object that your app can retrieve from the fused
location provider.
While you can get a device's location with getLastLocation(), a more direct approach
is to request periodic updates from the fused location provider. In response, the API
63
Locating and Sensing updates your app periodically with the best available location, based on the currently-
available location providers such as WiFi and GPS (Global Positioning System). The
accuracy of the location is determined by the providers, the location permissions
you've requested, and the options you set in the location request.
The starting point of location update would be to get the last known location of the
device. This also ensures that the app has a known location before starting the periodic
location updates. The snippets in the following sections assume that your app has
already retrieved the last known location and stored it as a Location object in the
global variable mCurrentLocation.
For this service you require fine location detection, so that your app can get as precise
a location as possible from the available location providers. Request this permission
with the uses-permission element in your app manifest, as shown in the following
example:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" p
ackage="com.google.android.gms.location.sample.locationupdates"
>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
</manifest>
Before requesting location updates, your app must connect to location services and
make a location request. Once a location request is in place you can start the regular
updates by calling requestLocationUpdates(). Do this in the onConnected() callback
provided by Google API Client, which is called when the client is ready.
Depending on the form of the request, the fused location provider either invokes the
LocationListener.onLocationChanged() callback method and passes it a Location
object, or issues a PendingIntent that contains the location in its extended data. The
accuracy and frequency of the updates are affected by the location permissions you've
requested and the options you set in the location request object.
This section shows you how to get the update using the LocationListener callback
approach. Call requestLocationUpdates(), passing it your instance of the
GoogleApiClient, the LocationRequest object, and a LocationListener. Define a
startLocationUpdates() method, called from the onConnected() callback, as shown in
the following code sample:
@Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
Consider whether you want to stop the location updates when the activity is no longer
in focus, such as when the user switches to another app or to a different activity in the
same app. This can be handy to reduce power consumption, provided the app doesn't
need to collect information even when it's running in the background. This section
shows how you can stop the updates in the activity's onPause() method.
@Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
@Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()
&&!mRequestingLocationUpdates) {
startLocationUpdates();
}
}
Google maps are the most popular method of displaying maps. You can easily
incorporate Google maps to your app. The following link shows you a step by step
approach to incorporate Google maps to your app.
12.14 SUMMARY
In this unit, first we discussed about the various sensors available with
Android framework. We also learnt about some important sensors and
how to use them in an application. You will have to get familiar with the
sensor coordinate system and the best practices when you develop apps.
It will be useful to make your applications more efficient.
https://developer.android.com/guide/topics/sensors/sensors_overview?authuser=1
https://source.android.com/devices/sensors/sensor-stack
https://www.javatpoint.com/android-sensor-tutorial
66
UNIT 13 CONNECTIVITY AND THE CLOUD
13.0 Introduction
13.1 Objectives
13.2 Connecting devices wirelessly
13.3 Performing network operations
13.3.1 Check Your Progress
13.4 Considerations when transferring data
13.5 Syncing to the cloud with information delivery models
13.5.1 Video – V11: Connectivity and the cloud
13.6 Push notification
13.6.1 Check Your Progress
13.7 Summary
13.8 Further Readings
13.0 INTRODUCTION
This unit will help you to understand the process of connecting your application to the
world beyond the user's device. You will learn how to connect your application to
other devices in the areaand to the Internet, how to take backup and sync your
applications data and how to deal with Push notifications in this unit.
13.1 OBJECTIVES
After studying this unit, you should be able to:
First of all we will see what a wireless network is. It is any type of computer network
that uses wireless data connections for connecting network nodes. Besides enabling
communication with the cloud, Android's wireless APIs also enable communication
with other devices on the same local network, and even devices which are not on a
67
Connectivity and the network, but are physically nearby. The addition of Network Service Discovery
Cloud (NSD) takes this further by allowing an application to seek out a nearby device
running services with which it can communicate. Integrating this functionality into
your application helps you provide a wide range of features, such as playing games
with users in the same room, pulling images from a networked NSD-enabled webcam,
or remotely logging into other machines on the same network.
Adding Network Service Discovery (NSD) to your app allows your users to identify
other devices on the local network that support the services your application requests.
This is useful for a variety of peer-to-peer applications such as file sharing or multi-
player gaming. Android's NSD APIs simplify the effort required for you to implement
such features.
The Wi-Fi P2P APIs allow applications to connect to nearby devices without needing
to connect to a network or hotspot. Wi-Fi P2P allows your application to quickly find
and interact with nearby devices, at a range beyond the capabilities of Bluetooth. Also
it provides fast data transfer with more security than the Bluetooth.
Let’ssee how to discover services published by nearby devices without being on the
same network using Wi-Fi P2P. Using Wi-Fi Peer-to-Peer (P2P) Service Discovery
allows you to discover the services of nearby devices directly without being connected
to a network. You can also advertise the services running on your device. These
capabilities help you communicate between apps, even when no local network or
hotspot is available. While this set of APIs is similar in purpose to the Network
Service Discovery APIs outlined in a previous section, implementing them in code is
very different.
This section explains the basic tasks involved in connecting to the network,
monitoring the network connection (including connection changes), and giving users
control over an app's network usage. It also describes how to parse and consume XML
data.
These fundamental building blocks will enable you to create Android applications that
download content and parse data efficiently, while minimizing network traffic.
To perform the network operations, your application manifest must include the
following permissions:
68
Android Mobile App
<uses-permissionandroid:name="android.permission.INTERNET"/> Development
<uses-
permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
If your application performs a lot of network operations, you should provide user
settings that allow users to control your app’s data habits, such as how often your app
syncs data, whether to perform uploads/downloads only when on Wi-Fi, whether to
use data while roaming, and so on. With these controls available to them, users are
much less likely to disable your app’s access to background data when they approach
their limits, because they can instead precisely control how much data your app uses.
Over the life of a smartphone, the cost of a cellular data plan can easily exceed the
cost of the device itself. From Android 7.0 (API level 24), users can enable Data
Saver on a device-wide basis in order optimize their device's data usage, and use less
data. This ability is especially useful when roaming, near the end of the billing cycle,
or for a small prepaid data pack. Though this has been introduced as OS feature with
Android 7.0, various vendors have introduced their own data saving mechanisms like
ultra-data saving mode, on other Android versions which support VPN.
When a user enables Data Saver in Settings and the device is on a metered network,
the system blocks background data usage and signals apps to use less data in the
foreground wherever possible. Users can white-list specific apps to allow background
metered data usage even when Data Saver is turned on.
The optimal frequency of regular updates will vary based on device state, network
connectivity, user behavior, and explicit user preferences.
Optimizing battery life discusses how to build battery-efficient apps that modify their
refresh frequency based on the state of the host device. That includes disabling
background service updates when you lose connectivity and reducing the rate of
updates when the battery level is low.
How your refresh frequency can be varied to best mitigate the effect of background
updates on the underlying wireless radio state machine.
The most fundamental way to reduce your downloads is to download only what you
need. In terms of data, that means implementing REST APIs that allow you to specify
query criteria that limit the returned data by using parameters such as the time of your
last update.
Similarly, when downloading images, it is a good practice to reduce the size of the
images server-side, rather than downloading full-sized images that are reduced on the
client.
When it comes to impact on battery life, not all connection types are created equal.
Not only does the Wi-Fi radio use significantly less battery than its wireless radio
counterparts, but the radios used in different wireless radio technologies have different
battery implications
The Wearable Data Layer API, which is part of Google Play services, provides a
communication channel for your handheld and wearable apps. The API consists of a
set of data objects that the system can send and synchronize over the wire and
listeners that notify your apps of important events with the data layer
In this video you will be learning how to integrate cloud based services to
your application.
URL:https://tinyurl.com/y86wfhhw
70
Android Mobile App
13.6 PUSH NOTIFICATION Development
A notification is a message you can display to the user outside of your application's
normal UI. When you tell the system to issue a notification, it first appears as an icon
in the notification area. To see the details of the notification, the user opens the
notification drawer. Both the notification area and the notification drawer are system-
controlled areas that the user can view at any time.
Polling happens when the phone goes to the server with a certain interval and asks if
there are any messages to process. Basically there are two ways to get messages to the
phone:
1. Push messages (the server contacts the phone and tells it there are messages
waiting)
2. Polling service (the phone contacts the server and ask for messages)
Creating a notification
The following snippet illustrates a simple notification that specifies an activity to open
when the user clicks the notification. Notice that the code creates a TaskStackBuilder
object and uses it to create the PendingIntent for the action. This pattern is explained
in more detail in the section Preserving Navigation when Starting an Activity:
NotificationCompat.Builder mBuilder =
newNotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent =newIntent(this,ResultActivity.class);
// The stack builder object will contain an artificial back //stack for
thestarted Activity.
// This ensures that navigating backward from the Activity leads //out ofyour
application to the Home //screen.
TaskStackBuilder stackBuilder =TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent //itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the //stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
71
Connectivity and the );
Cloud mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());
Every time an app polls a server to check if an update is required, you activate the
wireless radio, drawing power unnecessarily, for up to 20 seconds on a typical 3G
connection.
Compared to polling, where your app must regularly ping the server to query for new
data, Google cloud messaging model allows your app to create a new connection only
when it knows there is data to download.
Google Cloud Messaging (GCM) is a free service that enables developers to send
messages between servers and client apps. This includes downstream messages from
servers to client apps, and upstream messages from client apps to servers.
For example, a lightweight downstream message could inform a client app that there
is new data to be fetched from the server, as in the case of a "new email" notification.
For use cases such as instant messaging, a GCM message can transfer up to 4kb of
payload to the client app. The GCM service handles all aspects of queuing of
messages and delivery to and from the target client app.
72
Android Mobile App
13.7 SUMMARY Development
https://developer.android.com/training/connect-devices-
wirelessly#:~:text=Besides%20enabling%20communication%20with%20the,network
%2C%20but%20are%20physically%20nearby.
https://developer.android.com/training/basics/network-ops
https://www.netapp.com/hybrid-cloud/what-is-hybrid-cloud/
73
Connectivity and the
Cloud
74
UNIT 14 PUBLISH TO ANDROID MARKET
14.0 Introduction
14.1 Objectives
14.2 How can you obtain an Android application?
14.3 App Stores
14.3.1 Check Your Progress
14.4 Revenue Models
14.4.1 Check Your Progress
14.5 Google Play Store
14.6 Process of Publishing an Android Application
14.6.1 Video – V12: Publish to Android Market
14.6.2 Check Your Progress
14.7 Summary
14.8 Further readings
14.0 INTRODUCTION
By following this unit you will gain theoretical knowledge on the revenue and
distribution models, process of launching an Android application in a distributed
environment. Knowledge gained from this unit will help you to make an informed
choice of the business models to cater to specific requirements when launching a
developed Android application to the market.
The provided video will demonstrate you how to publish an Android application to the
Google Play.
14.1 OBJECTIVES
Terminology
75
Publish to Android Market
14.2 HOW CAN YOU OBTAIN AN ANDROID
APPLICATION?
As you already learnt in the previous units, Android mobile applications are software
programs that may be installed on portable computing devices such as smartphones,
tablets, some digital set-top boxes, laptops etc. Mobile applications market is the place
where the buyers (consumers/users) and sellers (app developers) of mobile
applications meet. These mobile application markets are dedicated retail platforms
known as AppStores which can be accessible through the consumer’s device. The
main objective of an AppStore is to serve as a host to initially source online to
distribute to potential users through a data connection and accessing device.
An end-user can obtain an Android application in two main ways. Applications may
be pre-installed or downloaded on-demand. Pre-installed mobile applications are
selected by device manufacturers and usually include the following.
Via the device - end-user can directly access the device manufacturer’s app
store through a menu on the device, and download and install a mobile
application. Access may be enabled through 3G or Wi fi networks (in Wifi-
enabled devices).
Via the Internet directly onto the mobile device - the end-user can access the
manufacturer’s app store via the web browser on his/her device.
Via the Internet and transfer to the mobile device - the end-user can access the
manufacturer’s app store via the web browser on a personal computer and
then transfer over Bluetooth or an external memory to install in the mobile
device.
Mobile applications are commonly made available through aggregators with online
stores. Mobile applications aggregators are not new to the communications industry.
Online stores offering mobile phone ringtones, themes and other applications have
existed since the late 1990s.
76
example, Android mobile applications can be used on Motorola, HTC and Samsung Android Mobile App
devices etc. which have Android Operating system. Development
Mobile network operator—including Telstra, Verizon and Optus. These stores can
only be accessed by consumers with service contracts with the network operator.
Consumers can use multiple handset brands to access these stores.
AppB - advanced colouring app which can edit and use existing art for children
Revenue models are different ways that entrepreneurs can earn money from their
mobile applications. Under this topic we will be explaining three revenue models:
Free Model, Paid model and Paymium model.
Free Model
Free model is also referred to as freemium model. In this model, users don’t pay to
download or use an application. The main advantage of removing the barrier of price
increases the likelihood that users in the target market will download and try. This
initiation can help increase awareness for the application and grow the distribution
among the target user base.
Paid Model
In this model, users pay once to download an application. Then, use the functionalities
provided by that application without any further payments. The paid model is suitable
for users who prefer to pay once to get the full application experience, without in-app
purchases. We will discuss the in-app model in the next section. Often the application
developers need to pay careful attention to include premium experiences through
attractive design and functionality for applications intend to be distributed using paid
model. Since there is only a one-time payment it is important to drive the marketing
strategy to acquire more users. It is advisable that the developers make sure that their
77
Publish to Android Market app’s title, icon, description, preview, screenshots, and other marketing
communications effectively showcase the premium nature of the application.
Paymium Model
Paymium model is essentially a combination of the paid and freemium models. Users
pay to download the application and have the option to buy additional features,
content, or services as they continue to use the application. Paymium model is suitable
for users who would like to engage interacting with the application step-by-step
depending on their requirements. Unlike in the paid model, this model allows a user to
decide whether to acquire more features as and when needed rather than to pay a hefty
price. In-app purchases can reduce the chances of disappointments in paid model
where the user is not fully satisfied with the functionalities and features offered by an
application. Another important aspect is the developers have the flexibility to add
more customizable features.
Offering Subscriptions
This model offer an easy experience for digital subscriptions. In-app purchase APIs
provide a simple, standardized way to implement auto-renewable and non-renewing
subscriptions to content or services. With in-app purchase subscriptions, it is possible
to the price and duration of subscriptions. Duration of subscriptions may be seven
days, one month, two months, three months, six months, or one year. Often AppStores
allow the users to manage the subscription of their applications. For example, in
Apple AppStore a user can manage the subscriptions through the Apple user ID
account.
78
Android Mobile App
14.5 GOOGLE PLAY STORE Development
The Google Play Store or Google Play is a digital distribution service operated and
developed by Google. It serves as the official app store for theAndroid operating
system. GooglePlay allows users to browse and download applications developed with
the Android SDK and published through Google. In Android devices, Google Play
Store is an official pre-installed application. This pre-installed application provides
access to the Google Play store for users to browse and download music, books,
magazines, movies, television programs, and other applications from Google Play.
The Devices segment of Google Play is not accessible through the Play Store. The
Play Store application is not open source. Only Android devices that comply with
Google's compatibility requirements may install and access Google's closed-source
Play Store application, subject to entering into a free-of-charge licensing agreement
with Google.
Applications are available through Google Play use freemium or paid business
models. They can be downloaded directly to an Android or Google TV device through
the Play Store mobile app, or by deploying the application to a device from the
Google Play website. Many applications can be targeted to specific users based on a
particular hardware attribute of their device, such as a motion sensor (for motion-
dependent games) or a front-facing camera (for online video calling). Such specific
application are allowed to download onto devices with appropriate in-built hardware
or sufficient capabilities.
Once the application is developed, the next process is to make it available for the
users to download and use it. To reliably distribute an Android application for the
users to download, an AppStore is required. The steps of the publishing process can
be summarized as follows.
79
Publish to Android Market 14.6.1 Video – V12: Publish to Android Market
This video shows the steps to follow when building your application to
release and releasing the application to users.
URL:https://tinyurl.com/Publish-to-Android-Market
14.7 SUMMARY
This unit covered the topics on revenue and distribution models, process
of launching an Android application in a distributed environment. To
further enhance your understanding on these topics activities and a
supplementary video were provided.
https://www.businessofapps.com/guide/app-stores-list/
https://support.google.com/googleplay/answer/113409?hl=en
https://themanifest.com/mobile-apps/how-publish-app-google-play-step-step-
guide
https://developer.android.com/studio/publish
80
UNIT 15 ANDROID APP PERFORMANCE
15.0 Introduction
15.1 Objectives
15.2 Performance Profiling
15.3 Android Monitor Overview
15.3.1 Video -V13: Performance Profiling
15.3.2 Check Your Progress
15.4 Android Monitor Basics
15.5 Profiling a Running App in Android Monitor
15.6 How Android Manages Memory
15.6.1 Check Your Progress
15.7 Battery Analysis
15.7.1 Video – V14: Battery Analysis
15.8 Optimizing Battery Life
15.8.1 Check Your Progress
15.9 Summary
15.10 Further readings
15.0 INTRODUCTION
In this unit you will learn to analyze the performance of an Android application. First
you will identify and use tools to visualize performance which would enable you to
analyze performance in various aspects of an Android application. Then you will learn
how to improve the performance by optimizing memory usage and minimizing the
power consumption by selecting appropriate techniques.
15.1 OBJECTIVES
After studying this unit, you should be able to :
81
Android App
Performance 15.2 PERFORMANCE PROFILING
Android Monitor provides various sub-tools that you can use to profile the
performance of an app so that you can optimize, debug, and improve them. It lets you
monitor the following aspects of your apps from a hardware device or the Android
Emulator:
It lets you capture data as your app runs and stores it in a file that you can analyze in
various viewers. You can also capture screenshots and videos of your app as it runs.
Android Monitor has a main window that contains performance monitors such as
logcat, Memory, CPU, GPU, and Network Monitors. From this window, you can
select a device and app process to work with, terminate an app, collect dumpsys
system information, and create screenshots and videos of the running app. dumpsys is
an Android tool that runs on the device and dumps information about the status of
system services.
Usage of these performance monitors will be described in the screen cast on
‘Performance monitors’. A brief description of each performance monitor with a
screen shot is given below for you to see what it looks like.
Those screen shots are taken from the weather app shown in Figure 15.1 below.
82
Android Mobile App
Development
In this video you will see how different profiling tools in Android
Monitor are used. These tools are, CPU monitor, GPU monitor,
memory monitor, network monitor and logcat.
URL:https://tinyurl.com/Performance-Profiling
83
Android App
Performance Figure 15.2 Logcat
Memory Monitor – We use the Memory Monitor an in figure 15.3 to evaluate memory
usage and find de-allocated objects, locate memory leaks, and track the amount of
memory that the connected device is using.
84
Android Mobile App
Applications Memory Usage (kB): Development
Uptime: 269104 Realtime: 269104
Cursor 4 4 0 0
Ashmem 2 0 0 0
Other dev 4 0 4 0
.apkmmap 168 0 8 0
.ttfmmap 113 0 72 0
Other mmap 38 8 4 0
App Summary
Pss(KB)
------
Code: 2644
Stack: 120
Graphics: 0
System: 2590
CPU Monitor–As in Figure 15.4, CPU Monitor can be used to display CPU usage in
real time and the percentage of total CPU time (including all cores) used in user and
kernel mode.
85
Android App
Performance
GPU Monitor – You can use the GPU Monitor as in figure 15.5for a visual
representation of how much time it takes to render the frames of a UI window. This
information can be used to optimize the code that displays graphics and conserve
memory.
86
What are the sub-tools provided by the Android Monitor to analyse the Android Mobile App
performance of an app? Development
Data Analysis
Android Monitor also lets you capture various types of data about your app while it is
running and stores it in a file, which you can access later. It lists these files in the
Captures window and you may observe how it works in the screen cast provided for
this unit.
In this section you will be guided how to use the Android Monitor step by step. The
screen cast on Android Monitor Basics will demonstrate this activity.
Android Monitor is integrated into the Android Studio main window:
Note: If you don't see the sidebar buttons, you can display them by selecting
View>Tool Buttons.
A screen shot of Android Monitor is given below in Figure 15.7:
Before start using Android Monitor, you need to set up the environment, as well as the
hardware device or emulator. All of the monitors require the following:
● If you want to run your app on a hardware device (as opposed to the
emulator), connect it to the USB port. Make sure your development computer
detects your device, which often happens automatically when you connect it.
● Enable ADB integration by selecting Tools>Android>Enable ADB
Integration. Enable ADB Integration should have a check mark next to it in
the menu to indicate it's enabled.
All but the logcat Monitor have these additional requirements:
The Network Monitor and the Video Capture tool work with a hardware device only,
not with the emulator.
After you have met the prerequisites and connected a hardware device, you are ready
to profile an app in Android Monitor. To start;
By default, Android Monitor displays data for your most recently run app. You can
switch to another device and app as needed. In addition to currently running apps, you
can view information about apps that are no longer running so you can continue to see
any information about them that you gathered previously.
At the top of the Android Monitor main window, there are two menus listing devices
and processes. To switch to another device, process, or both:
The Device menu lists the devices and emulators that are running or have run during
your current unit. There are various status messages that can appear in the Device
menu:
The Process menu lists the processes that are running or have run during your current
unit. If a process is no longer running, the menu displays status of DEAD.
88
Terminating an App and removing it from a Device Android Mobile App
Development
To stop an app you have run from Android Studio, select the device and the process in
the Android Monitor menus and click ‘Terminate Application’. The process status
changes to DEAD in the Processes menu. The emulator or device may continue to
run, but the app closes. Any running monitors in Android Monitor would stop.
To remove an app from a device you use for development, use the normal uninstall
procedure on the device.
If you run a new version of an app from Android Studio that’s been already installed
on a hardware device, the device displays an Application Installation Failed dialog.
Click OK to install the new version of the app.
From the Android Monitor main window, you can also do the following:
If your app needs a service to perform work in the background, do not keep it running
unless it is actively performing a job. Bbe careful to never leak your service by failing
to stop it when its work is over.
Release memory when your user interface becomes hidden
When the user navigates to a different app and your user interface (UI) is no longer
visible, you should release any resources that are used by only your UI. Releasing UI
89
Android App resources at this time can significantly increase the system's capacity for cached
Performance processes, which has a direct impact on the quality of the user experience.
Release memory as memory becomes tight
During any stage of your app's lifecycle, the onTrimMemory()callback also tells you
when the overall device memory is getting low. You should respond by further
releasing resources based on the memory levels delivered by onTrimMemory().
Because the onTrimMemory() callback was added in API level 14, you can use the
onLowMemory()callback as a fallback for older versions.
Check how much memory you should use
When you load a bitmap, keep it in RAM only at the resolution you need for the
current device's screen. Scale it down if the original bitmap is a higher resolution. You
may keep in mind that an increase in bitmap resolution results in a corresponding in-
memory needed, because both the X and Y dimension increase.
Use optimized data containers
Be knowledgeable about the cost and overhead of the language and libraries you are
using, and keep this information in mind when you design your app, from start to
finish. Often, things on the surface that look trivial may in fact have a large amount of
overhead.
Be careful with code abstractions
External library code is often not written for mobile environments and can be
inefficient when used for work on a mobile client. At the very least, when you decide
90
to use an external library, you should assume you are taking on a significant porting Android Mobile App
and maintenance burden to optimize the library for mobile. Plan for that work up-front Development
and analyse the library in terms of code size and RAM footprint before deciding to use
it at all.
Optimize overall performance
Some of the actions can be taken to optimize your app's performance in various ways
to improve its responsiveness and battery efficiency are given below.
If it is appropriate for your app, an advanced technique that may help you manage
your app's memory is dividing components of your app into multiple processes. This
technique must always be used carefully and most apps should not run multiple
processes, as it can easily increase—rather than decrease—your RAM footprint if
done incorrectly. It is primarily useful to apps that may run significant work in the
background as well as the foreground and can manage those operations separately.
The battery-life impact of performing application updates depends on the battery level
and charging state of the device. The impact of performing updates while the device is
91
Android App charging over AC is negligible, so in most cases you can maximize your refresh rate
Performance whenever the device is connected to a wall charger. Conversely, if the device is
discharging, reducing your update rate helps prolong the battery life.
Similarly, you can check the battery charge level, potentially reducing the frequency
of or even stopping the updates when the battery charge is nearly exhausted.
Battery Historian Walkthrough
This walkthrough shows the basic usage and workflow for the Batterystats tool and
the Battmery Historian script.
Batterystats collects battery data from your device, and Battery Historian converts that
data into an HTML visualization that you can view in your Browser. Batterystats is
part of the Android framework, and Battery Historian script is open-sourced and
available on GitHub at https://github.com/google/battery-historian.
It is good for:
● Showing you where and how processes are drawing current from the battery
and
● Identifying tasks in your app that could be deferred or even removed to
improve battery life.
This video shows you how to analyse battery power and generate a
report.
URL:https://tinyurl.com/ya2lsmko
The Battery Historian chart graphically illustrate power-relevant events over time.
Each row shows a colored bar segment when a system component is active and thus
drawing current from the battery. The chart does not show how much battery was used
by the component, only that the app was active.
92
Charts are organized by category. Android Mobile App
Development
● battery_level: When the battery level was recorded and logged. Reported in
percent, where 093 is 93%. Provides an overall measure of how fast the
battery is draining.
● top: The application running at the top; usually, this is the application that is
visible to the user. If you want to measure battery drain while your app is
active, make sure it is the top app. If you want to measure battery drain while
your app is in the background, make sure it'snot the top app.
● wifi_running: Shows that the Wi-Fi network connection was active.
● screen: Screen is turned on.
● phone_in_call: Recorded when the phone is in a call.
● wake_lock: App wakes up, grabs a lock, does small work, then goes back to
sleep. This is one of the most important pieces of information. Waking up the
phone is expensive, so if you see lots of short bars here, that might be a
problem.
● running: Shows when the CPU is awake. Check whether it is awake and
asleep when you expect it to be.
● wake_reason: The last thing that caused the kernel to wake up. If it's your
app, determine whether it was necessary.
● mobile_radio: Shows when the radio was on. Starting the radio is battery
expensive. Many narrow bars close to each other can indicate opportunities
for batching and other optimizations.
● gps: Indicates when the GPS was on. Make sure this is what you expect.
● sync: Shows when an app was syncing with a backend. The sync bar also
shows which app did the syncing. For users, this can show apps where they
might turn syncing off to save battery. Developers should sync as little as
possible and only as often as necessary.
For more details you may go to following links in Android Developer Forum.
● https://developer.android.com/studio/profile/battery-historian.html
● https://developer.android.com/training/.../battery-monitoring.html
For your app to be ‘good’, it should seek to limit its impact on the battery life of its
device. After studying this section, you will be able to build apps that modify their
functionality and behavior based on the state of its device.
By taking steps such as batching network requests, disabling background service
updates when you lose connectivity, or reducing the rate of such updates when the
battery level is low, you can ensure that the impact of your app on battery life is
minimized, without compromising the user experience.
Here we briefly describe the steps you can take to optimize battery life. You should go
to Android Developer Studio for more details.
(https://developer.android.com/training/monitoring-device-state/index.html) What is
described in detail in this page are summarized below.
Requests that your app makes to the network are a major cause of battery drain
because they turn on the power-hungry mobile or Wi-Fi radios. Beyond the power
needed to send and receive packets, these radios spend extra power just turning on and
keeping awake. Something as simple as a network request every 15 seconds can keep
the mobile radio on continuously and quickly use up battery power.
2. Optimizing for Doze and App Standby
Starting from Android 6.0 (API level 23), Android introduces two power-saving
features that extend battery life for users by managing how apps behave when a
device is not connected to a power source. Doze reduces battery consumption by
deferring background CPU and network activity for apps when the device is unused
for long periods of time. App Standby defers background network activity for apps
with which the user has not recently interacted.
3. Monitoring the Battery Level and Charging State
When you are altering the frequency of your background updates to reduce the effect
of those updates on battery life, check the current battery level.You can stopyour
updates when the battery charge is nearly exhausted.
4. Determining and Monitoring the Docking State and Type
Android devices can be docked into several different kinds of docks. These include
car or home docks and digital versus analog docks. The dock-state is typically closely
linked to the charging state as many docks provide power to docked devices.
5. Determining and Monitoring the Connectivity Status
94
Some of the most common uses for repeating alarms and background services is to Android Mobile App
schedule regular updates of application data from Internet resources, cache data, or Development
execute long running downloads. But if you arenot connected to the Internet, or the
connection is too slow to complete adownload there in no use waking the device to
schedule the update.
You can use the ConnectivityManagerto check the Internet connectivity.
6. Manipulating Broadcast Receivers On Demand
15.9 SUMMARY
https://developer.android.com/studio/profile
https://developer.android.com/games/sdk/performance-tuner/unity/run-
monitor-app
https://developer.android.com/topic/performance/memory-overview
95
Android App
Performance
96
UNIT 16 SECURITY ISSUES
16.0 Introduction
16.1 Objectives
16.2 Security Concerns of an Android Application
16.3 Security Provided by the OS
16.3.1 Check Your Progress
16.4 Information Leakage
16.4.1 Check Your Progress
16.5 Device management policies
16.5.1 Check Your Progress
16.6 Summary
16.7 Further readings
16.0 INTRODUCTION
Android is considered to be the most widely used mobile operating system in the
world today. Being Open Source it is very much vulnerable for security breaches if
the security is not managed properly.
In this unit, first you will learn about security provided by the operating system and
how to analyse an application to understand what security features are built into it.
Then you will study device management policies, which will enable you to design and
develop applications for devices that enforce security policies.
16.1 OBJECTIVES
97
Security Issues
16.2 SECURITY CONCERNS OF AN ANDROID
APPLICATION
There are many security concerns regarding Android applications. One major security
threat is over the limit access permission given and requested by apps. When an app is
downloaded from Google Play, users ignore the extent of permission this app should
have on their devices. Very often, app developers also do not have a clear
understanding as to what permissions a mobile application actually needs and request
overzealous and irrelevant permission. In any operating system, this kind of situations
expose the user to a source of potential risks.
However, risks increase when users download apps from unidentified sources to avoid
paying the fee. Anyone can create a malicious app and upload it on the Internet. This
can result in downloading a malicious app or one that has been modified to
automatically install a virus on Android devices.
Fact that Android is Open Source makes it more vulnerable for malware and
malicious software attacks. However, being Open Source there is a large community
of experts reviewing it and developing patches. Anyway, users are being hacked
without them knowing that they are hacked. Another major security threat faced by
Android platform due to the option of customizing the operating system. Device
manufacturers can modify the OS to make it function optimally on their device.
Moreover, users also can modify the OS, integrating customization layers or launchers.
These practices leads to more security breaches.
Another major issue with Android is fragmentation. It means that there exist multiple
versions of Android, even on latest devices. Since some devices are never updated to
the latest version they will not have the latest security updates. It is also difficult to
take appropriate security measures or educate the users about potential vulnerabilities
because user experience on each device is different.
Android has many security features built into the operating system that significantly
reduce the frequency and impact of application security issues we already discussed.
Latest versions of the operating system is designed in a way that you can build your
apps with default system and file permissions without worrying too much about
security.
Some of the core security features provided by Android OS are:
Android Application Sandbox that isolates your app data and code execution
from other apps by running each application other than system apps with a
different user.
Permission reflects Linux permissions groups and corresponding user related
to app will be assign to particular user group to assign permissions. So, access
restrictions guaranteed even in the kernel level.
An application framework which provides common security functionality
such as cryptography, permissions, and secure inter process communication
Techniques to mitigate risks associated with common memory management
errors
An encrypted file system that can be enabled to protect data on lost or stolen
devices
User-granted permissions to restrict access to system features and user data
Application-defined permissions to control application data on a per-app
basis.
98
Android 6.0 and higher versions ask from user to allow or deny individual Android Mobile App
permissions for application dynamically when needed. Development
However, it is important for you to be familiar with the Android security best
practices as given in https://developer.android.com/training/best-security.html. This
web page describe best practices to be followed when storing data, using permissions,
using networks, validating inputs, handling user data, using web view, using
cryptography, using inter process communication, and dynamically loading code.
Following these practices will reduce many security issues that may adversely affect
the users.
It is recommended to use the Android SDK for application development, rather than
using native development kit. Applications built with native code are more complex,
less portable, and more like to include common memory-corruption errors such as
buffer overflows.
It is widely known that many mobile applications share data with third parties without
the knowledge of users. There are many reports and research papers about in-app
advertising that leak potentially sensitive personal information on millions of mobile
phone users. These data may include how much money users make, whether or not
they have kids, and what their political affiliations are.
Following is a list of situations how information leakage in mobile apps take place.
In one research [1], to test what is being leaked, researchers had created a custom-
built Android app that they installed on more than 200 participants’ phones. From that
they have been able to review the accuracy of personalized advertisements served to
test subjects from the Google mobile ad network, AdMob, based on users’ personal
interests and demographic profiles.
Many researchers [1] [2] have found that the root cause of the privacy leakage is the
lack of isolation between the advertisements and mobile apps. It is reported that
adopting HTTPS would not do anything to protect the advertisement traffic.
Device management policies control features in mobile devices and computers. To use
them, first you have to define the type of policy to support at the functional level.
Policies may cover screen-lock password strength, expiration timeout, encryption, etc.
Any operating system would have its own device management policies. For mobile
devices, these policies can be created by using templates that contain recommended or
custom settings, and then deploying them to devices. Since Android 2.2 (API level 8),
the Android platform offers system-level device management capabilities through the
Device Administration APIs so that the application can be configured to ensure a
strong screen-lock password before displaying restricted content to the user.
‘Android for Work’ is a program for supporting enterprise use of Android. You can
develop apps for Android for Work to take advantages of built in security and
management features in Android. Enterprise mobility management (EMM) providers
and enterprise application developers can accessed it via APIs.
Apps built on Android for Work include data security, app security and device
security as explained below.
100
Data security—Business data is separated in a work profile and protected Android Mobile App
device-wide on work-managed devices. So data leakage prevention policies Development
can easily be applied.
Apps security—Work apps are deployed through ‘Google Play for Work’
preventing installation of apps from unknown sources and apply app
configurations.
Device security— ‘Android for Work’ devices are protected with disk
encryption, lockscreen, remote attestation services, and hardware-backed key
store.
Using ‘Android for Work’, organizations can choose what devices, APIs, and
framework they want to use to develop apps which may enable;
Moreover, ‘Android for Work’ offers a partner program for developers through the
Android for Work DevHub
(https://enterprise.google.com/android/developers/applyDevHub/). It provides
exclusive access to beta features and developer events, along with access to a
community of Android developers making enterprise apps.
In this section, you will learn how to create a security-aware application that manages
access to its content by enforcing device management policies. To do that we will
discuss how to,
First, you need to define the kinds of policy to support at the functional level such as
screen-lock password strength, expiration timeout, encryption, etc.
Then, you must declare the selected policy set, which will be enforced by the
application, in the res/xml/device_admin.xml file. The Android manifest should also
reference the declared policy set.
Each declared policy corresponds to some number of related device policy methods in
DevicePolicyManager(e.g. defining minimum password length and minimum number
of uppercase characters). If an application attempts to invoke methods whose
corresponding policy is not declared in the XML, this will result in a
SecurityException at runtime.
101
Security Issues Create a device administration receiver
You must create a Device Administration broadcast receiver, which gets notification
of events related to the policies you have declared to support. An application can
selectively override callback methods.
Before enforcing any policies, the user needs to manually activate the application as a
device administrator. It is a good practice to include the explanatory text to highlight
to users why the application is requesting to be a device administrator. It can be done
by specifying the EXTRA_ADD_EXPLANATIONextra in the intent.
16.6 SUMMARY
102