Android slides - Users.drew.edu

advertisement
Developing Android Apps
Barry Burd
Drew University
Barry@Burd.org
Slides available at
http://allmycode.com/tcf
This presentation © 2014 Barry Burd
1
Agenda
• About Android
• Demo: Creating a "Hello, Android" App
• Making calls, sending text messages, visiting
Web sites, etc.
• Publishing an Android App
• ?&!
Today at TCF
10:15-11:10
Android 1
11:20-12:15
Android 2
12:25-1:30
Google Glass
Time?
Book signing
2
ABOUT ANDROID
3
Android
•
•
•
•
Purchased in mid-2000s by Google
"Open"
Based on Linux
Versions: Astro Boy, Bender, R2-D2, Cupcake
(1.5), Donut (1.6), Éclair (2.0-2.1), Froyo (2.2),
Gingerbread (2.3), Honeycomb (3.x), Ice
Cream Sandwich (4.0), Kit-Kat (4.1-4.3)
• Also Cyanogenmod
4
U.S. Market Share - 2013
Source:
http://thedroidguy.com/2013/07/androidmarket-share-vs-apple-blackberrywindows-symbian/
5
World Market Share - 2013
Source:
http://www.dazeinfo.com/2013/08/23/sam
sung-android-app-usage-advertisersreport/
6
CREATING AN ANDROID APP
7
What you need
• Java (java.com)
• Eclipse adt bundle
(developer.android.com/sdk)
– includes Eclipse with ADT
– includes the Android SDK
• Need to create at least one Android Virtual
Device (AVD)
8
Create an Android project
9
Project name, package name, SDKs used
10
About the app's Activity...
11
The newly created app's folders
12
The newly created activity
13
The main activity's layout
14
Drag and drop
15
Name the button's event handler
16
Create event handler code
17
Run As... Android Application
18
Running the app
The emulator takes a long
time to start. Make changes
to your code and rerun
without stopping and
restarting the emulator!
19
Testing on a real phone
• <application android:debuggable="true"...
• On the phone:
Settings → Applications → Development → USB debugging (on)
• Setup USB on the computer:
– Windows: Install an Android USB driver for the phone
– Mac: /* Do nothing */
– Linux: Add a rules file containing USB configuration info
• Plug the phone into the computer
• Run the project
(To run on an emulator with the phone plugged in, select Run
As... Run Configurations)
20
MAKING CALLS, SENDING TEXT
MESSAGES, VISITING WEB SITES, ETC.
21
Dialing
<activity android:name=”.DialerActivity”>
<intent-filter>
<action android:name=”android.intent.action.DIAL” />
<category
android:name=”android.intent.category.DEFAULT” />
<data android:scheme=”tel” />
</intent-filter>
</activity>
22
Dialing
boolean deviceIsAPhone() {
TelephonyManager manager = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
return manager.getPhoneType() !=
TelephonyManager.PHONE_TYPE_NONE;
}
intent.setData(Uri.parse("tel:234-555-6789"));
or
intent.setData(Uri.parse("tel:"));
startActivity(intent);
23
Sending a text message
SmsManager smsMgm = SmsManager.getDefault();
smsMgm.sendTextMessage("2345556789", null,
"Hello world", null, null);
The second parameter, a Java string, is a service center
address . null means "I don't care which service center."
The fourth parameter’s broadcast notifies the system
when the message is sent. The fifth parameter’s
broadcast notifies the system when the message is
received.
24
Using device sensors
sensorManager =
(SensorManager) getSystemService(Context.SENSOR_SERVICE);
magFieldSensor = sensorManager.getDefaultSensor(TYPE_MAGNETIC_FIELD);
accelerometer = sensorManager.getDefaultSensor(TYPE_ACCELEROMETER);
sensorManager.registerListener
(sensorListener, magFieldSensor, SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener
(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_UI);
locationManager.requestLocationUpdates
(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
25
Using device sensors
public void onSensorChanged(SensorEvent event) {
if (sensorEventType == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, gravityValues, 0, 3);
} else if (sensorEventType == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, geoMagnetValues, 0, 3);
...
if (SensorManager.getRotationMatrix
(rotationMatrix, null, gravityValues, geoMagnetValues)) {
SensorManager.getOrientation(rotationMatrix, orientation);
orientationView.setText
("Yaw:
" + orientation[0] + "\n"
+ "Pitch: " + orientation[1] + "\n"
+ "Roll: " + orientation[2]);
}
26
Using device sensors
public void onLocationChanged(Location location) {
locationView.setText
("Latitude: " + location.getLatitude() + "\n"
+ "Longitude: " + location.getLongitude());
}
27
public boolean onTouch(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
numberOfFingers = 1;
oldX[0] = event.getX(0);
oldY[0] = event.getY(0);
break;
case MotionEvent.ACTION_POINTER_DOWN:
numberOfFingers = 2;
oldX[1] = event.getX(1);
oldY[1] = event.getY(1);
break;
case MotionEvent.ACTION_MOVE:
handleMove(event);
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
numberOfFingers--;
break;
}
view.invalidate();
return true;
}
Handling
Touch Events
28
Getting an image from the Web
class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {
. . .
@Override
protected Bitmap doInBackground(String... urlArray) {
try {
URL url = new URL(urlArray[0]);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setDoInput(true); connection.connect();
progress += 50; publishProgress(progress);
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
progress += 50; publishProgress(progress);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
29
Getting real weather data
(from World Weather Online)
public Weather getWeather(String location) {
URL url;
Weather weather = null;
try {
url=new URL(WORLD_WEATHER_ONLINE_URL+location.replace(" ", "%20"));
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
XMLReader reader = parser.getXMLReader();
MySaxHandler saxHandler = new MySaxHandler();
reader.setContentHandler(saxHandler);
reader.parse(new InputSource(url.openStream()));
weather = saxHandler.getWeather();
} catch (Exception e) {
e.printStackTrace();
}
return weather;
}
30
Getting real weather data
(from World Weather Online)
public class MySaxHandler extends DefaultHandler {
@Override
public void startElement(String namespaceURI,
String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals(CURRENT_CONDITIONS)) {
current_conditions = true;
} else {
if (current_conditions) {
if (localName.equals(TEMP_F)) {
temp_f = true;
} else if (localName.equals(CONDITION)) {
weatherDescription = true;
}
}
}
}
31
Getting real weather data
(from World Weather Online)
@Override
public void characters(char chars[], int start, int length) throws SAXException {
if (temp_f) {
weather.setTemperature(Integer.parseInt(String.valueOf(chars, start, length)));
} else if (weatherDescription) {
weather.setCondition(String.valueOf(chars, start, length));
}
}
@Override
public void endElement(String namespaceURI,
String localName, String qName) throws SAXException {
if (localName.equals(CURRENT_CONDITIONS)) {
current_conditions = false;
}
else {
if (localName.equals(TEMP_F)) {
temp_f = false;
} else if (localName.equals(CONDITION)) {
weatherDescription = false;
}
}
}
32
Using sqlite (for an app's own data)
helper = new DBHelper(this, "simple_db", null, 1);
db = helper.getWritableDatabase();
values = new ContentValues();
values.put("name", "Barry");
values.put("amount", "100");
db.insert("simpletable", "", values);
values.clear();
values.put("name", "Harriet");
values.put("amount", "300");
db.insert("simpletable", "", values);
addToTextView();
values.clear();
values.put("amount", "500");
db.update("simpletable", values, "name='Barry'", null);
addToTextView();
db.delete("simpletable", "1", null);
addToTextView();
33
Doing a query
void addToTextView() {
cursor =
db.rawQuery("SELECT * FROM simpletable;", null);
if (cursor != null && cursor.moveToFirst()) {
String name;
do {
String _id = cursor.getString(0);
name = cursor.getString(1);
int amount = cursor.getInt(2);
textView.append(_id + " " + name + " " + amount + "\n");
} while (cursor.moveToNext());
}
textView.append("-----------\n");
}
34
My DBHelper Class
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String dbName,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, dbName, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createString =
"CREATE TABLE IF NOT EXISTS simpletable "
+ "( _id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "name TEXT NOT NULL, "
+ "amount INTEGER NOT NULL);";
db.execSQL(createString);
}
@Override
public void onUpgrade(SQLiteDatabase db,
int oldVersion, int newVersion) {
String dropString =
"DROP TABLE IF EXISTS simpletable;";
db.execSQL(dropString);
onCreate(db);
}
}
35
DEPLOYING AN ANDROID APP
36
Where to publish an Android app
from http://www.coderanch.com/how-to/java/AndroidFaq
•
•
•
•
•
•
•
•
•
•
•
•
Android Market: http://www.android.com/market/
Voeveo: http://www.voeveo.com/
SlideME: http://www.slideme.org/
AndAppStore: http://andappstore.com/
AndroLib: http://www.androlib.com/
Cyrket: http://www.cyrket.com/
AndroidPIT (in German): http://www.androidpit.de/
AndSpot: http://andspot.com/
AppBrain: http://www.appbrain.com/
Aproov: http://www.aproov.com/
Amazon appstore (in beta): https://developer.amazon.com/
as an .apk file on your own website
37
Preparing for Google's Android Market
• Test, test, test
– Wide variety of devices, conditions, resolutions,
network delays, etc.
• [optional] Add End User License Agreement
and support for Android Market Licensing
(network-based license check at startup time)
• Specify icon and label
<application android:icon="drawable resource"
android:label="string resource" ... >
...
</application>
38
Preparing for Google's Android Market
• Remove development-only stuff
– <application android:debuggable="true" ...
– Remove logging code, test data, etc.
• Create a version
<manifest android:versionCode="integer"
android:versionName="string" ...
– The only versionCode rule is that later versions
must have higher version numbers
– Users typically don't see the versionCode
– Users typically see versionName
– A versionName example: 1.1.2 (major.minor.point)
39
Compile the app in
release mode and
sign the app
40
Compile the app in
release mode and
sign the app
41
Compile the app in
release mode and
sign the app
Must be valid
at least until
Oct. 22, 2033
42
Compile the app in
release mode and
sign the app
Note: Eclipse automatically
performs zipalign on your app.
When you do it manually, the
zipalign step must come after
signing.
Note: To use Google's
Maps API you must also
have a Maps API key.
43
To start publishing, visit
http://market.android.com/publish/Home
44
45
After clicking Upload buttons
46
Icons
• UI Guidelines
developer.android.com/guide/practices/ui_guidelines/icon_design.html
Includes guidelines for icon naming; icon types (launcher, menu, tab, etc.),
icon densities (hdpi, mdpi, ldpi), etc.
• Android Icon Templates Pack
developer.android.com/shareables/icon_templates-v2.3.zip
• 512x512 pixels, 32-bit PNG (or JPEG?) with
alpha, max size of 1024KB
47
48
49
50
For testing, click Save instead of Publish.
51
Your app is saved
52
?&!
Barry Burd
Drew University
Barry@Burd.org
Slides available at
http://allmycode.com/tcf
Today at TCF
10:15-11:10
Android 1
11:20-12:15
Android 2
12:25-1:30
Google Glass
Time?
Book signing
53
Download