Through the use of a devious little prank application,
you’ve explored how
intents, intent receivers, services, and activities work
together in an
advanced, mostly background, application. i’ll now go over,
step by step,
what you did and how you accomplished it.
getting it done
you did the following:
1. you used an
intent receiver with the right
permissions and a system-level
sms intent to arrange for your pranksmsreciever object to be
instantiated each time an sms arrives on the phone. if your intent receiver
detected a very specific sms payloa d, it would respond by
sending an
intent that would start your activity.
2. this activity,
named prankactivity , would listen for the specific intent
action sent by the pranksmsreceiver. when it received that
precise
intent action, your activity would display a “gotcha” message to the
victim. at the same time, the activity would send out an intent meant to
start up a service. if, at any point the victim/user pressed
a key on the
phone, the application would exit, and the music service would be
terminated.
3. the service
class, called prankservice, listening
for the
prankactivity ’s intent, would start and begin to play an
obnoxious,
predefined audio file. it
would continue to play until it was told to stop by
the prankactivity ’s
call to the method stopservice.
34 android
essentials
note this sample
application does not deal with the handset’s native
sms application. because all intent receivers are notified
of an incoming
intent, your application will be competing for user
attention with android’s
sms inbox application. in production, this may require a
substantial timer
and perhaps a trigger text payload, which is a little more
subtle than
“0xbadcat0_fire_the_missiles!”
further deviousness
here are a few ways you can explore and extend the prank
application on your own:
▪ get more evil by
taking the activity out of the loop. launch the
prankservice directly from the intent receiver. do not give
the
victim a way of shutting off the music.
▪ add a different
text payload to stop the music. this
exercise
would be an excellent one to combine with the previous one.
▪ customize your
“get even” message. create a prefix that triggers
the service and a payload, which is displayed by the main
app
activity. pass this payload from the intent receiver to the
activity
using a payload within the intent. taunting, sometimes, needs fine-tuning.
these are just a few ways you can better learn the pieces of
android
while at the same time making life miserable for those
around you.
moving data in android
finally, to round your knowledge about android’s application building
blocks, you need to focus on the content resolver. android
does not give
the sdk particular access to the phones filesystem, as brew
does. nor does
it offer a
recordstore , as does java me. your primary method for
passing data between your activities, intent receivers, and
services is going
to be through the contentresolver superclass. though y ou can store data
through files, preferences, and other da tabases, content re
solvers can take
android
essentials 35
many forms, and android ships with a few important content resolvers
built in. here’s a list, at time of publication, of the
major android content
resolvers you’ll probably want to interact with on a regular basis:
browser
bookmarks
search history
phone calls
call log
recent calls
contacts
system settings
hardware settings (bluetooth, networking settings)
software settings
android’s documentation gives an excellent walk-through of
using the
contacts content resolver here: http://code.google.com/android/
devel/data/contentproviders.html#usingacp.
quickly, i’ll walk you through adding a bookmark to the
phone browser’s
bookmark list. first, you’ll want to sear ch the current
list of bookmarks to
see whether your link is in place. second, you’ll add your
bookmark if it
isn’t there.
note it is possible
to create your own content providers as a way to
wrap android’s sqlite implementation for universal access.
you’ll get into
how to do this in later chapters. for now you’re just going to handle the
“client” side of this content resolver interaction.
36 android
essentials
android uses a custom implementation of sqlite to store
information
locally. if you’re not familiar with the basics of sql, now might be a good
time to brush up. i’m going to assume, for the sake of expediency, that you
understand basic sql searching commands. if you need to
brush up,
apress has an excellent resource at http://apress.com/book/
catalog?category=145 .
shameless self-promotion
let’s say in the “about” section of your application that
you want to have a
button that adds your commercial so ftware page to the
user’s web
bookmarks. you want to make sure it isn’t added twice if
your user has
clicked the button again by accident. for the sake of this
simple
demonstration, you’ll trigger this event in your sample
application when
the user presses a key.
note on an amusing
note, if you need proof, as a developer, that
android is still not quite fully baked, you need look no
further than the
documentation for
android.content.contentresolver under the
method getdatafilepath,
which states “do not use this function!!
someone added this, and they shouldn't have. you do not have
direct
access to files inside of a content provider. don't touch
this. go away.” it’s
good to know that even the technical writers for android’s
documentation
have a sense of humor.
fetching the user’s bookmarks
it should be obvious, at least at this point, that a
developer could do some
fairly nefarious things with access to a user’s bookmarks. it’s not clear, at
this point, what android will do to keep this sort of thing
from happening. i
suppose it’s up to the carriers to lock down or monitor this
behavior. in any
case, you’ll use a call to the method managedquery, which will return a list
of the user’s bookmarks:
android
essentials 37
cursor bookmarks =
android.provider.browser.getallbookmarks
(getcontentresolver());
int urlcolumn = bookmarks.getcolumnindex(
android.provider.browser.bookmarkcolumns. url );
cursor results;
string[] proj =
new string[]
{
android.provider.basecolumns._id,
android.provider.browser.bookmarkcolumns.url,
android.provider.browser.bookmarkcolumns.title
};
results =
managedquery(android.provider.browser.bookmarks_uri,
proj, null,
android.provider.browser.bookmarkcolumns.url
+ "
asc");
i’ll now break down what’s happening. y ou’ll first get the
column index of
the bookmark url. again, because androi d provides access to
most of its
internal data in a sql format, you sh ould get used to
referring to your
saved information in a database-centric way. next you’ll set up the cursor,
an object similar to a java me recordstore enumerator and set up your
projection string array. because you’re interested only in
the columns
containing the url, you can keep it very simple. the method call
managedquery is the call that will return your data. you’ll pass in the uri
string for the bookmarks store, hand it your simple projection array, leave
the where
section empty, and tell it to sort
the urls in descending order.
0 comments:
Post a Comment