狠狠撸

狠狠撸Share a Scribd company logo
ANDROID
智慧型?手機程式設計
?
思創軟體 / 林彥宏?
資深軟體?工程師
http://lyhcode.info
基礎實作課程
建?立开发环境
ADT Bundle
? developer.android.com/sdk
? Eclipse IDE with built-in ADT?
(Android DeveloperTools)
DDMS
Dalvik Debug Monitor Server
Android Screen Monitor
http://goo.gl/mnMeaS
java -jar asm.jar
ctrl + 1 = 100%
ctrl + 7 = 75%
ctrl + 5 = 50%
縮放
執?行
AirDroid
Install “AirDroid”
from
Google Play Store
線上免費課程 from Coursera
Programming Mobile Applications for Android Handheld Systems
Android App 原始碼範例
https://github.com/aporter/coursera-android
從 GitHub 網站下載
第?一课
打造使?用者介?面
Activity
Life Cycle
UI
友善的
Android 智慧型手機程式設計
Android 智慧型手機程式設計
UI 的設計?方式
? 程序式(procedural)?
在程式碼動態產?生畫?面 UI 元件
? 宣告式(declarative)?
在 Layout XML 定義畫?面 UI 元件
指
尖
操
作
?行
為
手機程式的調色盤
Holo
?Colors
?Generator
?
Action
?Bar
?Style
?Generator
?
Adobe
?Color
?CC
Create a new Android Project
? Target SDK:Android 4.x
? Using Blank Activity
設定 API Level
? 編輯AndroidManifest.xml
? 設定 API Level 版本代號
uses-sdk
android:minSdkVersion=16
android:targetSdkVersion=16 /
Android API Level 对照表
? Change Layout =?
LinearLayout
? Add RadioButton
? Add Button
? AddTextView
畫?面佈置
? 修改 res/layout/activity_main.xml
? 調整 layout_width 為 ?ll_parent
Button
android:id=@+id/button1
android:layout_width=fill_parent
android:layout_height=wrap_content
android:onClick=showLocation
android:text=查詢地點 /
? Wrap Radio Buttons?
with RadioGroup
Click Event
1
2
3
Button ... android:onClick=“clickOpenMap” ...
public void clickOpenMap(View view) { ...
button1.setOnClickListener(new Button.OnClickListener() { ...
4
class MyButtonListener implements OnClickListener
public class MainActivity extends Activity implements OnClickListener
按鈕點擊事件的四種處理?方式
使?用 OnClickListener 類別
1. button1.setOnClickListener(new Button.OnClickListener() {
2. @Override
3. public void onClick(View v) {
4. ...
5. }
6. });
按鈕點擊後會執?行 onClick() ?方法
Show Location inTextView
1. public void showLocation(View view) {
2. switch (radioGroup1.getCheckedRadioButtonId()) {
3. case R.id.radioButton1:
4. textView1.setText(澄清湖的位置是 22.660665,120.3509745);
5. break;
6. case R.id.radioButton2:
7. textView1.setText(?西?子灣的位置是 22.629167,120.262778);
8. break;
9. }
10.}
Intent
1. Intent intent = new Intent();
2. intent.setClass(
3. MainActivity.this,
4. MainActivity2.class);
5. startActivity(intent);
參考資料
? http://ccckmit.wikidot.com/ga:intentexample
常?見的 Intent ?用法
? http://google.com
? geo:22.660,120.350
? tel: 0800080123
打開網站
打開地圖
撥打電話
Open Map with Intent
1. public void openMap(View view) {
2. Uri uri;
3. Intent intent;
4. switch (radioGroup1.getCheckedRadioButtonId()) {
5. case R.id.radioButton1:
6. uri = Uri.parse(geo:22.660,120.350);
7. intent = new Intent(Intent.ACTION_VIEW, uri);
8. startActivity(intent);
9. break;
10. }
11.}
Intent Example
?手機常?用功能快捷鍵
程
式
實
作
【學習??目標】
1. Button
2. Intent
RadioButton
Example
景點查詢?工具
程
式
實
作
【學習??目標】
1. RadioButton
2. TextView
3. Intent
第?二课
顯?示訊息與偵錯記錄
Logging / Debugging
Dialog
對話框
彈出後等待使?用者確認後才消失
Dialog Example
1. AlertDialog.Builder builder;
2. builder = new AlertDialog.Builder(view.getContext());
4. builder
5. .setTitle(“Something Wrong)
6. .setMessage(“Incorrect value, try again.”)
7. .setNeutralButton(OK, null)
8. .create()
9. .show();
}builder
style
Toast
Toast.makeText(view.getContext(), You've 3 messages., Toast.LENGTH_LONG);
message body
停留時間彈出後過幾秒?自動消失
訊息記錄(LOG)
? 給程式開發與測試?人員觀察程式執?行狀態
? 測試與除錯階段的重要資訊來源
輸出除錯訊息
System.out.println
Log.println tagpriority
使?用標準輸出(stdout)
使?用 Android 系統的 Log 機制
缺點:無法對訊息進?一步分類
訊息類型
PRIORITY 名稱 ?用途
DEBUG 僅供除錯
INFORMATION ?一般訊息
WARNING 資料或處理異常
ERROR 嚴重的錯誤;可能導致程式終?止
使?用 Log 類別
Log.println(Log.WARN, MyActivity, User account not exists.);
tagpriority message body
Tag 的命名慣例
public class MainActivity extends Activity {
private static final String TAG = MainActivity;
Log.println(Log.WARN, TAG, User account not exists.);
…
通常使?用該記錄存在的類別名稱(Class Name)
Log 類別提供的?方法簡寫
? v(String, String) (verbose)
? d(String, String) (debug)
? i(String, String) (information)
? w(String, String) (warning)
? e(String, String) (error)
依其重要程度(優先度)區分
}常?用
使?用 LogCat 監看除錯訊息
依照 Priority 篩選過濾
Dialog andToast
Example
景點查詢?工具
程
式
實
作
【學習??目標】
1. Dialog /Toast
2. Log
第叁课
多执?行绪与网路存取
應?用程式沒有回應
? 程式執?行超過五秒,UI 仍未能與使?用者互動
? 常發?生在:
? 處理複雜的演算法
? 等待網路傳輸資料
Application Not Responding (ANR)
處理 ANR 的?方法
? Thread / Runnable
? AsyncTask
? Handler
多執?行緒程式設計(Multithreading)
AsyncTask 範例
1. private class MyTask extends AsyncTaskVoid, Void, Void {
2. protected Long doInBackground(...) {
3. ...
4. }
5. }
KeepingYour App Responsive
http://developer.android.com/training/articles/perf-anr.html
程式實作
? 修改 res/layout/activity_main.xml
? 加?入 Button 「顯?示地圖」
? 加?入 ImageView 在畫?面下?方
Android 智慧型手機程式設計
activity_main.xml
ImageView
android:id=@+id/imageView1
android:layout_width=fill_parent
android:layout_height=150dp
android:src=/lyhcode/android-40667459/@drawable/ic_launcher /
Button
android:id=@+id/button3
android:layout_width=fill_parent
android:layout_height=wrap_content
android:onClick=showMap
android:text=顯?示地圖 /
Button
ImageView
?ndViewById
public class MainActivity extends Activity {
private RadioGroup radioGroup1;
private TextView textView1;
private ImageView imageView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
radioGroup1 = (RadioGroup) this.findViewById(R.id.radioGroup1);
textView1 = (TextView) this.findViewById(R.id.textView1);
imageView1 = (ImageView) this.findViewById(R.id.imageView1);
}
权限设定
使?用 Manifest 权限设定?工具
权限设定(XML定義)
? 編輯 AndroidManifest.xml
uses-permission
android:name=android.permission.INTERNET/
實作 showMap ?方法
public void showMap(View view) {
switch (radioGroup1.getCheckedRadioButtonId()) {
case R.id.radioButton1:
//...
break;
}
}
lat 與 lng 變數
Double lat = null, lng = null;
switch (radioGroup1.getCheckedRadioButtonId()) {
case R.id.radioButton1:
lat = 22.660;
lng = 120.350;
break;
}
if (lat != null  lng != null) {
//...
}
AsyncTask 實作
if (lat != null  lng != null) {
String url = ...;
new AsyncTaskString, Void, Drawable() {
@Override
protected Drawable doInBackground(String... params) {
try {
InputStream is = new URL(params[0]).openStream();
return Drawable.createFromStream(is, src);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Drawable result) {
if (result != null) {
imageView1.setImageDrawable(result);
}
super.onPostExecute(result);
}
}.execute(url);
}
2. 點擊「顯?示地圖」
1. 選擇景點
3. 地图显?示
加?入「查詢天氣」按鈕
Button
android:id=@+id/button4
android:layout_width=fill_parent
android:layout_height=wrap_content
android:onClick=showWeather
android:text=查詢天氣 /
showWeather ?方法實作
public void showWeather(View view) {
Double lat = null, lng = null;
switch (radioGroup1.getCheckedRadioButtonId()) {
case R.id.radioButton1:
lat = 22.660;
lng = 120.350;
break;
case R.id.radioButton2:
lat = 22.629;
lng = 120.262;
break;
}
}
OpenWeatherMap API
http://openweathermap.org
Web Services 存取天氣資料
http://api.openweathermap.org/data/2.5/weather?
lat=22.629lon=120.262units=metric
http://api.openweathermap.org/data/2.5/weather?
q=Taipei,TWunits=metric
OpenWeatherMap
Web Services APIAndroid App
HTTP Request
Data Response
XML, JSON, HTML, …
AsyncTask 實作
if (lat != null  lng != null) {
String url = ...;
new AsyncTaskString, Void, String() {
@Override
protected String doInBackground(String... params) {
//...
}
@Override
protected void onPostExecute(String json) {
//...
}
}.execute(url);
}
存取 HTTP Web Services
protected String doInBackground(String... params) {
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new URL(params[0]).openStream()));
String json = reader.readLine();
reader.close();
return json;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
解析 JSON 資料
protected void onPostExecute(String json) {
if (json != null) {
try {
JSONObject jsonObject = new JSONObject(json);
Double temp = jsonObject.getJSONObject(main).getDouble(temp);
textView1.setText(temp + ℃);
}
catch (Exception ex) {
ex.printStackTrace();
}
}
super.onPostExecute(json);
}
2. 點擊「查詢天氣」
1. 選擇景點
3. 显?示地区气温
第四课
建?立新专案 MyBrowser
activity_main.xml
MainActivity
public class MainActivity extends Activity {
EditText editText1;
WebView webView1;
Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText1 = (EditText) this.findViewById(R.id.editText1);
webView1 = (WebView) this.findViewById(R.id.webView1);
button1 = (Button) this.findViewById(R.id.button1);
}
权限设定
WebView 設定
//設定只?用 WebView 開啟網址
webView1.setWebViewClient(new WebViewClient());
//打開 JavaScript
webView1.getSettings().setJavaScriptEnabled(true);
按鈕 onClick 設定
Button
android:id=@+id/button1
android:layout_width=wrap_content
android:layout_height=wrap_content
android:layout_alignBottom=@+id/editText1
android:layout_alignRight=@+id/webView1
android:text=好?手氣
android:onClick=loadWebPage /
public void loadWebPage(View view) {
webView1.loadData(Loading..., text/plain, UTF-8);
String keyword = editText1.getText().toString();
try {
keyword = URLEncoder.encode(keyword, UTF-8);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String url = http://ajax.googleapis.com/ajax/services/search/web?v=1.0q= + keyword;
new AsyncTaskString, Void, String() {
@Override
protected String doInBackground(String... params) {
return null;
}
@Override
protected void onPostExecute(String json) {
}
}.execute(url);
}
doInBackground
@Override
protected String doInBackground(String... params) {
try {
InputStream stream = new URL(params[0]).openStream();
InputStreamReader isr = new InputStreamReader(stream, UTF-8);
BufferedReader reader = new BufferedReader(isr);
String json = reader.readLine();
return json;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
onPostExecute
@Override
protected void onPostExecute(String json) {
if (json != null) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray results = jsonObject.getJSONObject(responseData).getJSONArray(results);
if (results.length()  0) {
String url = results.getJSONObject(0).getString(url);
webView1.loadUrl(url);
}
else {
webView1.loadData(Not found..., text/plain, UTF-8);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
儲存紀錄
this.getPreferences(MODE_PRIVATE).edit().putString(LAST_QUERY,
editText1.getText().toString());
讀取記錄
editText1.setText(this.getPreferences(MODE_PRIVATE).getString(LAST_QUERY,
PCHome));
Android 智慧型手機程式設計
建?立新专案
2D 繪圖
setContentView(new View(this) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
paint.setColor(Color.GREEN);
canvas.drawCircle(100, 100, 20, paint);
}
});

More Related Content

Android 智慧型手機程式設計