Beginner android

162
Boris Farber Custom Software Solutions Expert [email protected] 1 Effective Android Workshop

Transcript of Beginner android

Page 1: Beginner android

Boris Farber

Custom Software Solutions Expert

[email protected]

1

Effective Android Workshop

Page 2: Beginner android

Disclaimer

2

Android, Google are registered trademarks of Google Inc.

All other trademarks and copyrights are the property of their

respective owners.

Page 3: Beginner android

License (http://www.gnu.org/licenses/fdl.html)

3

Copyright (C) 2011Boris Farber. Permission is granted to copy,

distribute and/or modify this document under the terms of

the GNU Free Documentation License, Version 1.3 or any

later version published by the Free Software Foundation;

with no Invariant Sections, no Front-Cover Texts, and no

Back-Cover Texts. A copy of the license is included in the

section entitled "GNU Free Documentation License".

Page 5: Beginner android

Course Goal

5

To simulate real life Android development for Android

beginner developers

Page 6: Beginner android

Requirements

6

Java experience

Language Model (basics)

Nested Classes

Threads

Collections

Effective Usage

Mobile working experience

Software/Framework Engineering

Framework Experience

Design Patterns

Workbooks and PC with strong cable connection

Page 7: Beginner android

Methodology

7

Minimize slides maximize code

No slides with Copy/Paste APIs

Workshop after workshop

Reading working code

Updating and refactoring real applications

Working directly with real APIs and documentations (thus

simulate real world development)

Solving problems !

Page 8: Beginner android

Workshops

8

First Application

UI

Blocks/Views

Synchronization

Services/Activities

Receivers/Intents

Final Project

Page 9: Beginner android

Workshops

9

For each workshop

1. Download and Run the Application

2. Understand the application

3. Develop, test and present the workshop requirements

Page 10: Beginner android

10

Introduction

Page 11: Beginner android

Introduction to Android Open software platform for mobile development

A complete stack – OS, Middleware, Applications

An Open Handset Alliance (OHA) project

Powered by Linux operating system

Fast application development in Java

Open source under the Apache 2 license

11

Page 12: Beginner android

Android

12

Google’s mobile phone OS and SDK Java only

Special VM

Nonstandard byte code

Eclipse is the development IDE

Linux

Application framework 2D & 3D graphics

Audio, video and still image support

SQLite database

Embeddable web browser

Hardware dependent Bluetooth, EDGE, 3G, WIFI

Camera, GPS, compass

Accelerometer

Page 13: Beginner android

Android Design Philosophy

13

Applications should be:

Fast Resource constraints: <200MB RAM, slow processor

Responsive Apps must respond to user actions within 5 seconds

Secure Apps declare permissions in manifest

Seamless Usability is key, persist data, suspend services

Android kills processes in background as needed

Page 14: Beginner android

Emulator

14

Very useful in developing applications

Not the same as running on real device

Emulator has bugs

Device has different bugs

Device has restriction and limitations

Eclipse starts emulator when run Android app

Can recompile and run app without exiting and restarting

emulator

Page 15: Beginner android

15

Building Blocks/Buzzwords

Page 16: Beginner android

Building Blocks of Android Application

16

AndroidManifest.xml

Activities

Views

Intents

Services

Notifications

Content Providers

Page 17: Beginner android

Android Manifest

17

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.android.hello2"

android:versionCode="1"

android:versionName="1.0.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<activity android:name=".HelloAndroid"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>

Page 18: Beginner android

Activities

Typically correspond to one UI screen

But, they can:

Be faceless

Be in a floating window

Return a value

18

Page 19: Beginner android

Intent Receivers

Components that respond to broadcast ‘Intents’

Way to respond to external notification or alarms

Apps can invent and broadcast their own Intent

19

Page 20: Beginner android

Intents

Think of Intents as a verb and object; a description of what

you want done

E.g. VIEW, CALL, PLAY etc..

System matches Intent with Activity that can best provide the

service

Activities and IntentReceivers describe what Intents they can

service

20

Page 21: Beginner android

Intents

GMail

Contacts

Home

Blogger

Chat

Client component makes a request for a specific action

“Pick photo”

Picasa

System picks best component for that action

New components can use existing functionality

Blogger

Photo Gallery

21

Page 22: Beginner android

Intent

22

Used to move from screen to screen.

Contains:

Data

Action,What you want done

MAIN, VIEW, PICK, EDIT, etc

Intent filter

What intents an activity can handle

To move to a new screen register an intent

startActivity(anIntent).

Page 23: Beginner android

Service

23

Code that runs in the background

Can be long lived

No UI

Example

music player

listening to connection

Page 24: Beginner android

ContentProviders

Enables sharing of data across applications

E.g. address book, photo gallery

Provides uniform APIs for:

querying

delete, update and insert.

Content is represented by URI and MIME type

24

Page 25: Beginner android

View

25

An object that knows how to draw itself to the screen

Set of existing views or widgets

Can create your own view

Games

New widgets

Page 26: Beginner android

Notifications

26

Icon that appears in the status bar

Used to notify user

SMS

Voicemail

Page 27: Beginner android

27

Hello World!+ Analysis

Page 28: Beginner android

Sample App

28

package com.android.hello2;

import android.app.Activity;

import android.os.Bundle;

public class HelloAndroid extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}

Page 29: Beginner android

Resources ids

29

package com.android.hello2;

public final class R {

public static final class attr {

}

public static final class drawable {

public static final int icon=0x7f020000;

}

public static final class layout {

public static final int main=0x7f030000;

}

public static final class string {

public static final int Foo=0x7f040002;

public static final int app_name=0x7f040001;

public static final int hello=0x7f040000;

}

}

Page 30: Beginner android

Layout

30

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/ apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical"

android:paddingLeft="6dip"

android:paddingRight="6dip"

android:paddingBottom="3dip">

<EditText

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:text="Hello, Android from xml"/>

</LinearLayout>

Page 31: Beginner android

Sum up session

You won't get very far just going through the Hello World

tutorial.

There's a ton of important information in the Developer's

guide. A lot of best practices are covered.

It is Java: You work in Java for most of your Android

programming. Don't spend time praising it. Don't spend time

complaining about it. Just work with it.

31

Page 32: Beginner android

32

Effective Android Activities

Page 33: Beginner android

Activity Lifecycle

33

Page 34: Beginner android

Feel the Activity

34

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class CountStates extends Activity

{

int paused = 0;

int killed = 0;

int stopped = 0;

TextView text;

Page 35: Beginner android

Feel the Activity

35

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

if (savedInstanceState != null) {

paused = savedInstanceState.getInt("paused");

killed = savedInstanceState.getInt("killed");

stopped = savedInstanceState.getInt("stopped");

}

text = new TextView(this);

text.setText("Paused: " + paused + " stopped: " +

stopped + " killed “ + killed);

setContentView(text);

}

Page 36: Beginner android

Feel the Activity

36

protected void onResume() {

super.onResume();

text.setText("Paused: " + paused + " stopped: " + stopped + " killed

“+ killed);

}

protected void onStart() {

super.onStart();

text.setText("Paused: " + paused + " stopped: " + stopped + " killed

“+ killed);

}

protected void onStop() {

stopped++;

super.onStop();

}

Page 37: Beginner android

Feel the Activity

37

protected void onPause() {

paused++;

super.onPause();

}

protected void onDestroy() {

killed++;

super.onDestroy();

}

protected void onSaveInstanceState(Bundle outState) {

outState.putInt("paused", paused);

outState.putInt("killed", killed);

outState.putInt("stopped", stopped);

}

}

Page 38: Beginner android

Override onPause/onResume

Make use of onPause()/onResume to save or close what

does not need to be opened the whole time.

protected void onResume() {

mSensorManager.registerListener(...);

}

protected void onStop() {

mSensorManager.unregisterListener(...);

super.onStop();

}

38

Page 39: Beginner android

39

Effective Android Intents

Page 40: Beginner android

Code for this part

40

public void do() {

Intent explicitIntent = new

Intent(this,InvokedActivity.class);

explicitIntent.putExtra(“Key”, “Value”);

startActivity(explicitIntent);

}

Connect between

components

Pass values

Start !

Page 41: Beginner android

Launching Services Activities

41

Methods in

android.content.Context

Action

startActivity(Intent)

startActivityForResult(Intent,

int)

Launch an Activity

sendBroadcast(Intent) send it to any interested

BroadcastReceiver

components

startService(Intent)

bindService(Intent,

ServiceConnection, int)

Start service

Abstract description of an operation to be performed

Page 42: Beginner android

Intents

42

Explicit Intents

Specify the component (class) an intent is to run

Implicit Intents

System determines which component to

run.Information about the request is given

action, type, scheme, categories <intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

Page 43: Beginner android

Implicit Intents

43

action

If given, must be listed by the component as one it handles.

String, which we can create

type

Retrieved from the Intent's data, if not already supplied in the Intent.

If given, must be listed by the component as one it handles

data that is not a content: URI and where no explicit type,

The scheme of the intent data (such as http: or mailto:) is considered

If given, must be listed by the component as one it handles

Categories

If given, all must be listed by the component as ones it handles

Page 44: Beginner android

Launch Intents Always prepare and launch intents from a separate method and

name those methods consistently. The code to launch an intent usually requires minor changes and parameter tweaks as the project progresses.

It changes frequently, and often all the intent code is looked at together. Mixing it in next to other code causes nothing put lingering, hard to debug, headaches.

The performance cost is minimal, mistakes are easier to see, testing is easier, and you won't cringe when need to review all your intent related code.

44

Page 45: Beginner android

Workshop

45

Write 2 basic programs that

Creates service

Registers receiver

Page 46: Beginner android

46

Introduction to UI, part 1

Page 47: Beginner android

View Hierarchy

47

An activity tree is a hierarchical tree

You show it by calling setContentView(rootNode) in the

activity

Page 48: Beginner android

Layout

48

Defines how elements are

positioned relative to each other

(next to each other, under each

other, in a table, grid, etc.)

Can have a different layouts for

each ViewGroup

Page 49: Beginner android

Widgets

49

All are View objects

Examples:

TextFields

EditFields

Buttons

Checkboxes

RadioButtons

etc.

Page 50: Beginner android

All layouts are hierarchical

50

Page 51: Beginner android

All screens are derived from view

51

Page 52: Beginner android

Hierarchical views can include similar

groups

52

Page 53: Beginner android

Children do as told in Android

53

TextView is child of parent viewgroup and fills, or

wraps content

Page 54: Beginner android

There are many types of controls in

Android

54

Page 55: Beginner android

Lists can be handled via adapters and filled

from xml file of values

55

Page 56: Beginner android

Table layout allows for just that with

data

56

Page 57: Beginner android

Views are tied to activities (screens) in

Android

57

One class per

activity, and

screen, which may

be done as xml file

Page 58: Beginner android

One layout per activity (class)

58

main.xml goes with AuctionStart

list.xml goes with ListItems

hit_server.xml goes with

HitServer

Page 59: Beginner android

Xml layout file details components

59

Hierarchy of views as noted earlier

Page 60: Beginner android

Xml layout inflated in onCreate

60

Set value of inflated object

INCOMPLETE CODE

New view items and attached to xml

values

Page 61: Beginner android

Summary

61

Need to provide permissions for network in manifest

Create tree of xml views for UI

Can re-use xml views for different displays

Page 62: Beginner android

62

Introduction to UI, part 2

Page 63: Beginner android

Goal

63

Familiarize with the main types of GUI components

Concepts:

Layouts

Widgets

Menus

Page 64: Beginner android

Linear Layout

64

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="red" android:gravity="center_horizontal" […………………….]

</LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="row one" android:textSize="15pt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> <TextView android:text="row two" android:textSize="15pt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>

[…………………………………..] </LinearLayout> </LinearLayout>

Page 65: Beginner android

One Layout, two views

65

XML File vs Layout Preview

Page 66: Beginner android

Relative Layout

66

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Type here:"/> <EditText android:id="@+id/entry" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:drawable/editbox_background" android:layout_below="@id/label"/> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/entry" android:layout_alignParentRight="true" android:layout_marginLeft="10dip" android:text="OK" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toLeftOf="@id/ok" android:layout_alignTop="@id/ok" android:text="Cancel" /> </RelativeLayout>

Page 67: Beginner android

Table Layout

67

<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="1"> <TableRow> <TextView android:layout_column="1" android:text="Open..." android:padding="3dip" /> <TextView android:text="Ctrl-O" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_column="1" android:text="Save..." android:padding="3dip" /> <TextView android:text="Ctrl-S" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_column="1" android:text="Save As..." android:padding="3dip" /> <TextView android:text="Ctrl-Shift-S" android:gravity="right" android:padding="3dip" /> </TableRow> <View android:layout_height="2dip" android:background="#FF909090" />

[………………………] </TableLayout>

Page 68: Beginner android

List View

68

List of scrollable items

Application will inherit from ListActivity rather than Activity

Create ./res/layout/list_item.xml Layout for each item

Page 69: Beginner android

Override the OnCreate method

69

public class HelloListView extends ListActivity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));

ListView lv = getListView();

lv.setTextFilterEnabled(true);

lv.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

// When clicked, show a toast with the TextView text

Toast.makeText(getApplicationContext(), ((TextView) view).getText(),

Toast.LENGTH_SHORT).show();

}

});

}

}

Setup the list for this

application, with this

layout and this content

Enables filtering by

keyboard

Small Toast showing the

text in the clicked item

for a short time

Page 70: Beginner android

Run it!

70

Page 71: Beginner android

Date Picker

71

Will display a dialogbox allowing to

change the date

Page 72: Beginner android

Layout

72

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/dateDisplay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> <Button android:id="@+id/pickDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Change the date"/> </LinearLayout>

Page 73: Beginner android

OnCreate( )

73

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // capture our View elements mDateDisplay = (TextView) findViewById(R.id.dateDisplay); mPickDate = (Button) findViewById(R.id.pickDate); // add a click listener to the button mPickDate.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(DATE_DIALOG_ID); } }); // get the current date final Calendar c = Calendar.getInstance(); mYear = c.get(Calendar.YEAR); mMonth = c.get(Calendar.MONTH); mDay = c.get(Calendar.DAY_OF_MONTH); // display the current date (this method is below) updateDisplay(); }

Page 74: Beginner android

updateDisplay( )

74

// updates the date in the TextView private void updateDisplay() { mDateDisplay.setText( new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-") .append(mDay).append("-") .append(mYear).append(" ")); }

Page 75: Beginner android

DatePickerDialog.OnDateSetListener( )

75

// the callback received when the user "sets" the date in the dialog private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mYear = year; mMonth = monthOfYear; mDay = dayOfMonth; updateDisplay(); } };

Page 76: Beginner android

onCreateDialog( )

76

@Override

protected Dialog onCreateDialog(int id) {

switch (id) {

case DATE_DIALOG_ID:

return new DatePickerDialog(this,

mDateSetListener,

mYear, mMonth, mDay);

}

return null;

}

Page 77: Beginner android

Run it!

77

Page 78: Beginner android

Selected Listeners, from Android site

78

GestureDetector.OnGestureListener Notify when gestures occur

MenuItem.OnMenuItemClickListener a menu item is clicked.

View.OnClickListener a view is clicked.

View.OnCreateContextMenuListener the context menu for this view is being built.

View.OnFocusChangeListener the focus state of a view changed.

View.OnKeyListener a key event is dispatched to this view.

View.OnLongClickListener a view has been clicked and held.

View.OnTouchListener a touch event is dispatched to this view.

Page 79: Beginner android

79

Introduction to UI, part 3

Page 80: Beginner android

Hello Form Stuff

80

Custom Buttons

Edit Text

Check Boxes

Radio Boxes

Toggle Button

Rating Bar

Page 81: Beginner android

Custom Button

81

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/android_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/android_focused" android:state_focused="true" /> <item android:drawable="@drawable/android_normal" /> </selector>

<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:background="@drawable/android_button" />

final Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { // Perform action on clicks Toast.makeText(HelloFormStuff.this, "Beep Bop", Toast.LENGTH_SHORT).show(); } });

Page 82: Beginner android

Edit Text

82

<EditText android:id="@+id/edittext" android:layout_width="fill_parent" android:layout_height="wrap_content"/>

final EditText edittext = (EditText) findViewById(R.id.edittext); edittext.setOnKeyListener(new OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down event on the "enter" button if ((event.getAction() == KeyEvent.ACTION_DOWN) && (KeyEvent.KEYCODE_ENTER)) { // Perform action keyCode == on key press Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show(); return true; } return false; } });

Page 83: Beginner android

Check Box

83

<CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="check it out" />

final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox); checkbox.setOnClickListener(new OnClickListener() { public void onClick(View v) { // Perform action on clicks, depending on whether it's now checked if (((CheckBox) v).isChecked()) { Toast.makeText(HelloFormStuff.this, "Selected", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(HelloFormStuff.this, "Not selected", Toast.LENGTH_SHORT).show(); } } });

Page 84: Beginner android

Radio Button

84

<RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/radio_red" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Red" /> <RadioButton android:id="@+id/radio_blue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Blue" /> </RadioGroup>

private OnClickListener radio_listener = new OnClickListener() { public void onClick(View v) { // Perform action on clicks RadioButton rb = (RadioButton) v; Toast.makeText(HelloFormStuff.this, rb.getText(), Toast.LENGTH_SHORT).show(); } };

final RadioButton radio_red = (RadioButton) findViewById(R.id.radio_red); final RadioButton radio_blue = (RadioButton) findViewById(R.id.radio_blue); radio_red.setOnClickListener(radio_listener); radio_blue.setOnClickListener(radio_listener);

Page 85: Beginner android

Toggle Button

85

<ToggleButton android:id="@+id/togglebutton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textOn="Vibrate on"

android:textOff="Vibrate off"/>

final ToggleButton togglebutton = (ToggleButton) findViewById(R.id.togglebutton);

togglebutton.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

// Perform action on clicks

if (togglebutton.isChecked()) {

Toast.makeText(HelloFormStuff.this, "Checked", Toast.LENGTH_SHORT).show();

} else {

Toast.makeText(HelloFormStuff.this, "Not checked", Toast.LENGTH_SHORT).show();

}

}

});

Page 86: Beginner android

Rating Bar

86

<RatingBar android:id="@+id/ratingbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="5" android:stepSize="1.0"/>

final RatingBar ratingbar = (RatingBar) findViewById(R.id.ratingbar); ratingbar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() { public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { Toast.makeText(HelloFormStuff.this, "New Rating: " + rating, Toast.LENGTH_SHORT).show(); } });

Page 87: Beginner android

Hello WebView

87

Making a window for viewing

web pages

Page 88: Beginner android

/res/layout/main.xml

88

<?xml version="1.0" encoding="utf-8"?>

<WebView xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/webview"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

/>

Page 89: Beginner android

OnCreate( )

89

WebView mWebView;

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.loadUrl("http://www.google.com"); }

Page 90: Beginner android

AndroidManifest

90

<uses-permission android:name="android.permission.INTERNET" />

<activity android:name=".HelloWebView" android:label="@string/app_name"

android:theme="@android:style/Theme.NoTitleBar">

Page 91: Beginner android

Run it!

91

Page 92: Beginner android

Relative Layout & Sum Up Love RelativeLayout: Most of the tutorials use LinearLayout, but you will find that

RelativeLayout is truly useful. Many layouts, like the GridLayout aren't used much at all. Play around with RelativeLayout

Use fill_parent with a top level RelativeLayout: A surprisingly common and hard to find problem is putting a wrap_content in a top level RelativeLayout and then wondering why unrelated fields far down in the hierarchy are rendering strangely.

Use empty layout items: You will often use empty items in your layouts just for positioning other layouts. For example, you might use an empty TextField, of width=0 and height=0 and centerInParent='True' just to anchor things relative to the middle of the screen. Also, you might have an empty TextField or LinearLayout so that you can give a layout_weight=1 to it and have it take up more screen space.

Set a layout background color: If you are having trouble figuring out your layout, try setting the background colors on some objects. It can highlight your mistakes faster than other tools, and shows some surprises that the IDE red box doesn't always help.

92

Page 93: Beginner android

93

Threads and Services

Page 94: Beginner android

Background Processes

94

One of the key strengths of Android is the ability to run

things in the background on Android

Threads

Run something in the background while user interacts with UI

Services

Regularly or continuously perform actions that don’t require a UI

Page 95: Beginner android

Threads

95

Recall that Android ensures responsive apps by enforcing a 5

second limit on Activities

Sometimes we need to do things that take longer than 5

seconds, or that can be done while the user does something

else

Page 96: Beginner android

Threads

96

Activities, Services, and Broadcast Receivers run on the main

application thread

We can start background/child threads to do things for us

Page 97: Beginner android

Threads

97

private void methodInAndroidClass() {

Thread thread = new Thread(null, doSomething, “Background”);

thread.start();

}

private Runnable doSomething = new Runnable() {

public void run() { /* do the something here */ }

};

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

private void methodInAndroidClass() {

new Thread(){

public void run() {/* do the something here */ }

}.start();

}

Page 98: Beginner android

Example

98

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

new Thread() {

public void run() {

String maps = null;

try {

URL updateURL = new URL("http://simexusa.com/cm/mapdata.txt");

URLConnection conn = updateURL.openConnection();

int contentLength = conn.getContentLength();

InputStream is = conn.getInputStream();

BufferedInputStream bis = new BufferedInputStream(is,1024);

ByteArrayBuffer baf = new ByteArrayBuffer(contentLength);

int current = 0;

while((current = bis.read()) != -1){

baf.append((byte)current);

}

maps = new String(baf.toByteArray()); //Convert the Bytes read to a String.

} catch (Exception e) {}

}

}.start();

}

Get data from web in background

Now we want to display data on screen

Page 99: Beginner android

Android Thread Constraints

99

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

TextView hello = (TextView)this.findViewById(R.id.hellotv);

hello.setText("testing");

new Thread() {

public void run() {

String maps = null;

try {

URL updateURL = new URL("http://simexusa.com/cm/mapdata.txt");

URLConnection conn = updateURL.openConnection();

int contentLength = conn.getContentLength();

InputStream is = conn.getInputStream();

BufferedInputStream bis = new BufferedInputStream(is,1024);

ByteArrayBuffer baf = new ByteArrayBuffer(contentLength);

int current = 0;

while((current = bis.read()) != -1){

baf.append((byte)current);

}

maps = new String(baf.toByteArray()); //Convert the Bytes read to a String.

} catch (Exception e) {}

TextView hello = (TextView)findViewById(R.id.hellotv);

hello.setText(maps);

}}.start();

CalledFromWrongThreadException: Only the original

thread that created a view hierarchy can touch its views.

Page 100: Beginner android

Android Thread Constraints

100

Child threads cannot access UI elements (views); these must be

accessed through the main thread

What to do?

Give results to main thread and let it use results

In Campus Maps I set a flag in the thread, then I added the menu item

dynamically in Activity.onPrepareOptionsMenu

Page 101: Beginner android

Solution

101

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final TextView hello = (TextView)this.findViewById(R.id.hellotv);

hello.setText("testing");

new Thread() {

public void run() {

String maps = null;

try {

URL updateURL = new URL("http://simexusa.com/cm/mapdata.txt");

URLConnection conn = updateURL.openConnection();

int contentLength = conn.getContentLength();

InputStream is = conn.getInputStream();

BufferedInputStream bis = new BufferedInputStream(is,1024);

ByteArrayBuffer baf = new ByteArrayBuffer(contentLength);

int current = 0;

while((current = bis.read()) != -1){

baf.append((byte)current);

}

maps = new String(baf.toByteArray()); //Convert the Bytes read to a String.

} catch (Exception e) {}

hello.setText(maps);

}}.start();

Page 102: Beginner android

Post to GUI Thread

102

Handler allows you to post Messages and Runnable objects to

threads

These can be scheduled to run at some point in the future, or

enqueued for another thread

Page 103: Beginner android

Post to GUI Thread

103

public class BackgroundDemos extends Activity {

private Handler handler = new Handler();

private String maps = null;

TextView hello;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

hello = (TextView)this.findViewById(R.id.hellotv);

hello.setText("testing");

new Thread() {

public void run() {

try {

URL updateURL = new URL("http://simexusa.com/cm/mapdata.txt");

//code omitted here

maps = new String(baf.toByteArray()); //Convert the Bytes read to a String.

handler.post(doUpdateMaps);

} catch (Exception e) {} } }.start();

}

private Runnable doUpdateMaps = new Runnable() {

public void run() {

hello.setText(maps);

}

};}

Page 104: Beginner android

Services

104

Services are like Activities, but without a UI

Services are not intended as background threads Think of a media player where the song keeps playing while the

user looks for more songs to play or uses other apps

Don’t think of a cron job (e.g. run every day at 3am), use Alarms to do this

Several changes in 2.0 related to Services See http://android-

developers.blogspot.com/2010/02/service-api-changes-starting-with.html

Page 105: Beginner android

105

Update service

something is

happening via

startService()

Expose

interfaces via

Binder

Page 106: Beginner android

Tradeoffs

106

If you application involves only activities and services use

messengers(threads running) and startService/startActivities

usually the simple desired case

If your application has more complicated objects that need to

communicate (or request “services” such as context) with

services and activities use binder. Think twice before applying

Page 107: Beginner android

Creating the Service

107

Add to AndroidManifest.xml

<service android:enabled=“true” android:name=“.NewMapService”></service><

Create the class

public class NewMapService extends Service {

@Override

public void onCreate() {

}

@Override

public void onStart(Intent intent, int startId) {

//do something

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

}

Page 108: Beginner android

Start/Stop the Service

108

public class MyActivity extends Activity {

@Override

public void onCreate() {

startService(new Intent(this, NewMapService.class);

}

@Override

public void onStop() {

stopService(new Intent(this, NewMapService.class));

}

}

Page 109: Beginner android

Status Bar Notifications

109

NotificationManager nm = (NotificationManager)getSystemService(

Context.NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable.icon,

"NewMaps",System.currentTimeMillis());

String expandedTitle = "New Map Service";

String expandedText = "New Map Service is running";

Intent i = new Intent(this, NewMapService.class);

PendingIntent launchIntent = PendingIntent.getActivity( getApplicationContext(), 0, i, 0);

notification.setLatestEventInfo(

getApplicationContext(), expandedTitle, expandedText, launchIntent);

nm.notify(1,notification);

nm.cancel(1); //cancel a notification (id/parameters must match)

Page 110: Beginner android

Other Notification

110

Sounds

Vibration

Flashing lights

Ongoing and Insistent

Page 111: Beginner android

Workshop

111

Add functionality to your Hello Service program

Explain your solution

Page 112: Beginner android

112

Intents and Broadcast Receivers

Page 113: Beginner android

Intents

113

Allows communication between loosely-connected components

Allows for late run-time binding of components

Explicit

Intent myIntent = new Intent(AdventDevos.this, Devo.class);

myIntent.putExtra("ButtonNum", ""+index);

startActivity(myIntent);

//finish(); //removes this Activity from the stack

Implicit

Intent i = new Intent(Intent.ACTION_VIEW,

Uri.parse("http://www.biblegateway.com/passage/?searc h="+ passage +"&version=NIV"));

startActivity(i);

Page 114: Beginner android

Other Native Android Actions

114

ACTION_ANSWER – handle incoming call

ACTION_DIAL – bring up dialer with phone #

ACTION_PICK – pick item (e.g. from contacts)

ACTION_INSERT – add item (e.g. to contacts)

ACTION_SENDTO – send message to contact

ACTION_WEB_SEARCH – search web

Page 115: Beginner android

Sub-Activities

115

Activities are independent

However, sometimes we want to start an activity that gives us

something back (e.g. select a contact and return the result)

Use

startActivityForResult(Intent i,

int id)

instead of

startActivity(Intent)

Page 116: Beginner android

Capturing Intent Return Results

116

class ParentActivity extends Activity {

private static final int SUB_CODE = 34;

Intent intent = new Intent(…);

startActivityForResult(intent, SUB_CODE);

@Override

public void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == SUB_CODE)

if (resultCode == Activity.RESULT_OK) {

Uri returnedUri = data.getData();

String returnedString = data.getStringExtra(SOME_CONSTANT,””);

}

if (resultCode == Activity.RESULT_CANCELED) { … }

}

};

Page 117: Beginner android

Capturing Intent Return Results

117

class SubActivity extends Activity {

if (/* everything went fine */) {

Uri data = Uri.parse(“content://someuri/”);

Intent result = new Intent(null,data);

result.putStringExtra(SOME_CONSTANT, “This is some

data”);

setResult(RESULT_OK, result);

finish();

}

if (/* everything did not go fine or the user did not

complete the action */) {

setResult(RESULT_CANCELED, null);

finish();

}

};

Page 118: Beginner android

Using a Native App Action

118

public class MyActivity extends Activity {

//from http://developer.android.com/reference/android/app/Activity.html

... static final int PICK_CONTACT_REQUEST = 0; protected boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( new Intent(Intent.ACTION_PICK, new Uri("content://contacts")), PICK_CONTACT_REQUEST); return true; } return false; } protected void onActivityResult(int requestCode,

int resultCode, Intent data) { if (requestCode == PICK_CONTACT_REQUEST) { if (resultCode == RESULT_OK) { // A contact was picked. Here we will just display it to // the user. startActivity(new Intent(Intent.ACTION_VIEW, data)); } }

}

}

Page 119: Beginner android

Broadcasts and Broadcast Receivers

119

So far we have used Intents to start Activities

Intents can also be used to send messages anonymously

between components

Messages are sent with sendBroadcast()

Messages are received by extending the

BroadcastReceiver class

Page 120: Beginner android

Sending a Broadacst

120

//…

public static final String MAP_ADDED =

“com.simexusa.cm.MAP_ADDED”;

//…

Intent intent = new Intent(MAP_ADDED);

intent.putStringExtra(“mapname”, “Cal

Poly”);

sendBroadcast(intent);

//…

Typically like a package name to

keep it unique

Page 121: Beginner android

Receiving a Broadcast

121

public class MapBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Uri data = intent.getData();

String name = data.getStringExtra(“mapname”);

//do something

context.startActivity(…);

}

};

Broadcast Receivers are started automatically – you don’t have to try to keep an Activity running

Less than 5 seconds

Page 122: Beginner android

Registering a BroadcastReceiver

122

Statically in ApplicationManifest.xml <receiver android:name=“.MapBroadcastReceiver”>

<intent-filter>

<action android:name=“com.simexusa.cm.MAP_ADDED”>

</intent-filter>

</receiver>

Dynamically in code (e.g. if only needed while visible) IntentFilter filter = new IntentFilter(MAP_ADDED);

MapBroadcastReceiver mbr = new MapBroadcastReceiver();

registerReceiver(mbr, filter);

unregisterReceiver(mbr);

Page 123: Beginner android

Native Broadcasts

123

ACTION_CAMERA_BUTTON

ACTION_TIMEZONE_CHANGED

ACTION_BOOT_COMPLETED

requires RECEIVE_BOOT_COMPLETED permission

Page 124: Beginner android

Intent Filters

124

Intent filters register application components with Android

Intent filter tags: action – unique identifier of action being serviced

category – circumstances when action should be serviced (e.g. ALTERNATIVE, DEFAULT, LAUNCHER)

data – type of data that intent can handle Ex. URI = content://com.example.project:200/folder/subfolder/etc

Components that can handle implicit intents (one’s that are not explicitly called by name), must declare category DEFAULT or LAUNCHER

Page 126: Beginner android

Android References Download Apps-For-Android: This is a big chunk of useful source code

for a half dozen applications. It can supplement the sample applications

nicely and show different coding style solutions.

Download the source: You need the Android source to solve some

problems or, more likely, get past holes in the documentation. Your copy

does not need to perfect or kept up to date.

Learn to search your source: The fastest solution to many problems is to

find where a particular parameter is used in some other source. Put a

copy or link to the sample applications, apps-for-android applications,

and any other source you have under one directory tree. Use "grep -ir

funky_parameter sample_code/" or your favorite searching routine to

quickly find some code that uses that parameter.

126

Page 127: Beginner android

Workshop

127

Add functionality

Explain your solution

Page 128: Beginner android

Persistence

128

Page 129: Beginner android

Persistence

Three ways to store data

Shared Preferences

Files

SQL (out of scope)

129

Page 130: Beginner android

Shared Preferences

Three forms:

Share across all components in an application

getSharedPreferences(“SomeString”,Activity.MODE_PRIVATE);

Store only data needed by this Activity

getPreferences(Activity.MODE_PRIVATE);

Store only data needed by this Activity when Activity becomes inactive

(but not when finished)

Ex. Orientation change from portrait to landscape

use Bundle in onSaveInstanceState/onRestoreInstanceState/onCreate

130

Page 131: Beginner android

Shared Preferences Across all components (from context)

public static final String CMPREFS = "CampusMapSharedPreferences";

private void savePreferences() {

SharedPreferences cmSharedPreferences =

getSharedPreferences(CMPREFS,Activity.MODE_PRIVATE);

SharedPreferences.Editor editor = cmSharedPreferences.edit();

editor.putBoolean(VIRTUAL_MODE, inVirtualMode);

editor.commit();

}

private void restorePreferences() {

SharedPreferences cmSharedPreferences =

getSharedPreferences(CMPREFS,Activity.MODE_PRIVATE);

inVirtualMode = cmSharedPreferences.getBoolean(VIRTUAL_MODE, true/*def value*/);

}

131

Page 132: Beginner android

Shared Preferences Only for this Activity (each Activity has one)

private void savePreferences() {

SharedPreferences cmActivityPreferences =

getPreferences(Activity.MODE_PRIVATE);

SharedPreferences.Editor editor = cmActivityPreferences.edit();

editor.putBoolean(VIRTUAL_MODE, inVirtualMode);

editor.putInt(MAP_INDEX, curMapIndex);

editor.commit();

}

private void restoreUIState() {

SharedPreferences cmActivityPreferences =

getPreferences(Activity.MODE_PRIVATE);

inVirtualMode = cmActivityPreferences.getBoolean(VIRTUAL_MODE, true);

curMapIndex = cmActivityPreferences.getInt(MAP_INDEX, 0);

}

132

Page 133: Beginner android

Files Generally not recommended to use files

Store read-only static files in res/raw

133

Page 134: Beginner android

Files Standard java.io is available

Can also use openFileOutput and openFileInput

byte[] b = new String("Yo").getBytes();

try {

FileOutputStream fos =

openFileOutput("anotherExampleFile.txt",

Context.MODE_WORLD_WRITEABLE);

fos.write(b);

FileInputStream fis =

openFileInput("anotherExampleFile.txt");

fis.read(b);

} catch (IOException e) {}

134

Page 135: Beginner android

Wrap Up

135

Page 136: Beginner android

Wrap Up

136

Covered most of basic very basic Android APIs and usage

Practice Practice and Practice

Doesn’t covered 100% of API

No brain is not enough

No need, what is most important is cope with problems

Page 137: Beginner android

From Here Advanced Android

137

NDK

Open Source project research

Page 138: Beginner android

Appendix UI Sessions

138

Page 139: Beginner android

Design Considerations

Dos and Don’t

Principles of Effective UI Design

Rules of Thumb

Testing

139

Page 140: Beginner android

Now

Take 30 min and learn out sample android application

140

Page 141: Beginner android

Design considerations

Physical screen size

Screen density

Portrait & landscape orientations

Primary UI interaction method

Touch-screen

D-pad/trackball

Soft & physical keyboard

141

Page 142: Beginner android

Don’ts

DON’T simply port your UI from other platforms

Users should feel right at home

with your app on their device

Balance your brand and platform look

DON’T overuse modal progress & confirmation dialogs

DON’T create 1000 activities. When you open an activity,

it's another app open on the top on others. As a result,

closing the app one by one can eventually piss off the user, or

at least confuse him.

142

Page 143: Beginner android

Don’ts

DON’T create rigid, absolute-positioned layouts

DON’T use px units, use dp (or sp for text)

DON’T use small font sizes

143

Page 144: Beginner android

Dos

DO create versions of all resources for high

density screens

DO make large, obvious tap targets (buttons, list items)

DO follow Android icon guidelines

DO use proper margins and padding

144

Page 145: Beginner android

Dos

DO support D-pad & trackball navigation

DO properly manage the activity stack

DO properly handle orientation changes

DO use theme/style, dimension, color

resources to reduce redundancy

145

Page 146: Beginner android

Dos

Do design for big fingers.

Do design for interruption. It's a phone : it gets on and off,

calls income, music is played, etc. Your app will be open and

shut a 1000 times so cut loading, save the right states and

ensure congruency.

DO work with visual and interaction designer(s)

146

Page 147: Beginner android

Principles of good interface design

1.Focus on the user

2. Make the right things visible

3. Show proper feedback

4. Be predictable

5. Be fault-tolerant

147

Page 148: Beginner android

1. Know your users

Know your users

Age, skill level, culture, disabilities, etc.

What they want to do with your app

What kinds of devices they’ll be using

Where/when/how they’ll be using their devices

Design with a ‘user-first’ mentality

Users are generally task-driven

Test on real users, early and often

148

Page 149: Beginner android

2. Make the right things visible

The most common operations should be immediately visible

and available

Secondary functionality can be reserved for the MENU

button

149

Page 150: Beginner android

3. Show proper feedback

Have at least 4 states (<selector>) for all interactive UI

elements:

Make sure the effects of an action are clear and visible

Show adequate yet unobtrusive progress indicators

150

Page 151: Beginner android

4. Be predictable

Do what the user expects

Properly interact with the activity stack

Show information and actions users expects to see (requires

testing or observation)

Use proper affordances If something is clickable, make sure

it looks clickable!

If complex instructions are required, rethink your design.

151

Page 152: Beginner android

5. Be fault tolerant

Constrain possible operations to only those that make sense

Disable UI elements when appropriate

Limit the number of irreversible actions

Prefer ‘undo’ to confirmation dialogs

In fact, use as few modal dialogs as possible. They’re obtrusive.

Awareness about the ways in which devices can vary

is very important

152

Page 153: Beginner android

Testing

Buy a real phone ASAP. There are plenty of things you just

can't know if you run your app only on the emulator.

Don't think about releasing your app without having using it

for at least 2 week yourself on the phone.

Desktop computer experience does not suit.

153

Page 154: Beginner android

Rules of thumb 1 Read the UI guidelines

2 Understand and design for touch mode

3 But, support multiple interaction modes

4 Use notifications and the window shade

5 Support interaction between applications

6 Keep your UI fast and responsive

7 Use widgets and live folders

8 Handle screen orientation changes

9 Use images wisely

10 Use layouts that adapt to multiple devices

154

Page 155: Beginner android

Appendix Platform High Level View

155

Page 156: Beginner android

156

Page 157: Beginner android

Linux Kernel

• Works as a HAL

• Device drivers

• Memory management

• Process management

• Networking

157

Page 158: Beginner android

Libraries

• C/C++ libraries

• Interface through Java

• Surface manager – Handling UI Windows

• 2D and 3D graphics

• Media codecs, SQLite, Browser engine

158

Page 159: Beginner android

Android Runtime

•Dalvik VM

•Dex files

•Compact and efficient than class files

•Limited memory and battery power

•Core Libraries

•Java 6 edition

•Collections, I/O etc…

159

Page 160: Beginner android

Application Framework

• API interface

• Activity manager – manages application life cycle.

160

Page 161: Beginner android

Applications

• Built in and user apps

• Can replace built in apps

161

Page 162: Beginner android

162