Slides Lecture Android 12 - App Programming

knapsackyarnMobile - Wireless

Dec 14, 2013 (3 years and 7 months ago)

83 views

1
2

Intents and Intent Filters


Aim:

1.
A
llow apps to be composed of smaller units that do not have to be loaded
in memory all the time.

2.
Provide a generic mechanism so Activities can be started implicitly (i.e.
without specifying exactly which Activity should be started) or explicitly
(effectively specifying which Activity to start)


Means:

1.
Activities have Intent Filters that specify the actions that an Activity can
perform

2.
Activities can create Intents that specify which actions need to be
performed on behalf of the Activity

3.
Android matches Intents and Intent Filters


1
2

Intents and Intent Filters


Intents and intent filters provide a generic way to start activities. Why would we want this?


Divide your program into smallish activities to reduce the load (scarce memory)


D
o some background processing



Book “Pro Android 4”: What is an intent? The short answer may be that an intent is an
action with its associated data payload



To start an activity (either from same app or from different app) from another activity,
create an instance
i

of the
Intent

cl ass and execute (
this

== current activity)

t h i s.s t a r t A c t i v i t y
( i );



Activities have intent filters, usually specified in the manifest. Android creates instances
of the
IntentFilter

class from this.



When
this.startActivity
(i)
i s executed, Androi d searches for an acti vi ty that i s
i nstal l ed on your devi ce wi th an i ntent fi l ter that matches the i ntent
i
. Thi s acti vi ty i s then
started. If not found, an excepti on i s thrown.




1
2

Android will search the Intent Filters of all installed Apps!

1
2

Example of an intent filter
(show in Eclipse)


HelloActivity

Manifest:



This a
ction that says that this activity can be started as a main activity that
is started without input


This category tells Android to add the activity to the launcher screen so it
can be launched from there

1
2

Example of starting an activity from another activity


Simplest way to do this:
explicit

intent

PersonListActivity

(treated later) has
intent filter

with action
name

as shown below
(added especially to enable starting it this way)

When adding the action: drop
-
down list with predefined actions or, as in this case,
create your own specific action name



Notice that there are
two

Intent Filters.

Each intent filter has its own specific purpose

In this case:

one that has the same function as the one of the
HelloActivity

one to start it with an explicit intent


1
2

StartPersonListActivity

instantiates an
Intent

with the action
name

and then calls
startActivity


Intent i = new Intent("
n l.t u e.w i n.i n t e n t.a c t i o n.S h o w P e r s o n L i s t
");

this.startActivity
(i);


Demo:
StartPersonList

(Notice: if
PersonList

is not installed yet,
StartPersonList

crashes if
you don’ t catch the exception!)


This tells Android to start the activity with this action name in the intent filter


Another way to start an activity with an explicit intent:

specify the class name (class must be accessible, in same application!)


Example:
i.setClassName
(
packageName,className
);




1
2


With
methods
i.putExtra
(String name,...)
, it is also possible to pass any data
to the
Activity

started. Here, … can be almost any type, e.g.,
String
,
int
[]
,
float
, …


The started
Activity

can access the data
by first getting hold of the
Intent

it was
started with:
this.getIntent
()


Then it can get the extra data with
i.getXXXExtra
(String name)

where
XXX

stands for
String
,
IntArray
,
Float
, etc. (must of course match the type passed to
it!)


1
2

More powerful ways to start an activity need categories: implicit intents



An intent filter must specify a category

Book: if filter has no categories, it only matches an intent that doesn’t mention any category

Practice: without default category in intent filter of PersonList, StartPersonListActivity
crashes when
this.startActivity(i)

i s executed.



If an activity is to be invoked by implicit intents one needs to specify
CATEGORY_DEFAULT

i n the i ntent fi l ter



A few other categori es:

CATEGORY_HOME
:

show a home screen

CATEGORY_TEST
:

test activity

CATEGORY_ALTERNATIVE
:
alternative for an activity the user is currently viewing, e.g.,
print view instead of normal view (useful for context menus)

1
2

An intent matches an intent filter if (at runtime):

1.
The action in the intent matches one of the actions in the intent filter

2.
All categories in the intent are specified in the intent filter

3.
If data
*

is supplied in the intent it matches the data in the intent filter


Ad 1. and 2.:
Intent.ACTION_XXXX

as specified in the intent is matched to the action with
name

android.intent.action.XXXX

in the intent filter (same with categories)



If an intent matches different activities, Android lets the user choose, e.g., if you want to start
a browser and more than one browser is installed



Ad. 3.:Example of data in intent filters:




Matches if the data in the intent is set to a URL accessed via the http protocol, but not one
accessed with the https protocol


*
: Do not confuse this data with the data passed with
putExtra
(...)
!!!

1
2

Example of starting activity implicitly, with data:


Intent i =
new

Intent(
I n t e n t.A C T I O N _ V I E W
,
U r i.p a r s e
("http://www.tue.nl"));

startActivity
( i );


Uri.parse

takes the string and returns an instance of the
Uri

class


Android will look among all installed apps for intent filters that specify “http” in the
data

element

(see previous slide)


Notice: both an action and data (http scheme) are used in creation of the intent; because the filter
specifies that it handles http, Android can match the intent with the filter


Demo:
StartBrowser



notice how, when back is pressed, the top activity is deleted and the
previous activity is now on top (activity stack)


1
2

Actions


Actions describe what an activity in general does, e.g.,

ACTION_VIEW

activity shows something

ACTION_EDIT

activity allows to edit something

ACTION_PICK

activity displ ays a l ist of items and returns the URI of the item the user sel ected

ACTION_GET_CONTENT
activity returns one item of a particular mime type indicated by the intent
(mime types are discussed in a few slides)



Examples of actions and data (started, like the previous example with

n e w I n t e n t ( < a c t i o n >,
Uri.parse
(<data>)
)


action


data


ACTION_VIEW


content://contacts/people/1






Displ ay information about the person whose identifier is "1".

ACTION_EDIT


content://contacts/people/1





Edit information about the person whose identifier is "1".

ACTION_VIEW


content://contacts/people/





Displ ay a l ist of peopl e, which the user can browse through.

1
2

Data




Data in an intent filter can either be a scheme, e.g.,

http, mailto,
tel



Or a Multipurpose Internet Mail Extensions (MIME) type, an internet standard for text in
character sets other than ASCII (rtf), but also for images (jpeg), video, audio.



Mime types are specified by a
type

and a
subtype

(format:
type/subtype
, e.g.,
text/html

)


Can be a standard mime type (defined in the standard) or a custom mime type for use with
Android only


Mime types must always be given in
lower case

(but there are methods to translate to lower
case)





1
2

Data


Custom mime
type

always has format
that starts with
vnd.android.cursor.
dir

(multiple
items)

or

vnd.android.cursor.
item

(single item)




Examples of mime types (examples how to use follow
):



custom vendor
-
specific subtype:


vnd.android.cursor.dir
/
vnd.google.note

and
vnd.android.cursor.item
/
v n d.g o o g l e.n o t e



si mpl e subtype


vnd.android.cursor.dir
/phone_v2

and

vnd.android.cursor.item
/p h o n e _ v 2


Example of intent filter: Notepad



1
2

The data test compares both the URI and the data type in the Intent object to
a URI and data type specified in the filter. The rules are as follows (from
Android documentation):


a.
An Intent object that contains neither a URI nor a data type passes the test only if the
filter likewise does not specify any URIs or data types.

b.
An Intent object that contains a URI but no data type (and a type cannot be inferred
from the URI) passes the test only if its URI matches a URI in the filter and the filter
likewise does not specify a type. This will be the case only for URIs like mailto: and tel:
that do not refer to actual data.

c.
An Intent object that contains a data type but not a URI passes the test only if the filter
lists the same data type and similarly does not specify a URI.

d.
An Intent object that contains both a URI and a data type (or a data type can be inferred
from the URI) passes the data type part of the test only if its type matches a type listed
in the filter. It passes the URI part of the test either if its URI matches a URI in the
filter or if it has a content: or file: URI and the filter does not specify a URI. In other
words, a component is presumed to support content: and file: data if its filter lists only a
data type.


1
2

Start activity using the required mime type


Intent i = new Intent(
I n t e n t.A C T I O N _ G E T _ C O N T E N T
);

i.setType
("
v n d.a n d r o i d.c u r s o r.
item
/
vnd.google.note
"); // r e q u e s t s s i n g l e i t e m

this.startActivity

(i);



The intent matches the intent filter below:





The mime type
"
vnd.android.cursor.
item
/
vnd.google.note
"

matches a single note

The mime type
"
vnd.android.cursor.
dir
/
vnd.google.note
"

matches a directory of notes

I
n the Notepad application, there is also an intent filter that matches the latter

1
2

Start activity with a URI that specifies where the content can be found



Intent i = new Intent(
I n t e n t.A C T I O N _ E D I T
);

i.setData
(
U r i.p a r s e
("c o n t e n t://
com.google.provider.Notepad
/n o t e s") );

this.startActivity
(i);



Matches the intent filter (demo:
StartNotepad



again notice
the activity stack!):




Seems to violate rule b, but the data type can be deduced from the URI (rule d)



With the action above, the list is shown and the notes can be edited.

When
ACTION_PICK

is specified,
the
list shows up, but no editing is possible (?).

1
2

Note:


The
activity with this filter uses a
ContentResolver

to get hold of its
ContentProvider
, in this case a part of the same app which stores the notes.
Subsequently it retrieves that data from the provider. The match with the provider is
made based on the URI and the Authority specified in the Provider node in the
manifest








The
URI is passed to the provider, which uses a
UriMatcher

(must be provided by
the
ContentProvider

itself) to
translate the URI to the actual location of the data in
the file system or in a database .


1
2

Passing data between activities


some more detail




Intent
i = n e w
Intent(
I n t e n t.A C T I O N _ E D I T
); // m a y b e u s e a n I n t e n t f i l t e r o f y o u r o w n






// choice
-

f o r t h i s o n e A n d r o i d w i l l






// return a list of possible editors


// pass data <data> of any type identify it with key <name>

i.putExtra
(<
r e q u e s t k e y n a m e
>,< d a t a > );


// start the activity with
s t a r t A C t i v i t y F o r R e s u l t

this.startActivityForResult
( i,<
requestCode
> );
//
r e q u e s t C o d e

is
a n a r b i t r a r y
n u m b e r


1
2

Passing data between
activities (2)


At the side of the activity that was started:


// inspect the Intent we were started with

Intent i =
t h i s.g e t I n t e n t
();

if
(
Intent.ACTION_EDIT.equals
(
i.getAction
( ) ) ) {




//
check that we
w e r e r e c e i v e d <
requestkeyname
>


String
msg

=
i.g e t S t r i n g E x t r a
(<
requestkeyname
>);


// do something relevant with
msg


// and return some data




i.putExtra
(<
replykey
>, < d a t a > );


//
set result code to OK (constant of this class)


//and
pass the (modified) intent



this.setResult
( R E S U L T _ O K
, i );


// t h e f i n i s h c a l l c a u s e s t h e c a l l b a c k t o
t h e c a l l i n g a c t i v i t y



finish
();


}


1
2

Passing data between activities (3)



The method
startActivityForResult

and the call to finish() result in a callback to the
function
onActivityResult
,
in which the data returned can be accessed (example will be
given later)




public void
o n A c t i v i t y R e s u l t
(
int

requestCode
,
int

r e s u l t C o d e
, Intent data){


super.onActivityResult
(
r e q u e s t C o d e
,
r e s u l t C o d e
, d a t a );



// check if the request code matches and the result is OK


if(
r e q u e s t C o d e

== <
r e q u e s t C o d e
> &&
r e s u l t C o d e

= = R E S U L T _ O K )
{



// get the value that the called Activity returned


String s =
d a t a.g e t S t r i n g E x t r a
(<
replykey
>);


}


}

For data types other than String, there are methods like
getIntExtra
,
getDoubleExtra
, etc.

Demo: Exercise 11.1



1
2

Switching screens



Possibility to show another part of the UI without starting another activity
(remaining within the same activity). “Why” is on next slide.



public class
S c r e e n S w i t c h e r

extends Activity {


...// layout set to main.xml in
o n C r e a t e


public void
o n B a c k C l i c k e d
(View v){



setContentView
(
R.layout.main
);


}


public void
o n O t h e r C l i c k e d
(View v){



setContentView
(
R.layout.otherscreen
);


}

}


Demo:
ScreenSwitcher



1
2

Switch screen or start new Activity?


So, in the PersonList app, we could have made a second screen with the AddPerson
functionality.

Obviously, starting another activity in PersonList is not very useful.



When one has e.g. some background calculations that need not execute continuously
but that do require considerable amounts of resources or if one has a complex
application it would be a very good idea.



Which solution is more appropriate depends on the situation.



Cooperating small activities/apps are of course less likely to exhaust the resources of
the physical device than one big one that implements all functionality in one activity.



Cooperating small activities is also what the designers of Android intended


Question: were they right to assume resource constraints? Compare to Windows NT:
PCs were not powerful enough when NT was developed… But, of course, there was
no equivalent of earlier Windows versions to secure a market segment…