Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Developing Android Apps:
The Basics
Ioannis Papavasileiou
1
Who Am I?
•
•
•
•
Hi.
Ph.D. Graduate student
Have worked with android in the past
Currently working on data analytics
Slides based on Mike’s Desjardins
presentation:
•
http://www.slideshare.net/mdesjardins/a
ndroid-development-the-basics
Developing for Android:
The Basics
What’s In This
Presentation?
• What is Android?
• Activities and Intents
• Views
• Permissions
• Other Facilities
• Marketplace
Developing for Android:
The Basics
What is it
• Software platform
• Operating system
• Key apps
• Developers:
• Google
• Open Handset
Alliance
• Open Source
(http://source.and
roid.com/)
Developing for Android:
The Basics
4
Software stack design
• Android ≠ Linux!!!
• The kernel is based on Linux kernel version
3.x (source Wikipedia)
• Written in C/C++
• Apps written in Java
• Use of Dalvik VM
• Runs .dex files (dalvic executables)
Developing for Android:
The Basics
5
Android’s Layers
User applications: Contacts, phone, browser, etc.
Application managers: windows, content, activities,
telephony, location, notifications, etc.
Android Runtime: Java via Dalvik VM
Libraries: graphics, media, database, communications,
browser engine, etc.
Linux kernel, including device drivers
Hardware device with specific capabilities such as GPS,
camera, Bluetooth, etc.
Abelson, W. Frank & Sen, Robi (2011) Unlocking Android, Second Edition (Fig. 1.4). Greenwich, CT: Manning
Publications.
Developing for Android:
The Basics
What is Android: Dalvik VM
• Register Based instead of Stack Based
• Interprets .dex files
.java
source
code
Java
Compiler
.class
.class
.class
file
file
files
dx
Compiler
• Packaged w/ resources in .apk files
Developing for Android:
The Basics
.dex
file
Versions
Version
Codename
API
Distribution
2.3.3 2.3.7
4.0.3 4.0.4
Gingerbread
10
1.0%
Ice Cream
Sandwich
15
1.0%
4.1.x
4.2.x
4.3
4.4
Jelly Bean
16
17
18
19
4.0%
5.7%
1.6%
21.9%
5.0
5.1
Lollipop
21
22
9.8%
23.1%
6.0
Marshmallo
w
Nougat
23
30.7%
24
25
0.9%
0.3%
7.0
7.1
KitKat
Developing for Android:
The Basics
Data collected during a 7-day period ending on February 6, 2017.
https://developer.android.com/about/dashboards/index.html
What is “Rooting” ?
• Processes in the Android system run under an
unprivileged user account
• Default user can’t access all of the filesystem,
or some of the more interesting APIs (e.g.,
enabling mobile hotspot, setting CPU speed)
• “Rooting” is finding back door shell access,
and copying a program conceptually similar to
su or sudo onto your phone.
• Custom ROMs are something completely
different.
Developing for Android:
The Basics
Development Environment
• Android studio is the
“default”
• Android SDK comes w/
command line tools and
emulator (adb)
Developing for Android:
The Basics
Application
components
• 1 app = N components
• APP components:
• Activities
• A single screen with a UI. E.g. compose, read, list e-mails
• Services
• Run in the background to perform long-running operations. E.g. play music,
•
•
•
•
fetch data over the network
Content Providers
Manage a shared set of app data. Other apps can query or modify the data.
E.g. contacts
Broadcast Receivers
Respond to a system-wide broadcast announcement. E.g. screen turned off,
low-battery. May initiate services or notifications
Intents
Processes and threads
•
•
Developing for Android:
The Basics
11
Activities
•
•
•
•
Typical applications have (along with
some other stuff) a collection of
“Activities”
An Activity roughly corresponds to a
screen
Class inheriting from android.app.Activity
Started by “Intents” (more on those later)
Developing for Android:
The Basics
Developing for Android:
The Basics
Activity Lifecycle
Entire Lifetime - Between
onCreate and onDestroy
Visible Lifetime - Between
onStart and onStop
Foreground Lifetime Between onResume and
onPause
Image:
http://developer.android.com/images/activity_lifecycle.png
Developing for Android:
The Basics
Demo Time!
•
•
•
•
•
Views
Android allows you to be quite ModelView-Controllery
Views contain UI elements displayed on
the screen by an Activity (controller)
Can be defined in XML or programatically
Views are nested, topmost is a
LayoutView
setContentView(viewId) or
setContentView(view)
Developing for Android:
The Basics
Our Hello World Demo View
<?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"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Developing for Android:
The Basics
Our Hello World Demo View
<?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"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Developing for Android:
The Basics
Which direction we’re
filling
Our Hello World Demo View
<?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"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Developing for Android:
The Basics
fill_parent
match_parent
wrap_content
Our Hello World Demo View
<?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"
>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Developing for Android:
The Basics
what the???
Developing for Android:
The Basics
Resources
• Resources go into the res
directory
•
•
•
Different Types: strings,
layouts, drawables, arbitrary
XML, styles, raw, etc.
Referenced in XML using
identifiers prefixed with an at
sign (@) followed by type
Handles / IDs end up in the
mysterious “R” class
R
R.java
/* AUTO‐GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
MyActivity.java
Layout.xml
package com.cereslogic.demo01;
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 app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}
Developing for Android:
The Basics
•
•
Autogenerated by
Android’s compile
tools
Scans res folder,
creates R in your gen
folder w/ the same
package name as your
app.
Referring to Resources in
Java
package com.cereslogic.demo01;
import android.app.Activity;
import android.os.Bundle;
public class Hello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Developing for Android:
The Basics
Here’s an example!
Developing for Android:
The Basics
Let’s add a Button!
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/deliver_bacon"
android:onClick="deliverBacon" />
</LinearLayout>
Developing for Android:
The Basics
First we’ll add the
Firs
button to our view
in main.xml.
Let’s add a Button!
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Hello!</string>
<string name="app_name">AndroidPresentation</string>
<string name="deliver_bacon">Please Deliver Bacon!</string>
</resources>
Developing for Android:
The Basics
add the string to
values.xml
Let’s try it out...
Developing for Android:
The Basics
Demo Time
Developing for Android:
The Basics
Uh Oh!
That’ll get you a one star review in the App Market.
Developing for Android:
The Basics
Let’s check logcat to see
what went wrong...
DOH!
E/AndroidRuntime(
E/AndroidRuntime(
E/AndroidRuntime(
E/AndroidRuntime(
E/AndroidRuntime(
.
.
.
523): Uncaught handler: thread main exiting due to uncaught exception
523): java.lang.IllegalStateException: Could not find a method deliverBacon(View) in the activity
523):
at android.view.View$1.onClick(View.java:2016)
523):
at android.view.View.performClick(View.java:2344)
523):
at android.view.View.onTouchEvent(View.java:4133)
Developing for Android:
The Basics
OOPS.
We forgot to write the
deliverBacon
method in our
Activity. It got called
when onClick was
fired.
Add a method for that...
package com.cereslogic.androidpreso;
import
import
import
import
android.app.Activity;
android.os.Bundle;
android.util.Log;
android.view.View;
public class Hello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void deliverBacon(View view) {
Log.i("Demo App", "TODO: Figure Out How To Deliver Bacon!");
}
}
the view passed in is the button that was
tapped
Developing for Android:
The Basics
Developing for Android:
The Basics
Demo Time
Yeah... that was pretty lame.
Bacon makes everything better,
so...
...let’s add a picture of bacon!
Photo Credit: Shawn Zamechek (shawnzam), Licensed under Creative Commons (CC BY 2.0),
http://www.flickr.com/photos/shawnzam/31302636/
Developing for Android:
The Basics
Now Things Start To Get
Ugly
• We are supporting devices with multiple
screen densities.
• Good News: Android provides a way to
support multiple screen densities
• Bad News: We will probably want to
include four copies of our bacon picture
in our app
Developing for Android:
The Basics
Screen Densities
• Android currently generalizes screens
into four categories of screen density
• LDPI (low) - QVGA, 120dpi, ~240x320
• MDPI (medium) - HVGA, 160dpi,
~320x480
• HDPI (high) - WVGA, 240dpi, ~480x800
• XHDPI (xtra high) - ? 320dpi, Added in
Android 2.3 (Gingerbread)
Developing for Android:
The Basics
Bacon should Fill the Screen!
•
We want Bacon to fill the width of the
screen in HIGH DEFINITION, so we will
make four sizes
LDPI
Developing for Android:
The Basics
MDPI
320x240
HDPI
480x360
XHDPI
640x480
Developing for Android:
The Basics
Add Bacon...
<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/deliver_bacon"
android:onClick="deliverBacon" />
<ImageView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:src="@drawable/bacon"/>
</LinearLayout>
Now let’s try that out...
Developing for Android:
The Basics
Bacon Time
Developing for Android:
The Basics
Meh. That’s still pretty lame
We could make the bacon only appear
when the button is clicked...
1
Make the bacon’s default state hidden:
Developing for Android:
The Basics
visible, invisible, or gone
<ImageView
android:visibility="invisible"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:src="@drawable/bacon"/>
Meh. That’s still pretty lame
We could make the bacon only appear
when the button is clicked...
2
Developing for Android:
The Basics
Put an ID on our bacon:
The @+id in our XML is special magic that
causes the Android build tools to generate an
handle w/ an ID for the view in the R object
<ImageView
android:id="@+id/bacon_image"
android:visibility="invisible"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:src="@drawable/bacon"/>
Meh. That’s still pretty lame
We could make the bacon only appear
when the button is clicked...
3 Wire up the Button listener to do something:
public void deliverBacon(View view) {
ImageView i = (ImageView)findViewById(R.id.bacon_image);
if (i.getVisibility() == View.INVISIBLE) {
i.setVisibility(View.VISIBLE);
} else {
i.setVisibility(View.INVISIBLE);
}
}
Developing for Android:
The Basics
Let’s try that out!
Developing for Android:
The Basics
Blinky Bacon Time
Developing for Android:
The Basics
ListViews
• Probably the most common UI Element
is a ListView
• Allows you to scroll through a selection
of items and choose one
• Next we’ll add a list of bacon-related
treats to our app!
Developing for Android:
The Basics
Create a List of Treats
1
Put our list entries into strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Hello!</string>
<string name="app_name">AndroidPresentation</string>
<string name="deliver_bacon">Please Deliver Bacon!</string>
<string name="show_bacon_treats">Show me treats!</string>
<string name="bacon_treat_list">Bacon Treat List</string>
<string name="bacon_plain">Bacon (Plain)</string>
<string name="bacon_lettuce_tomato_sandwich">Bacon, Lettuce, Tomato sandwich</string>
<string name="bacon_and_eggs">Bacon and Eggs</string>
<string name="bacon_cheeseburger">Bacon Cheeseburger</string>
<string name="bacon_bits">Bacon Bits</string>
<string name="bacon_ice_cream">Bacon Ice Cream</string>
<string name="bacon_chewing_gum">Bacon Chewing Gum</string>
<string name="bacon_lollipop">Bacon Lollipop</string>
</resources>
Developing for Android:
The Basics
Create a List of Treats, cont.
2 Create a TextView to hold our list entries
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="24.0dip"
android:padding="4.0dip"
android:id="@+id/empty_text_view">
</TextView>
Wait... a TextView? Don’t you mean ListView or
something?
Nope - this is what each list item will contain.
Developing for Android:
The Basics
Create a List of Treats, cont.
3
Create a new Activity class that inherits
from ListActivity
public class BaconTreats extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.treat_list); unneeded ListActivity provides a default
ArrayAdapter<String> aa = new ArrayAdapter<String>(this,R.layout.empty);
aa.add(getResources().getString(R.string.bacon_plain));
aa.add(getResources().getString(R.string.bacon_and_eggs));
aa.add(getResources().getString(R.string.bacon_bits));
aa.add(getResources().getString(R.string.bacon_cheeseburger));
aa.add(getResources().getString(R.string.bacon_chewing_gum));
aa.add(getResources().getString(R.string.bacon_ice_cream));
aa.add(getResources().getString(R.string.bacon_lettuce_tomato_sandwich));
aa.add(getResources().getString(R.string.bacon_lollipop));
setListAdapter(aa);
}
}
Developing for Android:
The Basics
Converts objects to things appearing in ListView
Create a List of Treats, cont.
4
Add the new Activity to the Manifest
(hey waitaminute - what’s a Manifest?)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cereslogic.androidpreso"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Hello"
android:label="@string/app_name">
<intent‐filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent‐filter>
</activity>
<activity android:name=".BaconTreats"
android:label="@string/bacon_treat_list">
</activity>
</application>
</manifest>
Developing for Android:
The Basics
Create a List of Treats, cont.
4
•
•
•
So... what is a Manifest?
AndroidManifest.xml in the root directory of the
project.
Describes Activities in your project and any
intents that should activate them (hey
waitaminute - what’s an Intent? We’ll get to
that in a minute)
Describes application permissions, version,
name, req’d API version, other stuff
Developing for Android:
The Basics
ListActivity is ready
• We’ve created our ListActivity, now how
do we get to it?
• We’ll add an ugly little button in our
Main screen that launches the list:
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/show_bacon_treats"
android:onClick="showBaconTreats" />
Developing for Android:
The Basics
Now we need to implement the
showBaconTreats method...
showBaconTreats
public class Hello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
Hey - there’s one of
those Intent things
again...
public void showBaconTreats(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setComponent(
new
ComponentName("com.cereslogic.androidpreso","com.cereslogic.androidpreso.BaconTreats")
);
startActivity(intent);
}
public void deliverBacon(View view) {
ImageView i = (ImageView)findViewById(R.id.bacon_image);
if (i.getVisibility() == View.INVISIBLE) {
i.setVisibility(View.VISIBLE);
} else {
i.setVisibility(View.INVISIBLE);
}
}
}
Developing for Android:
The Basics
Developing for Android:
The Basics
Et Voila!
Developing for Android:
The Basics
Intents
•
•
•
•
In some ways, Android resembles a Serviceoriented Architecture (SOA)
An Intent represents the user’s desire to
accomplish something
An app can create an Intent without knowing
or caring what Activity will receive it
Applications create Intent Filters in their
manifests, indicating Activities (or other things
like BroadcastReceivers) that would like to be
notified of Intents
Developing for Android:
The Basics
Intent Resolution
•
•
•
•
Two types of Intents:
Explicit - identifies a Component Name (a
specific Activity class) to be started. This is
how we launched our ListActivity earlier
Implicit - does not name a target Activity,
instead identifies an action, a category, and
data and/or data type
Typical “Actions”: ACTION_VIEW,
ACTION_DIAL, ACTION_EDIT, etc.
Developing for Android:
The Basics
Examples of Implicit Intents
•
•
•
•
•
Data is given in URL format: scheme://data
ACTION_VIEW contacts://people/1 shows the
contact who’s identifier is 1.
ACTION_DIAL tel://2075551212 shows the dialer
with 207-555-1212 filled in.
Normally the data type is inferred by the scheme,
but you can force it to a specific MIME type in the
Intent constructor
“Categories” are sometimes used to further refine
which Activities may be launched
Developing for Android:
The Basics
What if more than one intent
will work?
• If more than one Activity is registered to
receive an intent, Android will ask the
user which Activity they want to launch
• This is how people build things like
alternate dialers or text messaging apps
Developing for Android:
The Basics
Declaring supported Intents
•
If an Activity wants to make itself
available to receive specific Intents, it
declares them in its application’s Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cereslogic.androidpreso"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Hello"
android:label="@string/app_name">
<intent‐filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent‐filter>
</activity>
<activity android:name=".BaconShare"
android:label="@string/bacon_share">
<intent‐filter>
<action android:name="android.intent.action.ACTION_SEND" />
<data android:mimeType="image/png" />
<category android:name="android.intent.category.DEFAULT" />
</intent‐filter>
</activity>
</application>
</manifest>
Allows our
app to be a
target for
photo
sharing
Developing for Android:
The Basics
Declaring supported Intents
• First Activity launched by your App gets
the MAIN/LAUNCHER intent:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cereslogic.androidpreso"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Hello"
android:label="@string/app_name">
<intent‐filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent‐filter>
</activity>
<activity android:name=".BaconShare"
android:label="@string/bacon_share">
<intent‐filter>
<action android:name="android.intent.action.ACTION_SEND" />
<data android:mimeType="image/png" />
<category android:name="android.intent.category.DEFAULT" />
</intent‐filter>
</activity>
</application>
</manifest>
Developing for Android:
The Basics
Permissions
• To use some of the facilities in the
device, you need to declare that you will
use them in the Manifest.
• The user is informed of these
permissions when he or she downloads
your application.
• Examples:
Location (Fine and Coarse),
WiFi state, Network state, Call,
Camera, Internet, Send/Receive SMS,
Read Contacts
Developing for Android:
The Basics
Developing for Android:
The Basics
Common Idioms
Common Idioms
•
•
Android makes extensive use of callbacks
Example of selecting an item from a ListView,
passing that value to the next activity, and exiting:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selected = (String)myListAdapter.getItem(position);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setComponent(
new ComponentName("com.cereslogic.androidpreso",
"com.cereslogic.androidpreso.NextActivity")
);
intent.putExtra("selected", selected); // avail to NextActivity via getIntent()
startActivity(intent);
finish(); // called when we don’t want to come back here when user presses back.
}
});
Developing for Android:
The Basics
Common Idioms
• Separate “Handler” with a
progress dialog when
asynchronous stuff may take a
while
• If you don’t do this, Android may
just decide to kill your application
Developing for Android:
The Basics
Developing for Android:
The Basics
Demo Time!
Developing for Android:
The Basics
Time-consuming Async
Tasks
To kick off the task...
public class AsyncActivity extends Activity {
private Button button;
private EditText time;
private TextView finalResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = (EditText) findViewById(R.id.et_time);
button = (Button) findViewById(R.id.btn_do_it);
finalResult = (TextView) findViewById(R.id.tv_result);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AsyncTaskRunner runner = new AsyncTaskRunner();
String sleepTime = time.getText().toString();
runner.execute(sleepTime);
}
});
}
private class AsyncTaskRunner extends AsyncTask<String, String, String> { ... }
}
Developing for Android:
The Basics
Blocking task
button = (Button) findViewById(R.id.btn_do_it2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String resp;
finalResult.setText("Sleeping....");
try {
String sleepTime = time.getText().toString();
Thread.sleep(Integer.parseInt(sleepTime));
resp = "Slept for " + sleepTime + " milliseconds";
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
finalResult.setText(resp);
}
});
Developing for Android:
The Basics
Time-consuming
Async Tasks
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
@Override
protected String doInBackground(String... params) {
publishProgress("Sleeping..."); // Calls onProgressUpdate()
try {
// Do your long operations here and return the result
int time = Integer.parseInt(params[0]);
// Sleeping for given time period
Thread.sleep(time);
resp = "Slept for " + time + " milliseconds";
} catch (InterruptedException e) {
e.printStackTrace();
resp = e.getMessage();
} catch (Exception e) {
e.printStackTrace();
resp = e.getMessage();
}
return resp;
}
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
finalResult.setText(result);
}
@Override
protected void onPreExecute() {
// Things to be done before execution of long running operation. For
// example showing ProgessDialog
}
@Override
protected void onProgressUpdate(String... text) {
finalResult.setText(text[0]);
// Things to be done while execution of long running operation is in
// progress. For example updating ProgessDialog
}
}
Code for the Bad Bacon
Joke
public class BadBaconJoke extends Activity {
private ProgressDialog progressDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.progressDialog = ProgressDialog.show(this, "working...", "Some pancakes, eggs, and bacon walk into a bar. Bartender looks at them and says...");
new PunchlineTask().execute();
}
private class PunchlineTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
try {
Thread.sleep(8000);
} catch (InterruptedException e) { /* Don’t ever do this */ }
return "...hey! We don't serve breakfast here!";
}
@Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
new AlertDialog.Builder(BadBaconJoke.this)
.setMessage(result).setCancelable(false).setTitle("Punchline")
.setPositiveButton("Groan", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "Sorry.", Toast.LENGTH_LONG).show();
}
}).show();
}
}
}
Developing for Android:
The Basics
BroadcastReceiver
• Used for receiving events. Intended for short “trigger”
style events, not long running activities (use Services
for those)
• Examples: Incoming Phone Call, Text Message
• Registered using Intent Filters, just like Activities
• No View associated with them
• Can be registered statically in the manifest, or at
runtime
• Instance goes away when you’re finished processing
• Ordered or (more typically) Unordered
Developing for Android:
The Basics
Trivial BroadcastReceiver Example
Sorry, no Bacon this time...
public class WiFiChangeReceiver extends BroadcastReceiver {
private final static String TAG = "WiFiChangeReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "In onReceive.");
doSomethingAsynchronouslyInTheBackground();
}
Receiver
class
}
<receiver android:name="com.cereslogic.demo.WiFiChangeReceiver"
android:enabled="true">
<intent‐filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent‐filter>
</receiver>
Developing for Android:
The Basics
Manifest
(Demo if there is time)
Developing for Android:
The Basics
Services
• Long-running background processes
• Need to be started and stopped by an
Application (e.g., in a BroadcastReceiver), but
otherwise run independently of the applications
with which they’re associated
• “Foreground” services are less likely to be killed
by the OS
• Great way to drain batteries
• Big sloppy half-hearted example on the next
slide
Developing for Android:
The Basics
Service Example
public class LocalService extends Service {
private NotificationManager notificationManager;
private int NOTIFICATION = R.string.local_service_started;
@Override
public void onCreate() {
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
showNotification();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
@Override
public void onDestroy() {
notificationManager.cancel(NOTIFICATION);
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
private void showNotification() {
CharSequence text = getText(R.string.local_service_started);
Notification notification = new Notification(R.drawable.notification_icon, text, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, AnActivity.class), 0);
notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent);
notificationManager.notify(NOTIFICATION, notification);
}
}
Kick it off like this...
context.startService(new Intent(context, LocalService.class));
Developing for Android:
The Basics
Location Services
• A little weird to program for
• Can’t just ask the system “hey, where
am I right now?”
• Two Options:
• Last known location
• Sample location at rate X, and
Developing for Android:
The Basics
register to be notified when location
changes by more than X from the
previous location
Very Simple Location
Example
public class LocationClient implements LocationListener {
private static final Long MIN_UPDATE_INTERVAL = 1000L;
private static final float MIN_DISTANCE_SENSITIVITY = 100.0f;
private LocationManager locationManager;
private Location location = null;
public void determineLocation() {
this.locationManager = (LocationManager)this.getSystemService(LOCATION_SERVICE);
String bestProvider = this.getBestLocationProvider();
this.locationManager.requestLocationUpdates(bestProvider, MIN_UPDATE_INTERVAL, MIN_DISTANCE_SENSITIVITY, this);
}
private String getBestLocationProvider() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
String bestProvider = this.locationManager.getBestProvider(criteria, true);
return bestProvider;
}
// Required by LocationListener...
public void onLocationChanged(Location location) {
this.location = location;
logLocation(location);
this.locationManager.removeUpdates(this);
}
public Location getLocation() {
return this.location;
}
}
Developing for Android:
The Basics
Android Market
• No wait to publish apps - upload in the
developer console, and it’s available to
everybody.
• Buyer’s currency
• In-app purchases
• Google Checkout for purchases, 2.9%
discount rate
• Google’s cut of app price: 30%
Developing for Android:
The Basics
Developing for Android:
The Basics
Developer Console
Developer Console
user comments
in-app
purchase
s
Developing for Android:
The Basics
stats (earlier in
presentation)
error reports
Developer Console - Error
Reports
Developing for Android:
The Basics
Developer Console - Error Reports
Developing for Android:
The Basics
Developing for Android:
The Basics
Questions?
82