2. App Fundamentals
• Android app lives in its own world
– Own process, app files only visible to the app
• Apps can make use of other apps, information
sharing, moving between apps
• Apps are build using Android components
• Every app holds a application description file
(AndroidManifest.xml)
– In the file you define the android components
4. Components
• Android app is built using components
– Activity: User visible Window
– Service: Background service (no UI)
– Broadcast Receiver: receiving broadcasts from apps
and system services
– Content provider: Provides content to apps
• Components are separate building blocks that
can be accessed by other apps!
• Components are usually declared in application
manifest
6. 1. Activities
• An activity is a single, focused thing that the
user can do
– Equivalent to Frame or Window in GUI toolkits
• Subclass of Activity – class
• One app may have one or several activities
• Each activity is given a default window to draw
in
• Window consists of views (widgets)
8. Activity Stack
• Android keeps navigation history of activities
the user has visited: Activity Stack or the Back
Stack
• Pressing Back displays the previous Activity!
• User cannot go further than the last visit of
home
10. About Tasks
• Task is a sequence of activities
• Task can hold activities from several apps
• Activity that starts the task is called root
activity
– Usually started from home screen
• New task is started when new app is
launched. Also new task can be started on
certain activities (opening browser, maps..)
• Recent task switcher shows the recent tasks..
15. Activity Lifecycle: States
• Resumed
– App is in foreground and user can interact with it
• Paused
– Partially obscure by another activity.
• Stopped
– not visible, in background. All member variables are
retained, cannot execute code.
• Other states
– Createdand Started – system quickly moves from
them to the next state!
16. public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
// The derived class must invoke these: super.onCreate(…),
// super.onStart()..
17. • onCreate()
– Create the user interface
• onStart()
– When visible to user
• onResume()
– Activity is visible again, initialize fields, register listeners,
bind to services
• onPause()
– Activity still partially visible, but most often is an indication
that the user is leaving the activity and it will soon enter
the stopped state. Release resources, save app data,
unregister listeners, unbind services
• onStop()
– Activity is no longer visible to user. Time or CPU intensive
shut-‐down operations like writing information to database
18. "Importance Hierarchy"
• When running out of memory, what to kill?
1. Background Process – When task is not visible to
user
2. Service Process – killed only if memory is
needed for foreground and visible processes
3. Visible Process – killed only if keep foreground
processes alive
4. Foreground Process – killed only as last resort
19. // ACTIVITY 1
public class Activity1 extends Activity implements OnClickListener {
private Button changeActivity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
changeActivity = (Button) findViewById(R.id.Button01);
changeActivity.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(this, Activity2.class);
startActivity(intent);
}
}
21. State Information
• Think about following situation:
1. User opens app and Activity 1 opens. User is
prompt a name in EditText. User writes his/her
name.
2. User navigates from Activity 1 to Activity 2
3. User presses back button and Activity 1 is
opened again
• Is the name still there?
22. How to Store State Information
• Store state:
– onSaveInstanceState(Bundle)
• Read state
– onRestoreInstanceState(Bundle)
• This will store data only temporarily: for app
lifetime!
• Data will be held in memory until the app is
closed!
26. Intro to Intents
• Intents are message-‐passing mechanism that
lets you declare your intentation than an
action be performed with a particular piece
of data
• Interaction between any android component
• Uses
– Start new activities
– Broadcast messages
– Start new services
27. Intents and Intents Filter
• Intents can be used to
– start activities and services
– broadcast data between components
• Intent
– Message to someone
– Request an action to be performed
– Interaction between any app component on Android
• Intent Filter
– Who can handle the message?
– Register Activity, Service and Broadcast receiver
28. Explicit vs Implicit Intents
• Explicit
– Open explicitly certain Activity
– Internal messaging between your app
– Designated target class
• Implicit
– External messaging between apps
– Open some Activity with certain service
• you don’t know which activity of which app…
29. Explicit Intent
// This is done in some Activity-class:
Intent intent = new Intent(this,
SecondActivity.class);
startActivity(intent)
30. Sending Data
Intent intent = new Intent(this,
SecondActivity.class);
// Extra data is key/value pairs
// Send data
intent.putExtra(“key”, “value”);
startActivity(intent);
31. Receiving the Information
public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();
if (extras != null){
String value1 = extras.getString("key");
}
....
32. public class GettingResultsBack extends Activity {
private static final int REQUEST_CODE = 10;
...
public void clickButton(View v) {
if (v == settings) {
Intent intent = new Intent(this,
Settings.class);
startActivityForResult(intent, REQUEST_CODE);
}
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
String result = bundle.getString("somevalue");
}
}
}
}
33. Getting results Back
@Override
public void onBackPressed() {
Intent intent = new Intent();
number = phoneNumber.getText().toString();
intent.putExtra("phonenumber", number);
setResult(RESULT_OK, intent);
super.onBackPressed();
}
34. Implicit Intents
• Implicit Intents are mechanism that lets open
anonymous application’s components
• Android will at run time resolve the best class
suited to performing the action
– Your app will use other app’s functionality without
knowing exactly which application!
• Various native apps provide components that
can be called implicitly
35. Implicit Intent’s Pieces
• Primary pieces of information in Intent’s are
1. Action
• The general action to be performed, for example
ACTION_DIAL, ACTION_VIEW
2. Data
• The data to operate on expressed in Uri
• Example action/data pairs
– ACTION_VIEW, content://contacts/people/1
– ACTION_VIEW, content://contacts/people/
– ACTION_DIAL, tel://123456
• I want to view (action) a webpage (URI)
36. Using Implicit Intents
Intent intent = new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:123456"));
startActivity(intent);
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://..");
startActivity(intent);
Intent Filter's
name
Data
37. Lot of Native Android Actions
• All the String constants can be found from Intent class. These are native
actions.
• Activity
– ACTION_ANSWER (=“android.intent.action.ANSWER”)
– ACTION_CALL
– ACTION_BUG_REPORT
– ACTION_POWER_USAGE_SUMMARY
– …
• Broadcast
– ACTION_BATTERY_CHANGED
– ACTION_BATTERY_LOW
– ACTION_BOOT_COMPLETED
– ACTION_AIRPLANE_MODE_CHANGED
– ACTION_CAMERA_BUTTON
– ...
38. public void clicked(View button) {
...
case R.id.button1:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.tamk.fi"));
startActivity(intent);
break;
case R.id.button2:
intent = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:(+358)12345789"));
startActivity(intent);
break;
case R.id.button3:
intent = new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:(+358)12345789"));
startActivity(intent);
break;
case R.id.button4:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:60.123,60.1434?z=19"));
startActivity(intent);
break;
case R.id.button5:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:0,0?q=kauppakadun rauta"));
startActivity(intent);
break;
case R.id.button6:
intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
break;
case R.id.button7:
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/"));
startActivity(intent);
break;
case R.id.button8:
intent = new Intent(Intent.ACTION_EDIT, Uri.parse("content://contacts/people/1"));
startActivity(intent);
break;
}
39. Intent Filters
• How does Android know which application
(and component) handles the request?
• Intent Filters are used to register components
as being capable of performing an action on
particular kind of data
– Tell Android that your app can service request
from other apps
• How? Use application’s manifest file and add
inter-filter tag
40. Using Intent Filter
• Intent action
– Name of the action being serviced. Should be
unique, so use Java package naming conventions
• Intent type / data
– type of data given to component (MIME type)
• Intent category
– Additional info about the component that should
handle the action. CATEGORY_BROWSABLE,
CATEGORY_PREFERENCES...
42. Opening the Activity (App A)
intent =
new Intent("fi.organization.demos.PLAYSOUND",
Uri.parse("http://www….fi/music.mp3"));
startActivity(intent);
43. The Activity (App B)
public class PlaySound extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i = getIntent();
Uri uri = i.getData();
if(uri != null) {
MediaPlayer mp = MediaPlayer.create(this, i.getData());
mp.start();
}
}
}
46. 2. Services
• A facility for the application to tell the system
about something it wants to be doing in the
background
– background music
– fetching data over network.
– file i/o
– ..
• Activity may be frozen when user moves to
another Activity. Service can go on in the
background.
47. About Services
• Service is NOT a separate process or thread
• Provides two features
– Tell the system, that we want to do something in the
background. (startService())
• Even if the app closes!
– The ability to expose functionality to other apps
(bindService())
• Service is a simple class, you must implement
separate threads by yourself.
• Modify the Manifest – file!
48. Started and Bounded Service
• Started Service
– Service is started when an app component calls startService()
– Service can run in background forever. Usually started service
performs a single operation and does not return to caller
– When operation is done, the service should stop itself
• Bounded Service
– Service is bounded when app component binds to it by calling
bindService()
– Bound service may interact with the service (not just start and stop).
– Bound Service is run only as long as app is bound to the service
• Service can be both, run indefinatelyand allow
bounding
49. public class MyService extends Service {
/*
If client is binded to service, this method is
called. Your implementation must return an object
that implements IBinder interface. If you don't need
this, just return null.
*/
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onDestroy() {
}
/*
When Activity calls startService(..), this
method is invoked. Service is started and it's
running until stopService or stopSelf() is called
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onCreate() {
}
}
50. public class MainActivity extends Activity implements OnClickListener{
@Override
public void onClick(View v) {
if (v == startService) {
Intent intent = new Intent(this, MyService.class);
startService(intent);
} else if (v == stopService) {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
}
51. public class MyService extends Service
implements Runnable {
private boolean isRunning;
private final static String TAG =
"MyService";
private Thread thread;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onDestroy() {
isRunning = false;
}
@Override
public void public int onStartCommand(Intent
intent, int flags, int startId) {
if(!isRunning)
thread.start();
return START_STICKY;
}
@Override
public void onCreate() {
isRunning = false;
thread = new Thread(this);
}
@Override
public void run() {
isRunning = true;
while(isRunning) {
try {
Log.d(TAG, "Service running...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
54. IntentService
• IntentService has separate thread built in!
• Class inherites IntentService, overrides
onHandleIntent()
• Everything is done on separate thread
• Cannot directly interact with UI
55. Example
public class RSSPullService extends IntentService {
@Override
protected void onHandleIntent(Intent workIntent) {
// Gets data from the incoming Intent
String dataString = workIntent.getDataString();
...
// Do work here, based on the contents of
dataString
...
}
}
56. About Bound Services
• Create bound service, if you want to
– Interact with the service from activities or other
components
– Expose some of app’s functionality to other apps
(IPC)
• To create bound service, implement onBind()
• A bound service typically lives only while it
serves another application component and
does not run in the background indefinitely
57.
58. Creating a Bound Service
• Private Service for your own app
– Extend Binder class
– Example: music application that needs to bind an
activity to its own service that's playing music in
the background.
• Service for other apps (work across
processes)
– Use a Messenger
59. Extending Binder
• If your service is private to your app, you can
use Binder
• Binder? Defines programming interface that
clients can use
• Binder can
– Contain public method that the client can call
– Return the Service object itself, so all the public
methods from the service is available
60. How?
• Service
– Create the Binder object in your Service
– Return the object in onBind() method
• Client
– Receive Binder object from onServiceConnected-‐
method
61. public class MyService extends Service {
private IBinder mBinder;
@Override
public IBinder onBind(Intent intent) {
// Returns IBinder, which "wraps" MyService inside..
return mBinder;
}
@Override
public void onDestroy() {
Log.d("MyService", "onDestroy()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStart()");
return START_STICKY;
}
@Override
public void onCreate() {
Log.d("MyService", "onCreate()");
mBinder = new LocalBinder(this);
}
public void someMethod() {
Toast.makeText(this, "someMethod is called!", 1000).show();
}
}
62. Client
• Client can bind to service by calling
bindService()
• bindService() – method needs
ServiceConnection object, which monitors the
connection of the service
• bindService() returns immediately, but
ServiceConnection’s onServiceConnected is
called to deliver the Binder to the client
63. Example
public class LocalServiceExample extends Activity {
private MyService mBoundService;
private MyServiceConnection mConnection;
public class MyServiceConnection implements
ServiceConnection {
@Override
public void
onServiceConnected(ComponentName className, IBinder
service) {
mBoundService = ((LocalBinder)
service).getService();
}
@Override
public void
onServiceDisconnected(ComponentName arg0) {
mBoundService = null;
}
}
@
Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mConnection = new MyServiceConnection();
doBindService();
}
void doBindService() {
Intent i = new Intent(this, MyService.class);
bindService(i, mConnection,
Context.BIND_AUTO_CREATE);
}
void doUnbindService() {
unbindService(mConnection);
}
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
public void click(View v) {
mBoundService.someMethod();
}
}
65. 3. Broadcast Receivers
• A broadcast receiver is a component that does
nothing but receive and react to broadcast
announcements
• Your app can
– 1) Receive and react to system services (example:
battery low)
– 2) Receive and react to other apps broadcast
announcements
– 3) Initiate broadcasts to other apps
• App is given fixed amount of time to react on the
broadcast! (10 secs!)
67. Registering
• To register Broadcast Receiver, you can
– 1) Dynamically register with registerReceiver
(in code)
– 2) Statically public receiver and <register> tag
in AndroidManifest.xml
• Note: if you are doing this dynamically and
you are working in local, you don't have
modify manifest – file.
68. 1. Registering in Code
public class Main extends Activity {
MyBroadCastReceiver s;
IntentFilter filter;
@Override
public void onResume() {
super.onResume();
filter = new IntentFilter("android.intent.action.TIME_TICK");
s = new MyBroadCastReceiver();
registerReceiver(s, filter);
}
@Override
public void onPause() {
super.onPause();
unregisterReceiver(s);
}
}
71. Sending Broadcast
• Broadcast is sent using Intent and
sendBroadcast or sendOrderedBroadcast
methods
• Example:
Intent intent = new Intent("fi.tamk.DETECTION");
sendBroadcast(intent);
72. Normal vs. Ordered Broadcast
• Normal Broadcasts
– Sent with sendBroadcast. All broadcasts are run
in undefined order, often at the same time.
• Ordered Broadcasts
– Sent with sendOrderedBroadcast. Each receiver
executes in turn. Possible to propagate a result to
next receiver. Order can be controlled using
android:prioritytag.
73. Receiver Lifecycle
• Broadcast Receiver object is valid only for the
duration of the onReceive(Context, Intent)
method
– Before API Level 11:
• You cannot do anything asynchronous in here!
– After API level 11 (3.0 -‐>)
• You can use method goAsync() to create asynchronous
processing. See:
• http://justanapplication.wordpress.com/tag/goasync/
– You can always start a service
74. Registering Broadcast Receiver in Java
public class Main extends Activity implements OnClickListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button click = new Button(this);
click.setText("Click me!");
setContentView(click);
click.setOnClickListener(this);
// Registering MyBroadCastReceiver to receive Broadcasts
IntentFilter filter = new IntentFilter("fi.tamk.DETECTION");
MyBroadCastReceiver s = new MyBroadCastReceiver();
registerReceiver(s, filter);
}
@Override
public void onClick(View v) {
// Sending Broadcast
Intent intent = new Intent("fi.tamk.DETECTION");
sendBroadcast(intent);
}
}
77. 4. Content Providers
• A content provider makes a specific set of the
application's data available to other applications
• => Share data to other apps
• Any app with appropriate permission, can read
and write the data.
• Many native databases are available via the
content providers, for example Contact Manager
• Files, SQL database
• Common interface for querying the data
78. About Content Provides
• The result of the query: simple table in Query
object
• Content provider exposes a public URI that
uniquely identifies its data set
– URIs begin with content://
– Android provides constants for native content
providers, for example:
• ContactsContract.Contacts.CONTENT_URI
79. Querying Native Content Provider
• You need
– URI
• ContactsContract.Contacts.CONTENT_URI
– Names of data fields (result comes in table)
• ContactsContract.Contacts.DISPLAY_NAME
– Data types of those fields
• String
• Remember to modify the manifest file for
permissions!
80. Query
Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI, // What Content Provider
null, // Which columns to return (all columns)
null, // Which rows to return (all rows)
null, // Selection arguments (none)
null); // In what order
if (cur.moveToFirst()) {
// Get column DISPLAY_NAME
int nameColumn = cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
do {
// Get the field values
String name = cur.getString(nameColumn);
System.out.println(name);
} while (cur.moveToNext());
}
82. Implementing your own Content Provider
1. Set up a system for storing data
For example, SQLite or flat file
2. Extend ContentProvider class
3. Declare the Content Provider in manifest
83. 2. Extend Content Provider
public class MyContentProvider extends ContentProvider {
public static final Uri CONTENT_URI = Uri.parse("content://fi.tamk.phonenumber");
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {...}
@Override
public String getType(Uri uri) {...}
@Override
public Uri insert(Uri uri, ContentValues values) {...}
@Override
public boolean onCreate() {...}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {...}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {...}
}