Android Final
Android Final
Where is
everything?
developer.android.com/courses/adf-v2
This
Thiswork
workis islicensed
licensedunder
undera aCreative
Creative
Introduction
Introductiontoto
Android Developer Fundamentals V2 Commons
CommonsAttribution
Attribution4.0
4.0International
International 1
Android
Android
License.
License.
1.0 Introduction to Android
● Android is an ecosystem
● Android platform architecture
● Android Versions
● Challenges of Android app development
● App fundamentals
Example:
Your app can use a system app to deliver a SMS
message.
Each app runs in its own process with its own instance of the
Android Runtime.
This
Thiswork
workis islicensed
licensedunder
undera aCreative
Creative
Your
Yourfirst
first
Android
AndroidDeveloper
DeveloperFundamentals
FundamentalsV2
V2 Commons
CommonsAttribution
Attribution4.0
4.0International
International 1
Android
Android appapp
License.
License.
1.1 Your first Android app
● Android Studio
● Creating "Hello World" app in Android Studio
● Basic app development workflow with Android Studio
● Running apps on virtual and physical devices
1. Toolbar
2. Navigation bar
3. Project pane
4. Editor
5. Tabs for other
panes
2. Select virtual
or physical
device
3. OK
Your first This work is licensed under a Creative
Android Developer Fundamentals V2 Commons Attribution 4.0 International 17 17
Android app
License.
Create a virtual device
Use emulators to test app on different versions of Android and form factors.
1. Choose hardware
2. Select Android version
3. Finalize
Windows drivers:
● OEM USB Drivers
Your first This work is licensed under a Creative
Android Developer Fundamentals V2 Commons Attribution 4.0 International 21
Android app
License.
Get feedback as your app runs
1. Emulator
running the
app
2. Run pane
3. Run tab to
open or close
the Run pane
Lesson 1
Views
Button CheckBox
EditText RadioButton
Slider Switch
android:<property_name>="@<resource_type>/resource_id"
Example: android:text="@string/button_label_next"
android:<property_name>="@+id/view_id"
Example: android:id="@+id/show_count"
linearL.addView(myText);
setContentView(linearL);
● Enable Autoconnect in
toolbar if disabled
● Drag element to any part
of a layout
● Autoconnect generates
constraints against
parent layout
Layouts and This work is licensed under a Creative
Android Developer Fundamentals V2 resources for the Commons Attribution 4.0 International 34
UI License.
ConstraintLayout handles
1. Resizing handle
2. Constraint line and handle
3. Constraint handle
4. Baseline handle
● View:
R.id.recyclerview
rv = (RecyclerView) findViewById(R.id.recyclerview);
● String:
In Java: R.string.title
In XML: android:text="@string/title"
Layouts and This work is licensed under a Creative
Android Developer Fundamentals V2 resources for the Commons Attribution 4.0 International 53
UI License.
Measurements
● Density-independent Pixels (dp): for Views
● Scale-independent Pixels (sp): for text
Lesson 1
● TextView
● ScrollView
<TextView android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/my_story"/>
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:text="@string/article_text"/> Don’t use HTML
for a web link in
free-form text
autoLink values:"web", "email", "phone", "map", "all"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>
</ScrollView>
Text and This work is licensed under a Creative
Android Developer Fundamentals V2 Commons Attribution 4.0 International 14
Scrolling Views
License.
ScrollView layout with a view group
<ScrollView ...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/article_subheading"
.../>
<TextView
android:id="@+id/article" ... />
</LinearLayout>
</ScrollView>
<TextView.../>
</LinearLayout>
</ScrollView>
Text and This work is licensed under a Creative
Android Developer Fundamentals V2 Commons Attribution 4.0 International 16
Scrolling Views
License.
Learn more
Developer Documentation:
● TextView
● ScrollView and HorizontalScrollView
● String Resources
Other:
● Android Developers Blog: Linkify your Text!
● Codepath: Working with a TextView
This work
This work isislicensed
licensedunder
underaa Creative
Creative
Resources to help
Android
Android Developer
Developer Fundamentals
Fundamentals V2
V2 Commons Attribution 4.0 International
Commons 1
you learn License.
License.
1.4 Resources
to help you learn
● Documentation
● Tutorials and codelabs
● Blogs and videos
● Udacity courses
● Source code for the practicals
● Course info
● Programs
● Certification details
● Authorized Training
Partners
Videos
● Android Developer YouTube channel
● Udacity online courses
Activities and
Intents
Lesson 2
setContentView(R.layout.activity_main);
}
Resource is layout in this XML file
}
<activity android:name=".MainActivity">
Intent Action
Android
System
Activities and This work is licensed under a Creative
Android Developer Fundamentals V2 Intents
Commons Attribution 4.0 International 18
License.
What can intents do?
● Start an Activity
○ A button click starts a new Activity for text entry
○ Clicking Share opens an app that allows you to post a photo
● Start an Service
○ Initiate downloading a file in the background
● Deliver Broadcast
○ The system informs everybody that the phone is now charging
Activities and This work is licensed under a Creative
Android Developer Fundamentals V2 Intents
Commons Attribution 4.0 International 19
License.
Explicit and implicit intents
Explicit Intent
● Starts a specific Activity
○ Request tea with milk delivered by Nikita
○ Main activity starts the ViewShoppingCart Activity
Implicit Intent
● Asks system to find an Activity that can handle this request
○ Find an open store that sells green tea
○ Clicking Share opens a chooser with a list of apps
Activities and This work is licensed under a Creative
Android Developer Fundamentals V2 Intents
Commons Attribution 4.0 International 20
License.
Starting
Activities
Intent: Start app Start main Intent: Shop Start choose Intent: order Start finish
Android activity Android food activity Android order activity
System System System
OrderActivity
Place order
CartActivity CartActivity
View shopping cart View shopping cart
FoodListActivity FoodListActivity FoodListActivity
Choose food items Choose food items Choose food items
MainActivity MainActivity MainActivity MainActivity
What do you want to do? What do you want to do? What do you want to do? What do you want to do?
Ancestral or up navigation
● provided by the Up button in app's action bar
● controlled by defining parent-child relationships between
activities in the Android manifest
Activities and This work is licensed under a Creative
Android Developer Fundamentals V2 Intents
Commons Attribution 4.0 International 41
License.
Back navigation
● Back stack preserves history of recently viewed screens
● Back stack contains all the Activity instances that have been
launched by the user in reverse order for the current task
● Each task has its own back stack
● Switching between tasks activates that task's back stack
Activities and
Intents
Lesson 2
● Activity lifecycle
● Activity lifecycle callbacks
● Activity instance state
● Saving and restoring Activity state
More formally:
● A directed graph of all the states an Activity can be in,
and the callbacks associated with transitioning from
each state to the next one
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onRestart() {
super.onRestart();
// The activity is between stopped and started.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible
// it is now "resumed"
}
Activity lifecycle This work is licensed under a Creative
Android Developer Fundamentals V2 and state
Commons Attribution 4.0 International 19
License.
onPause() –> Paused
● Called when system is about to resume a previous Activity
● The Activity is partly visible but user is leaving the Activity
● Typically used to commit unsaved changes to persistent data, stop
animations and anything that consumes resources
● Implementations must be fast because the next Activity is not
resumed until this method returns
● Followed by either onResume() if the Activity returns back to the front,
or onStop() if it becomes invisible to the user
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus
// this activity is about to be "paused"
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible
// it is now "stopped"
}
Activity lifecycle This work is licensed under a Creative
Android Developer Fundamentals V2 and state
Commons Attribution 4.0 International 23
License.
onDestroy() –> Destroyed
● Final call before Activity is destroyed
● User navigates back to previous Activity, or configuration
changes
● Activity is finishing or system is destroying it to save space
● Call isFinishing() method to check
● System may destroy Activity without calling this, so use
onPause() or onStop() to save data or state
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
if (savedInstanceState != null) {
String count = savedInstanceState.getString("count");
if (mShowCount != null)
mShowCount.setText(count);
}
}
Activity lifecycle This work is licensed under a Creative
Android Developer Fundamentals V2 and state
Commons Attribution 4.0 International 35
License.
onRestoreInstanceState(Bundle state)
@Override
public void onRestoreInstanceState (Bundle mySavedState) {
super.onRestoreInstanceState(mySavedState);
if (mySavedState != null) {
String count = mySavedState.getString("count");
if (count != null)
mShowCount.setText(count);
}
}
When you stop and restart a new app session, the Activity
instance states are lost and your activities will revert to their
default appearance
Activities and
Intents
Lesson 2
● Intent—recap
● Implicit Intent overview
● Sending an implicit Intent
● Receiving an implicit Intent
Intent Action
Android
System
User has pressed Call button — start Activity that can make
a call (no data is passed in or returned)
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
● Uri.parse("tel:8005551234")
● Uri.parse("geo:0,0?q=brooklyn%20bridge%2C%20brooklyn%2C%20ny")
● Uri.parse("http://www.android.com");
Uri documentation
1. Put extras
String query = edittext.getText().toString();
intent.putExtra(SearchManager.QUERY, query));
Testing, debugging,
and using support
libraries
Lesson 3
● identify problems
● find where in the source code the problem is created
● so that you can fix it
Logcat
pane
Logcat
tab
This work is licensed under a Creative
The Android
Android Developer Fundamentals V2 Commons Attribution 4.0 International 10
Studio debugger License.
Inspect logging messages
First Breakpoint
Force Step Into ⇧F7 Step into a method in a class that you wouldn't
normally step into, like a standard JDK class
Step Out ⇧F8 Step to first executed line after returning from
current method
Run to Cursor ⌥F9 Run to the line where the cursor is in the file
Resume
Pause
Mute all
breakpoints Menu:
Run->Pause Program…
Run->Resume Program...
This work is licensed under a Creative
The Android
Android Developer Fundamentals V2 Commons Attribution 4.0 International 25
Studio debugger License.
Learn more
Testing, debugging,
and using support
libraries
Lesson 3
$10
● Types of Testing
○ Installation, compatibility, regression, acceptance
○ Performance, scalability, usability, security
// assertThat method
import static org.junit.Assert.assertThat;
/**
* JUnit4 unit tests for the calculator logic.
* These are local unit tests; no device needed
*/
@RunWith(JUnit4.class) // Specify the test runner
public class CalculatorTest { // Name it what you are testing
}
● Frees resources
Result details
Testing, debugging,
and using support
libraries
Lesson 3
● compat—compatibility wrappers
● core-utils—utility classes (eg., AsyncTaskLoader)
● core-ui—variety of UI components
● media-compat—back ports of media framework
● fragment—UI component
User Interaction
Lesson 4
Buttons
Buttonsand
and This work is licensed under a Creative
Android
AndroidDeveloper
DeveloperFundamentals
FundamentalsV2
V2 clickable
clickableimages
images
Commons Attribution 4.0 International 1
License.
4.1 Buttons and clickable
images
1. Right-click app/res/drawable
2. Choose New > Image Asset
3. Choose Action Bar and Tab Items
from drop down menu
4. Click the Clipart: image Experiment:
(the Android logo) 2. Choose New > Vector Asset
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do something in response to button click
}
});
<ImageView
android:layout_width="wrap_content" android:onClick
android:layout_height="wrap_content"
android:src="@drawable/donut_circle"
android:onClick="orderDonut"/>
For example:
Add Contact button in Contacts app
● 56 x 56 dp by default
● Set mini size (30 x 40 dp) with app:fabSize attribute:
○ app:fabSize="mini"
● Set to 56 x 56 dp (default):
○ app:fabSize="normal"
User Interaction
Lesson 4
1. EditText
2. SeekBar
3. CheckBox
4. RadioButton
5. Switch
6. Spinner
● Activity.getCurrentFocus()
● ViewGroup.getFocusedChild()
● EditText default
● Alphanumeric keyboard
● Suggestions appear
● Tapping Return (Enter) key starts
new line
Return key
This work is licensed under a Creative
Android Developer Fundamentals V2 Input Controls Commons Attribution 4.0 International 18
License.
Customize with inputType
Emoticons
This work is licensed under a Creative
Android Developer Fundamentals V2 Input Controls Commons Attribution 4.0 International 20
License.
EditText for single line
● Both work:
○ android:inputType
="textLongMessage"
○ android:inputType
="textPersonName"
● Single line of text
● Tapping Done key advances focus
to next View Done key
This work is licensed under a Creative
Android Developer Fundamentals V2 Input Controls Commons Attribution 4.0 International 21
License.
EditText for phone number entry
● android:inputType ="phone"
● Numeric keypad (numbers only)
● Tapping Done key advances focus
to next View
Done key
This work is licensed under a Creative
Android Developer Fundamentals V2 Input Controls Commons Attribution 4.0 International 22
License.
Getting text
● Spinner
Toggle buttons
Switches
User Interaction
Lesson 4
1. Alert dialog
2. Date picker
3. Time picker
1 2 3
<item android:id="@+id/option_settings"
android:title="Settings" />
<item android:id="@+id/option_favorites"
android:title="Favorites" />
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
<item
android:id="@+id/action_favorites"
android:icon="@drawable/ic_favorite"
android:orderInCategory="30"
android:title="@string/action_favorites"
app:showAsAction="ifRoom" />
1. Create XML menu resource file and assign appearance and position attributes
2. Register View using registerForContextMenu()
3. Implement onCreateContextMenu() in Activity to inflate menu
4. Implement onContextItemSelected() to handle menu item clicks
5. Create method to perform action for each context menu item
<item
android:id="@+id/context_share"
android:title="Share"
android:orderInCategory="20"/>
This work is licensed under a Creative
Menus and
Android Developer Fundamentals V2 Commons Attribution 4.0 International 22
pickers License.
Register a view to a context menu
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_context, menu);
}
In onCreate():
View view = findViewById(article);
view.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View view) {
if (mActionMode != null) return false;
mActionMode =
MainActivity.this.startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
This work is licensed under a Creative
Menus and
Android Developer Fundamentals V2 Commons Attribution 4.0 International 31
pickers License.
Implement mActionModeCallback
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_context, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done.
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
1. Create XML menu resource file and assign appearance and position attributes
2. Add ImageButton for the popup menu icon in the XML activity layout file
3. Assign onClickListener to ImageButton
4. Override onClick() to inflate the popup and register it with
onMenuItemClickListener()
5. Implement onMenuItemClick()
6. Create a method to perform an action for each popup menu item
This work is licensed under a Creative
Menus and
Android Developer Fundamentals V2 Commons Attribution 4.0 International 39
pickers License.
Add ImageButton
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_popup"
android:src="@drawable/@drawable/ic_action_popup"/>
In onCreate():
mButton.setOnClickListener(new View.OnClickListener() {
// define onClick
});
User Interaction
Lesson 4
@Override
public void onBackPressed() {
// Add the Back key handler here.
return;
}
Descendant navigation
1. Icon in app bar
2. Header
3. Menu items
<activity android:name=".OrderActivity"
android:label="@string/title_activity_order"
android:parentActivityName="com.example.android.
optionsmenuorderactivity.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="@id/tab_layout" />
User Interaction
Lesson 4
● RecyclerView Components
● Implementing a RecyclerView
dependencies {
...
compile 'com.android.support:recyclerview-v7:26.1.0'
...
}
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
● onCreateViewHolder()
● inBindViewHolder()
● getItemCount()
@Override
public int getItemCount() {
// Return the number of data items to display
return mWordList.size();
}
mRecyclerView = findViewById(R.id.recyclerview);
mAdapter = new WordListAdapter(this, mWordList);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new
LinearLayoutManager(this));
● RecyclerView
● RecyclerView class
● RecyclerView.Adapter class
● RecyclerView.ViewHolder class
● RecyclerView.LayoutManager class
Delightful User
Experience
Lesson 5
● Drawables
● Creating image assets
● Styles
● Themes
Text
3. Click icon to chose clipart
4. Inspect assets for 4
<resources>
<style name="CodeFont">
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
<resources>
<style name="RedCode" parent="@style/Codefont>
<item name="android:textColor">#FF0000</item>
</style>
</resources>
● Android Styles
● Android Themes
● Styles and Themes Guide
● DayNight Theme Guide
Delightful User
Experience
Lesson 5
● Design guidelines
● Visual language
● Combine classic principles of good design with
innovation and possibilities of technology and science
● Material Design Spec
android:textAppearance=
"@style/TextAppearance.AppCompat.Display3"
● Bold hues
● Muted environments
● Deep shadows
● Bright highlights
● Expansion Panels
● Grid Lists
● Lists
● Menus
● Pickers
● Progress Bars
● Selection Controls
Tabs
Delightful User
Experience
Lesson 5
Landscape Portrait
Resources for This work is licensed under a Creative
Android Developer Fundamentals V2 Commons Attribution 4.0 International 14
adaptive layouts
License.
Smallest width
Testing your UI
Lesson 6
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation
'com.android.support.test.espresso:espresso-core:3.0.1'
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
● Store in module-name/src/androidTests/java/
○ In Android Studio: app > java > module-name (androidTest)
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<>(MainActivity.class);
@Before
public void initValidString() {
mStringToBetyped = "Espresso";
}
@Test
public void changeText_sameActivity() {
// 1. Find a View
// 2. Perform an action
// 3. Verify action was taken, assert result
}
Result snippet
android.support.test.espresso.base.DefaultFailureHandler$Assertion
FailedWithCauseError: 'with text: is "This is a failing test."'
doesn't match the selected view.
Expected: with text: is "This is a failing test."
Got: "AppCompatTextView{id=2131427417, res-name=text_message ...
Videos
● Android Testing Support - Android Testing Patterns #1 (introduction)
● Android Testing Support - Android Testing Patterns #2 (onView view matching)
● Android Testing Support - Android Testing Patterns #3 (onData & adapter views)
Background
Tasks
Lesson 7
● Threads
● AsyncTask
● Loaders
● AsyncTaskLoader
● AsyncTask
● The Loader Framework
● Services
Worker Thread Do some work
Worker Thread
doInBackground()
● onProgressUpdate()
○ Runs on the main thread
○ receives calls from publishProgress() from background thread
doInBackground()
doInBackground()
doInBackground()
onProgressUpdate()
doInBackground(
onPostExecute()
● String—could be query, URI for filename
● Integer—percentage completed, steps done
● Bitmap—an image to be displayed
● Use Void if no data passed
AsyncTask and This work is licensed under a Creative
Android Developer Fundamentals V2 AsyncTaskLoader
Commons Attribution 4.0 International 17
License.
onPreExecute()
LoaderManager
Request Receive
Work Result
Activity
AsyncTask and This work is licensed under a Creative
Android Developer Fundamentals V2 AsyncTaskLoader
Commons Attribution 4.0 International 31
License.
AsyncTask AsyncTaskLoader
doInBackground() loadInBackground()
onPostExecute() onLoadFinished()
1. Subclass AsyncTaskLoader
2. Implement constructor
3. loadInBackground()
4. onStartLoading()
@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
return new StringListLoader(this,args.getString("queryString"));
}
@Override
public void onLoaderReset(final LoaderList<String>> loader) { }
Background
Tasks
Lesson 7
networkInfo =
connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isMobileConn = networkInfo.isConnected();
● Use HttpURLConnection
● Must be done on a separate thread
● Requires InputStreams and try/catch blocks
HttpURLConnection conn =
(HttpURLConnection) requestURL.openConnection();
InputStream is = conn.getInputStream();
String contentAsString = convertIsToString(is, len);
return contentAsString;
} finally {
conn.disconnect();
if (is != null) {
is.close();
}
}
{
"population":1,252,000,000,
"country":"India",
"cities":["New Delhi","Mumbai","Kolkata","Chennai"]
}
Background
Tasks
Lesson 7
● Broadcasts
● Send a custom broadcasts
● Broadcast receivers
● Implementing broadcast receivers
● Restricting the broadcasts
● Best practices
Types of broadcast:
● System broadcast.
● Custom broadcast.
Few examples:
● An Intent with action, ACTION_BOOT_COMPLETED is broadcasted
when the device boots.
● An Intent with action, ACTION_POWER_CONNECTED is broadcasted
when the device is connected to the external power.
Custom broadcasts are broadcasts that your app sends out, similar to the
Android system.
For example, when you want to let other app(s) know that some data has
been downloaded by your app, and its available for their use.
LocalBroadcastManager.getInstance(this)
.sendBroadcast(customBroadcastIntent);
This work is licensed under a Creative
Android Developer Fundamentals V2 Broadcasts Commons Attribution 4.0 International 13
License.
Broadcast
Receivers
To add an intent-filter:
● To your AndroidManifest.xml file, use <intent-
filter> tag.
● To your Java file use the IntentFilter object.
This work is licensed under a Creative
Android Developer Fundamentals V2 Broadcasts Commons Attribution 4.0 International 21
License.
Subclass a broadcast receiver
LocalBroadcastManager.getInstance(this).registerReceiver
(mReceiver,
new IntentFilter(CustomReceiver.ACTION_CUSTOM_BROADCAST));
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(mReceiver);
● BroadcastReceiver Reference
● Intents and Intent Filters Guide
● LocalBroadcastManager Reference
● Broadcasts overview
Background
Tasks
Lesson 7
● Network transactions.
● Play music.
● Perform file I/O.
● Interact with a database.
Although services are separate from the UI, they still run
on the main thread by default (except IntentService)
If the service can't access the UI, how do you update the app
to show the results?
@Override
protected void onHandleIntent(Intent intent) {
try {
// Do some work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} // When this method returns, IntentService stops the service, as appropriate.
}
● Services overview
● Background Execution Limits
Alarms and
Schedulers
Lesson 8
■ Small icon
■ Title
■ Detail text
setPriority(NotificationCompat.PRIORITY_HIGH)
This work is licensed under a Creative
Android Developer Fundamentals V2 Notifications Commons Attribution 4.0 International 15
License.
Importance level and priority constants
Importance (Android 8.0 Priority (Android 7.1
User-visible importance level
and higher) and lower)
Urgent
PRIORITY_HIGH or
Makes a sound and appears as a heads-up IMPORTANCE_HIGH
PRIORITY_MAX
notification
High
IMPORTANCE_DEFAULT PRIORITY_DEFAULT
Makes a sound
Medium
IMPORTANCE_LOW PRIORITY_LOW
No sound
Low
No sound and doesn't appear in the status bar IMPORTANCE_MIN PRIORITY_MIN
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.android_icon)
.setContentTitle("You've been notified!")
.setContentText("This is your notification text.");
1. Application context
2. Request code—constant integer id for the pending intent
3. Intent to be delivered
4. PendingIntent flag determines how the system handles
multiple pending intents from same app
Intent notificationIntent =
new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent =
PendingIntent.getActivity(
this,
NOTIFICATION_ID,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
.setContentIntent(notificationPendingIntent);
.addAction(R.drawable.ic_color_lens_black_24dp,
"R.string.label",
notificationPendingIntent);
NotificationCompa.BigPictureStyle
mNotifyManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
mNotifyManager.notify(NOTIFICATION_ID, myNotification);
mNotifyManager.cancel(NOTIFICATION_ID);
This work is licensed under a Creative
Android Developer Fundamentals V2 Notifications Commons Attribution 4.0 International 43
License.
Design guidelines
If your app sends too many notifications, users will disable
notifications or uninstall the app.
● Relevant: Whether this information is essential for the user.
● Timely: Notifications need to appear when they are useful.
● Short: Use as few words as possible.
● Give users the power to choose -- Use appropriate
notification channels to categorise your notifications.
This work is licensed under a Creative
Android Developer Fundamentals V2 Notifications Commons Attribution 4.0 International 44
License.
What's Next?
Alarms and
Schedulers
Lesson 8
BroadcastReceiver
BroadcastReceiver
wakes up the app
wakes up
and delivers the
delivers notification
notification.
Activity creates Alarm triggers and
a notification and sends out Intent.
sets an alarm.
App may be
destroyed so….
This work is licensed under a Creative
Android Developer Fundamentals V2 Alarms Commons Attribution 4.0 International 6
License.
Benefits of alarms
AlarmManager alarmManager =
(AlarmManager) getSystemService(ALARM_SERVICE);
1. Type of alarm.
2. Time to trigger.
3. Interval for repeating alarms.
4. PendingIntent to deliver at the specified time
(just like notifications).
● setInexactRepeating()
○ repeating, inexact alarm.
● setRepeating()
○ Prior to API 19, creates a repeating, exact alarm.
○ After API 19, same as setInexactRepeating().
setInexactRepeating(
int alarmType,
long triggerAtMillis,
long intervalMillis,
PendingIntent operation)
alarmManager.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()
+ AlarmManager.INTERVAL_FIFTEEN_MINUTES,
AlarmManager.INTERVAL_FIFTEEN_MINUTES,
notifyPendingIntent);
This work is licensed under a Creative
Android Developer Fundamentals V2 Alarms Commons Attribution 4.0 International 24
License.
More Alarm
Considerations
boolean alarmExists =
(PendingIntent.getBroadcast(this,
0, notifyIntent,
PendingIntent.FLAG_NO_CREATE) != null);
alarmManager.cancel(alarmPendingIntent);
Alarms and
Schedulers
Lesson 8
● Wi-Fi radio uses less battery and has more bandwidth than
wireless radio.
● Use ConnectivityManager to determine which radio is
active and adapt your strategy.
FALSE—Job finished.
TRUE
● Work has been offloaded.
● Must call jobFinished() from the worker thread.
● Pass in JobParams object from onStartJob().
<service
android:name=".NotificationJobService"
android:permission=
"android.permission.BIND_JOB_SERVICE"/>
● JobInfo.Builder object.
setMinimumLatency(long minLatencyMillis)
setOverrideDeadline(long maxExecutionDelayMillis)
setPeriodic(long intervalMillis)
● Repeats task after a certain amount of time.
● Pass in repetition interval.
● Mutually exclusive with minimum latency and override
deadline conditions.
● Task is not guaranteed to run in the given period.
This work is licensed under a Creative
Efficient data
Android Developer Fundamentals V2 Commons Attribution 4.0 International 30
transfer License.
setPersisted()
setPersisted(boolean isPersisted)
setRequiresCharging(boolean requiresCharging)
setRequiresDeviceIdle(boolean requiresDeviceIdle)
● Whether device must be in idle mode.
● Idle mode is a loose definition by the system, when device is
not in use, and has not been for some time.
● Use for resource-heavy jobs.
● Pass in True or False. Defaults to False.
This work is licensed under a Creative
Efficient data
Android Developer Fundamentals V2 Commons Attribution 4.0 International 33
transfer License.
JobInfo code
mScheduler =
(JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
mScheduler.schedule(myJobInfo);
Preferences
and settings
Lesson 9
● Save new files that the user acquires through your app to a
public directory where other apps can access them and the
user can easily copy them from the device
● Save external files in public directories
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
This work is licensed under a Creative
Android Developer Fundamentals V2 Data storage Commons Attribution 4.0 International 17
License.
Always check availability of storage
developer.android.com/reference/android/os/Environment.html
This work is licensed under a Creative
Android Developer Fundamentals V2 Data storage Commons Attribution 4.0 International 19
License.
Accessing public external directories
1. Get a path getExternalStoragePublicDirectory()
2. Create file
● External storage
myFile.delete();
● Internal storage
myContext.deleteFile(fileName);
● You can use the network (when it's available) to store and
retrieve data on your own web-based services
● Saving Files
● getExternalFilesDir() documentation and code samples
● getExternalStoragePublicDirectory() documentation and code samples
● java.io.File class
● Oracle's Java I/O Tutorial
Preferences
and settings
Lesson 9
● Shared Preferences
● Listening to changes
● SharedPreferences.Editor interface
● Takes care of all file operations
● put methods overwrite if key exists
● apply() saves asynchronously and safely
● You can combine calls to put and clear. However, when you
apply(), clear() is always done first, regardless of order!
SharedPreferences.Editor preferencesEditor =
mPreferences.edit();
preferencesEditor.clear();
preferencesEditor.apply();
SharedPreferences.OnSharedPreferenceChangeListener listener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
// Implement listener here
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
Preferences
and settings
Lesson 9
<SwitchPreference
android:defaultValue="true"
android:title="@string/pref_title_social"
android:key="switch"
android:summary="@string/pref_sum_social" />
</PreferenceScreen>
● android:defaultValue—true by default
● android:summary—text underneath setting, for some
settings, should change to reflect value
● android:title—title/name
● android:key—key for storing value in SharedPreferences
<EditTextPreference
android:capitalize="words"
android:inputType="textCapWords"
android:key="user_display_name"
android:maxLines="1"
android:defaultValue="@string/pref_default_display_name"
android:title="@string/pref_title_display_name" />
<ListPreference
android:defaultValue="-1"
android:key="add_friends_key"
android:entries="@array/pref_example_list_titles"
android:entryValues="@array/pref_example_list_values"
android:title="@string/pref_title_add_friends_to_messages" />
● PreferenceGroup
○ for a group of settings (Preference objects).
● PreferenceCategory
○ title above a group as a section divider
This work is licensed under a Creative
Android Developer Fundamentals V2 App settings Commons Attribution 4.0 International 22
License.
Implement
settings
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, new MySettingsFragment())
.commit();
} This is the
} whole class!
In onCreate() of MainActivity
PreferenceManager.setDefaultValues(
this, R.xml.preferences, false);
● App context, such as this
● Resource ID of XML resource file with settings
● false only calls method the first time the app starts
String destinationPref =
sharedPref.getString("fav_city", "Jamaica");
This work is licensed under a Creative
Android Developer Fundamentals V2 App settings Commons Attribution 4.0 International 42
License.
Respond to
changes in
settings
Storing Data
with Room
Lesson 10
● SQLite Database
● Queries
WORD_LIST_TABLE
_id word definition
1 "alpha" "first letter"
2 "beta" "second letter"
3 "alpha" "particle"
● Insert rows
● Delete rows
● Update values in rows
● Retrieve rows that meet given criteria
● SELECT columns
○ Select the columns to return
○ Use * to return all columns
● SQLite website
● Full description of the Query Language
● SQLite class
● Cursor class
Storing data
with Room
Lesson 10
developer.android.com/arch
Single source of
truth for all app data;
Repository clean API for UI to
communicate with
WordListAdapter
Word architecture
WordRoomDatabase
SQLite WordDao
● 1 instance = 1 row
● Member variable = column name LiveData RoomDatabase
LiveData
Entity
SQLite DAO
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
@Entity(tableName = "word_table")
@NonNull
first_name last_name
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
● be public
OR
pet
name
owner
Activity Instance
ViewModel
Activity UI
Rotation Event
Data
Re-created Activity
Instance
Dao Network
When you pass live data through the layers of your app
architecture, from a Room database to your UI, that data
must be LiveData in all layers:
● DAO
● ViewModel
● Repository
mModel.getCurrentName().observe(this, nameObserver);
This work is licensed under a Creative
Android Developer Fundamentals V2 Room, LiveData, Commons Attribution 4.0 International 68
and ViewModel License.
No memory leaks
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void start() {...}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void start() {...}
SHARED PUBLICLY
Android Developer Fundamentals (V2) is an instructor-led course created by the Google Developers
Training team. Developers taking the course learn basic Android programming concepts and build a
variety of apps, starting with Hello World and working their way up to apps that use a Room
database.
Each lesson contains a slide deck, a concepts chapter, and in most cases, one or more hands-on
tutorial exercises (also known as codelabs). As developers work through the exercises, they create
apps to practice and perfect the skills they're learning. Some lessons are purely conceptual and do
not have practicals.
The course is offered as an in-person course at selected colleges, facilitated by college faculty. All
instructors are invited to use our materials to run their own courses, in accordance with the Creative
Commons license used in the course. The materials are also available online for self-study by
anyone who is familiar with the Java programming language.
Android Developer Fundamentals prepares developers to take the exam for the Associate Android
Developer certification.
Prerequisites
Page 1
Total course hours
Contents
Page 2
Unit 3 – Working in the background
Lesson 7. Background tasks
7.1: AsyncTask and AsyncTaskLoader
7.2: Internet connection
7.3: Broadcast receivers
7.4.0: Services
Page 3
Unit 1 – Get started
This unit covers installing Android Studio, understanding project structure, building your
first app, creating activities, testing your apps, and using the Android Support Library.
First, you deploy a simple Hello World app. You go on to create an app with a single activity,
and then you create a multi-screen app that passes data between activities. You also learn
how to use the Android Support Library to provide backward-compatibility with earlier
versions of the Android system for your app.
Lecture hours: 10
Codelab hours: 11
Page 4
Lesson 1. Build your first app
This lesson covers:
Codelabs
Codelabs
Page 5
in an app scrollable.
Codelabs
Codelabs
Page 6
Lesson 2. Activities and intents
This lesson covers:
- Activities, which are the major building blocks of your app's user
interface.
- Intents: learn about both implicit and explicit intents which are used to
Lesson hours:
communicate between activities.
3 hours Concepts (C)
- Callback events that perform tasks in each stage of the activity lifecycle.
3 hours Codelabs (P)
Codelabs
Codelabs
Codelabs
Page 7
Lesson 3. Testing, debugging, and using support
libraries
This lesson covers:
Codelabs
Codelabs
Codelabs
Page 8
Page 9
Unit 2 – User experience
Create adaptive, responsive user interfaces that work across a wide range of devices.
Create engaging, responsive interfaces that use material design principles. Test your app's
user interface.
Lecture hours: 9
Codelab hours: 10
Page 10
Lesson 4. User interaction
This lesson covers:
Codelabs
Codelabs
Page 11
4.4: User navigation
Learn about the different ways to enable users to navigate through your app.
Codelabs
4.5: RecyclerView
Learn about RecyclerView, which displays items in a list in a way that uses
memory efficiently.
Codelabs
4.5: RecyclerView
Display a list of interactive items in a RecyclerView. Use a floating 1C
action button (FAB) to add new items. 1P
Page 12
Lesson 5. Delightful user experience
This lesson covers:
Codelabs
Codelabs
Codelabs
Page 13
different orientations and screen sizes.
- An overview to UI Testing.
- An introduction to the Espresso Framework.
- Manual Testing.
- Automated Testing.
Lesson hours:
- Using Espresso and UI Automator.
1 hours Concepts (C)
- Recording Tests.
1 hours Codelabs (P)
6.1: UI testing
Learn about testing the user interface of your app.
Codelabs
You write an app that connects to the Internet in a background thread to find the author of
any book. You also build apps that send notifications and schedule tasks, and you learn
how to implement scheduling functionality for apps that run on earlier versions of Android.
Lecture hours: 7
Codelab hours: 6
Page 14
Lesson 7. Background tasks
This lesson covers:
Codelabs
7.1 P AsyncTask 1C
Add an AsyncTask to your app to run a task in the background. 1P
Codelabs
Codelabs
1C
7.3: Broadcast receivers 1P
Page 15
Responds to a system broadcast.Send and receive a custom
broadcast.
7.4.0: Services
Learn about the different types of services, how to use them, and how to
manage their lifecycles within your app. 1C
Page 16
8.1: Notifications
Learn how to create, deliver, and reuse notifications.
Codelabs
8.1: Notifications 1C
Send and update a notification. 1P
8.2: Alarms
Learn how to schedule alarms.
Codelabs
Codelabs
8.3: JobScheduler
Use JobScheduler to schedule tasks in a way that reduces battery 1C
drain. 1P
Page 17
Unit 4 – Saving user data
This unit discusses how to store user data. You learn how to use shared preferences to
save simple key value pairs, then you learn how to use the Room database to save,
retrieve, and update user data. This unit also introduces you to the Android Architecture
Components, which represent best practices for structuring your app.
Lecture hours: 5
Codelab hours: 4
Page 18
Lesson 9. Preferences and settings
This lesson covers:
Codelabs
Codelabs
Page 19
Lesson 10. Storing data with Room
This lesson covers:
- intro to SQLite
- Architecture Components
Lesson hours:
- using Room Database, ViewModel and Repository to save and manage
2 hours Concepts (C)
data in your app
2 hours Codelabs (P)
Codelabs
Page 20