Android基礎知識精簡版(轉)

1. 前言

裁剪了下轉載內容,只保留我認爲有用的知識點。

2. 搭建開發環境

http://tools.android-studio.org/

3. 開發一個 Android 程序

3.1. 建立 Android 程序

Ø 建立 Android Project javascript

Ÿ Project name :項目名 php

Ÿ Build Target Android 版本 html

Ÿ Application name :程序名,顯示在程序列表中,以及程序啓動後的標題欄 前端

Ÿ Package name :包名,程序的惟一標識 java

Ÿ Create Activity :選擇程序啓動時是否建立一個窗體,設置主窗體名字 android

Ÿ Min SDK Version :設置運行該程序所需的最低版本 git

3.2. 安裝、卸載程序

Ÿ Eclipse 安裝 github

右鍵點擊工程 – Run as – Android Applicationweb

Ÿ 虛擬機卸載sql

設置 – 應用程序 – 管理應用程序 – 選中要卸載的程序 – 卸載

3.3. 瞭解項目目錄結構

Ÿ src :源代碼

Ÿ gen :系統自動生成的文件

R.java 中記錄了項目中各類資源 ID

Ÿ res :系統資源,全部文件都會在 R 文件生成資源 ID

drawable :圖片

layout :界面佈局

values :數據

anim :定義動畫的 XML

raw :原生文件

Ÿ assets :資源路徑,不會在 R 文件註冊

Ÿ project.properties :供 Eclipse 使用,讀取該項目使用 Android 版本號。早期版本名爲: default.properties

Ÿ AndroidManifest.xml :清單文件,在軟件安裝的時候被讀取

Android 中的四大組件( Activity ContentProvider BroadcastReceiver Service )都須要在該文件中註冊

程序所需的權限也須要在此文件中聲明,例如:電話、短信、互聯網、訪問 SD

Ÿ bin :二進制文件,包括 class 、資源文件、 dex apk

Ÿ proguard.cfg:用來混淆代碼的配置文件,防止別人反編譯

3.4. 程序啓動過程

Ÿ Eclipse .java 源文件編譯成 .class

Ÿ 使用 dx 工具將全部 .class 文件轉換爲 .dex 文件

Ÿ 再將 .dex 文件和全部資源打包成 .apk 文件

Ÿ 將 .apk 文件安裝到虛擬機完成程序安裝

Ÿ 啓動程序 – 開啓進程 – 開啓主線程

Ÿ 建立 Activity 對象  – 執行 OnCreate() 方法

Ÿ 按照 main.xml 文件初始化界面

4. 演示案例

41. 查看程序錯誤信息

Ÿ Android 程序中若是出錯,錯誤不會顯示在 Console 中,而是顯示在 LogCat 界面下。能夠從 window  – show view 中打開

Ÿ 日誌信息分爲 5 個級別: verbose > debug > info > warn > error  高級的包含低級的

Ÿ 能夠建立過濾器對日誌進行過濾顯示,點擊綠色加號,能夠按照 tag pid level 進行篩選

4.2. 佈局

Ø RelativeLayout (相對佈局)

Ÿ android-sdk-windows/docs/guide/topics/ui/layout-objects.html#relativelayout

Ø TableLayout (表格佈局)

android-sdk-windows/docs/guide/topics/ui/layout-objects.html#tablelayout

Ø FrameLayout (幀佈局)

android-sdk-windows/docs/guide/topics/ui/layout-objects.html#framelayout

setRequestedOrientation(ActivityInfo. SCREEN_ORIENTATION_LANDSCAPE );

setRequestedOrientation(ActivityInfo. SCREEN_ORIENTATION_PORTRAIT );

4.3. Junit

Ø 項目中添加測試類

Ÿ 在 AndroidManifest.xml 清單文件中添加配置

< instrumentation  android:targetPackage = "cn.itcast.junit"  android:name = "android.test.InstrumentationTestRunner"  />

< uses-library  android:name = "android.test.runner"  />

Ÿ 定義一個類繼承 AndroidTestCase ,定義測試方法

Ÿ 在 Outline 視圖下右鍵點擊測試方法  – Run as – Android Junit Test

Ø 建立測試項目

Ÿ 建立 Android Test Project

Ÿ 輸入項目名,選擇一個已存在的工程, Eclipse 能夠自動配置 Junit 環境

5. 文件操做( File XML SharedPreferences

5.1. 讀寫文件

Ø 寫入文件到 SD

Ÿ 須要在清單文件中註冊權限

< uses-permission  android:name = "android.permission.WRITE_EXTERNAL_STORAGE"  />

Ÿ 2.1 版本如下的 SDCard 位置和 2.2 以後版本不一樣

能夠經過Environment.getExternalStorageDirectory()獲取當前 SDCard 位置,兼容全部版本

Ÿ 獲取 SDCard 狀態

經過Environment.getExternalStorageState()方法獲取 SDCard 當前狀態

常量 Environment.MEDIA_MOUNTED 爲已安裝

Ø 寫入文件

Ÿ 經過 Context. openFileOutput(String name,  int  mode)能夠獲取一個文件輸入流

name 爲文件名, mode 爲文件模式,有 4 種模式

輸出流指向路徑爲: /data/data/ 包名 /files/ 

Ÿ 文件模式在 Context 中有定義常量

MODE_PRIVATE 私有

MODE_WORLD_READABLE 其餘程序可讀(不可寫)

MODE_WORLD_WRITEABLE 其餘程序可寫(不可讀)

模式能夠組合使用,例如:MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE

MODE_APPEND 追加

Ø 讀取文件

Ÿ 經過 Context. openFileInput(String name)能夠獲取一個文件輸入流

該輸入流能夠讀取  /data/data/ 包名 /files/  路徑下的文件

Ÿ 獲取當前程序 Files 文件路徑

ContextWrapper.getFilesDir()

5.2. XML

Ø Pull 簡介

Ÿ 常見的 XML 解析方式有三種, DOM SAX Pull Android 系統中推薦使用 Pull

Ÿ Pull 解析器是一個開源的 Java 項目, Android 系統內部解析 XML 文件均爲此種方式,也可用於 JavaEE 項目

Ÿ Android SDK 中已經集成了 Pull 解析器,無需添加任何 jar 文件

Ÿ Pull 解析器運行方式與 SAX 相似,提供各類事件的判斷

Ÿ 官方網站: http://xmlpull.org/

Ø 使用 Pull 解析器解析 XML 文件

Ÿ Xml.newPullParser() 得到解析器

Ÿ parser.setInput(in,  "UTF-8" ) 設置輸入流以及編碼

Ÿ parser.next() 獲取下一個解析事件,獲得一個事件代碼

Ÿ XmlPullParser中定義了常量來標識各類解析事件

START_DOCUMENT 、 END_DOCUMENT  START_TAG  、END_TAG  TEXT 

Ø 使用XmlSerializer寫出 XML

Ÿ 使用如下方法生成 XML ,和 XML 文檔順序相似

startDocument

startTag

attribute

text

endTag

endDocument

5.3. 偏好設定( SharedPreferences ) 

Ÿ 在程序中保存一些配置參數的時候咱們常用 SharedPreferences

Context.getSharedPreferences(String name, int  mode)

該方法能夠在 /data/data/<package>/shared_pref/ 目錄下建立一個以 name 命名的 xml 文件, mode 文件爲模式

Ÿ 存儲偏好

調用edit()方法能夠獲取一個 Editor 對象,對數據進行存儲,存儲以後須要調用 commit()保存到文件

Ÿ 讀取偏好

得到SharedPreferences以後調用 getString() getInt() 等方法獲取其中設置的值

Ÿ 在 Activity 中獲取 SharedPreferences

Activity 中能夠調用 getPreferences( int  mode)方法得到一個SharedPreferences,文件名和 Activity 名一致

6. 數據庫( SQLite

6.1. SQLite 特色

Ÿ Android 平臺中嵌入了一個關係型數據庫 SQLite ,和其餘數據庫不一樣的是 SQLite 存儲數據時不區分類型

例如一個字段聲明爲 Integer 類型,咱們也能夠將一個字符串存入,一個字段聲明爲布爾型,咱們也能夠存入浮點數。

除非是主鍵被定義爲 Integer ,這時只能存儲 64 位整數

Ÿ 建立數據庫的表時能夠不指定數據類型,例如:

CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))

CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name)

Ÿ SQLite 支持大部分標準 SQL 語句,增刪改查語句都是通用的,分頁查詢語句和 MySQL 相同

SELECT * FROM person LIMIT 20 OFFSET 10

SELECT * FROM person LIMIT 10,20

6.2. 建立數據庫

Ÿ 定義類繼承SQLiteOpenHelper

Ÿ 聲明構造函數, 4 個參數

Ÿ 重寫 onCreate ()方法

Ÿ 重寫 upGrade() 方法

Ÿ 注意: SQLite 數據庫中列一旦建立不能修改,若是必定要修改,須要從新建立表,拷貝數據

6.3. CRUD操做

Ÿ 和 JDBC 訪問數據庫不一樣,操做 SQLite 數據庫無需加載驅動,不用獲取鏈接,直接可使用

獲取 SQLiteDatabase 對象以後經過該對象直接能夠執行 SQL 語句

SQLiteDatabase.execSQL()

SQLiteDatabase.rawQuery()

Ÿ getReadableDatabase()和getWritableDatabase()的區別

查看源代碼後咱們發現getReadableDatabase()在一般狀況下返回的就是getWritableDatabase() 拿到的數據庫

只有在拋出異常的時候纔會以只讀方式打開

Ÿ 數據庫對象緩存

getWritableDatabase() 方法最後會使用一個成員變量記住這個數據庫對象,下次打開時判斷是否重用

Ÿ SQLiteDatabase 封裝了 insert() delete ()、 update ()、 query ()四個方法也能夠對數據庫進行操做

這些方法封裝了部分 SQL 語句,經過參數進行拼接

6.4. 事務管理

Ÿ 在使用 SQLite 數據庫時能夠用 SQLiteDatabase類中定義的相關方法控制事務

beginTransaction()  開啓事務

setTransactionSuccessful()  設置事務成功標記

endTransaction()  結束事務

Ÿ endTransaction() 須要放在 finally 中執行,不然事務只有到超時的時候才自動結束,會下降數據庫併發效率

7. 內容提供者( ContentProvider

7.1. 什麼是內容提供者

Ÿ 內容提供者是 Android 中的四大組件之一,能夠將應用中的數據對外進行共享

Ÿ 內容提供者將數據的訪問方式統一,沒必要針對不一樣數據類型採起不一樣的訪問策略

Ÿ 內容提供者將數據封裝,只暴露出咱們但願提供給其餘程序的數據

Ÿ 內容提供者中數據更改可被監聽

7.2. 建立內容提供者

Ÿ 定義類繼承 ContentProvider ,根據須要重寫內部方法

Ÿ 在清單文件的 <application> 節點下進行配置, <provider> 標籤中須要指定 name authorities 屬性

name 爲類名,包名從程序 Package 開始,以「 . 」開始

authorities :是訪問 Provider 時的路徑,要惟一

Ÿ URI 表明要操做的數據,由 scheme authorites path 三部分組成

content:// cn.itcast. sqlite . provider / person

scheme :固定爲 content ,表明訪問內容提供者

authorites : <provider> 節點中的 authorites 屬性

path :程序定義的路徑,可根據業務邏輯定義

7.3. 完成 CRUD 方法

Ÿ 當程序調用 CRUD 方法時會傳入 Uri

Ÿ 咱們經過 Uri 判斷調用者要操做的數據

可使用工具類 UriMatcher 來判斷 Uri

addURI 方法能夠添加 Uri

match 方法能夠匹配一個 Uri 判斷其類型

Ÿ 根據業務邏輯操做數據

7.4. 訪問內容提供者

Ÿ 經過 Context 得到 ContentResolver 對象

Ÿ 調用 ContentResolver 對象的方法便可訪問內容提供者

7.5. 完成 getType 方法

Ÿ 若是返回數據是單條數據:vnd.android.cursor.item 

Ÿ 若是返回數據是多條數據:vnd.android.cursor.dir

7.6. 監聽內容提供者數據變化

Ÿ 在內容提供者中能夠通知其餘程序數據發生變化

經過 Context 的 getContentResolver() 方法獲取 ContentResolver

調用其notifyChange() 方法發送數據修改通知

Ÿ 在其餘程序中能夠經過ContentObserver監聽數據變化

經過 Context 的 getContentResolver() 方法獲取 ContentResolver

調用其registerContentObserver() 方法指定對某個 Uri 註冊 ContentObserver

自定義ContentObserver,重寫 onChange() 方法獲取數據

7.7. GIT 獲取源代碼

Ø 資源地址

Ÿ Git

http://code.google.com/p/msysgit/

Ÿ 源碼

https://github.com/android

注意:

GIT1.7.7 安裝後不能卸載,能夠用其餘版本覆蓋後再卸載。

使用 GIT 時不要使用中文目錄,不然 GIT GUI 會報錯沒法啓動。刪除 C 盤中 .gitconfig文件能夠解決。

8. 網絡通訊

8.1. 獲取文本數據

Ÿ 經過 URL 對象封裝地址,打開一個 HttpURLConnection

Ÿ 設置頭信息以後獲取響應碼,若是成功返回 200 便可從 HttpURLConnection 中獲取輸入流讀取數據

Ÿ 代碼過長屏幕顯示不全可使用 <ScrollView> 進行顯示

Ÿ 須要訪問網絡的權限

< uses-permission  android:name = "android.permission.INTERNET"  />

8.2. 獲取網絡圖片

Ÿ 經過 BitmapFactory 的 decodeByteArray(byte[] data, int offset, int length)方法將數據轉換爲圖片對象

8.3. 獲取 XML

Ÿ 使用 URL 封裝路徑,打開一個 HttpURLConnection

Ÿ 設置頭信息以後獲取相應碼,從輸入流中獲取數據

Ÿ 使用 XmlPullPaser 解析

8.4. 獲取 JSON

Ÿ 使用 URL 封裝路徑,打開一個 HttpURLConnection

Ÿ 設置頭信息以後獲取相應碼,從輸入流中獲取數據

Ÿ 將數據轉爲 String ,封裝成 JSONArray 對象

Ÿ 遍歷 JSONArray 對象,調用獲取其中的 JSONObject

Ÿ 再從 JSONObject 中獲取每一個字段的信息

8.5. 發送 GET 請求

Ÿ 拼接路徑和參數,經過 URL 進行封裝,打開一個 HttpURLConnection ,發送請求

Ÿ 若是參數是中文會出現亂碼

Ÿ URL 中包含的中文參數須要使用 URLEncoder 進行編碼

Ÿ 服務器端若是是 TOMCAT ,其默認使用 ISO8859-1 編碼,接收時須要處理編碼問題

8.6. 發送 POST 請求

Ÿ 經過 URL 打開一個 HttpURLConnection

Ÿ 頭信息中除了超時時間和請求方式以外還必須設置Content-Type和Content-Length

Ÿ 從 HttpURLConnection 得到輸出流輸出參數數據

Ÿ 服務端可使用 request 對象的 setCharacterEncoding方法設置編碼

8.7. 發送 XML ,訪問 WebService

Ø 發送 XML

Ÿ 經過 URL 封裝路徑打開一個 HttpURLConnection

Ÿ 設置請求方式,Content-Type和Content-Length

XML 文件的 Content-Type爲:text/xml; charset=UTF-8

Ÿ 使用 HttpURLConnection 獲取輸出流輸出數據

Ø WebService

Ÿ WebService 是發佈在網絡上的 API ,能夠經過發送 XML 調用, WebService 返回結果也是 XML 數據

Ÿ WebService 沒有語言限制,只要能夠發送 XML 數據和接收 XML 數據便可

Ÿ  http://www.webxml.com.cn  網站上提供了一些 WebService 服務,咱們能夠對其進行調用

Ÿ  http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?op=getMobileCodeInfo  中提供了電話歸屬地查詢的使用說明

8.8. HTTP 協議上傳文件

Ÿ 搭建服務器,完成上傳功能

Ÿ 使用瀏覽器上傳,查看請求信息

Ø HttpURLConnection

Ÿ 經過 URL 封裝路徑打開一個 HttpURLConnection

Ÿ 設置請求方式以及頭字段:Content-Type、Content-Length、Host

Ÿ 拼接數據發送

Ø Socket

Ÿ 使用 HttpURLConnection 發送時內部有緩存機制,若是上傳較大文件會致使內存溢出

Ÿ 咱們可使用 Socket 發送 TCP 請求,將上傳數據分段發送

Ø HttpClient

public   void  upload(String name, String password, String path)  throws  Exception {

//  建立 HttpClient 對象

HttpClient client =  new  HttpClient();

//  設置超時事件

client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

//  建立一個 Post 請求 指定路徑

PostMethod postMethod =  new  PostMethod( "http://192.168.1.102:8080/14.Web/LoginServlet" );

//  封裝每一個表單項

Part[] parts = {  new  StringPart( "name" , name),  new  StringPart( "password" , password),  new  FilePart( "file" ,  new  File(path)) };

//  Post 請求設置實體

postMethod.setRequestEntity( new  MultipartRequestEntity(parts, postMethod.getParams()));

//  執行 Post 請求

client.executeMethod(postMethod);

// Post 請求是釋放資源

postMethod.releaseConnection();

}


8.9. 多線程斷點續傳下載器

Ÿ 在下載的時候多個線程併發能夠佔用服務器端更多資源,從而加快下載速度

Ÿ 手機端下載數據時不免會出現無信號斷線、電量不足等狀況,因此須要斷點續傳功能

Ÿ 根據下載數據長度計算每一個線程下載的數據位置,程序中開啓多個線程併發下載

在請求頭中設置 Range 字段就能夠獲取指定位置的數據,例如: Range: bytes=100-200

Ÿ 在下載過程當中記錄每一個線程已拷貝數據的數量,若是下載中斷,下次啓動時從記錄位置繼續下載

Ø 多線程下載

Ÿ 進度條使用 <Progress> 進行配置

默認爲圓形進度條,水平進度條須要配置 style 屬性, ?android:attr/progressBarStyleHorizontal

使用 android.R.attr. progressBarStyleHorizontal做爲樣式

Ÿ 當點擊下載按鈕時開啓多線程下載,下載過程當中修改進度條進度

設置最大刻度:setMax()

設置當前進度:setProgress()

Ø 斷點續傳

Ÿ 斷點續傳須要在下載過程當中記錄每條線程的下載進度

Ÿ 每次下載開始以前先讀取數據庫,查詢是否有未完成的記錄,有就繼續下載,沒有則建立新記錄插入數據庫

Ÿ 在每次向文件中寫入數據以後,在數據庫中更新下載進度

Ÿ 下載完成以後刪除數據庫中下載記錄

Ø Handler 傳輸數據

Ÿ 主線程中建立的 View 只能在主線程中修改,其餘線程只能經過和主線程通訊,在主線程中改變 View 數據

Ÿ 咱們使用 Handler 能夠處理這種需求

主線程中建立 Handler ,重寫 handleMessage() 方法

新線程中使用 Handler 發送消息,主線程便可收到消息,而且執行 handleMessage() 方法

Ø 動態生成新 View

Ÿ 建立 XML 文件,將要生成的 View 配置好

Ÿ 獲取系統服務 LayoutInflater ,用來生成新的 View

LayoutInflater inflater = (LayoutInflater) getSystemService( LAYOUT_INFLATER_SERVICE );

Ÿ 使用inflate( int  resource, ViewGroup root)方法生成新的 View

Ÿ 調用當前頁面中某個容器的 addView ,將新建立的 View 添加進來

9. 活動( Activity

9.1. 建立 Activity

Ø 定義 Activity

Ÿ 定義類繼承 Activity

Ÿ 在 AndroidManifest.xml <application> 節點中聲明 <activity>

Ø 顯式意圖建立方式

Ÿ 構造函數,代碼少

new  Intent( this , NewActivity. class );

Ÿ 類名形式,靈活,可擴展性強

intent.setClassName( this ,  "cn.itcast.activity.NewActivity" );

Ÿ 包名類名形式,可啓動其餘程序中的 Activity

intent.setClassName( "cn.itcast.downloader" ,  "cn.itcast.downloader.MainActivity" );

Ø 建立 Activity 並傳遞數據

Ÿ 在乎圖對象中封裝了一個 Bundle 對象,能夠用來攜帶數據

Ÿ 在新 Activity 中能夠得到意圖對象以獲取其中 Bundle 保存的數據

Ø 建立 Activity 獲取返回數據

Ÿ 使用startActivityForResult(Intent intent,  int  requestCode) 方法打開 Activity

Ÿ 重寫onActivityResult( int  requestCode,  int  resultCode, Intent data) 方法

Ÿ 新 Activity 中調用 setResult( int  resultCode, Intent data) 設置返回數據以後,關閉 Activity 就會調用 onActivityResult方法

Ø 隱式意圖建立 Activity

Ÿ 顯式意圖是指在建立意圖時指定了組件,而隱式意圖則不指定組件,經過動做、類型、數據匹配對應的組件

Ÿ 在清單文件中定義 <activity> 時須要定義 <intent-filter> 才能被隱式意圖啓動

Ÿ <intent-filter> 中至少配置一個 <action> 和一個 <category> ,不然沒法被啓動

Ÿ Intent 對象中設置的 action category data <intent-filter> 必須所有包含才能啓動

Ÿ <intent-filter> 中的 <action> <category> <data> 均可以配置多個, Intent 對象中不用所有匹配,每樣匹配一個便可啓動

Ÿ 若是一個意圖能夠匹配多個 Activity Android 系統會提示選擇

9.2. 生命週期

Ÿ Acitivity 三種狀態

運行: activity 在最前端運行

暫停: activity 可見,但前端還有其餘 acti vity ,被覆蓋一部分,或者前端 activity 透明

中止: activity 不可見,徹底被覆蓋

Ÿ 生命週期相關方法

onCreate :建立時調用,或者程序在暫停、中止狀態下被殺死以後從新打開時也會調用

onStart onCreate 以後或者從中止狀態恢復時調用

onResume onStart 以後或者從暫停狀態恢復時調用,從中止狀態恢復時因爲調用 onStart ,也會調用 onResume

onPause:進入暫停、中止狀態,或者銷燬時會調用

onStop:進入中止狀態,或者銷燬時會調用

onDestroy:銷燬時調用

onRestart :從中止狀態恢復時調用

Ÿ 保存信息相關方法

onSaveInstanceState:在 Activity 被動的摧毀或中止的時候調用,用於保存運行數據,能夠將數據存在在 Bundle

onRestoreInstanceState:該方法在 Activity 被從新繪製的時候調用,例如改變屏幕方向, savedInstanceState爲onSaveInstanceState保存的數據

9.3. 啓動模式

Ÿ 在 AndroidManifest.xml 中的 <activity> 標籤中能夠配置 android:launchMode 屬性,用來控制 Actvity 的啓動模式

Ÿ 在 Android 系統中咱們建立的 Acitivity 是以棧的形式呈現的

standard :每次調用 startActivity() 啓動時都會建立一個新的 Activity 放在棧頂

singleTop :若是啓動的 Activity 時,指定 Activity 不在棧頂就建立,如在棧頂,則再也不建立

singleTask :若是啓動的 Activity 不存在就建立,若是存在直接跳轉到指定的 Activity 所在位置

singleInstance :若是啓動的 Activity 不存在就建立,若是存在就將指定的 Activity 移動到棧頂

9.4. 內存管理

Ÿ Android 系統在運行多個進程時,若是系統資源不足,會強制結束一些進程。優先選擇哪一個進程來結束是有優先級的。如下順序靠上的優先結束

空:進程中全部 Activity 都已銷燬

後臺:進程中有一箇中止狀態的 Activity

可見:進程中有一個暫停狀態的 Activity

前臺:進程中正在運行一個 Activity

10. 廣播接收者 (BroadcastReceiver)

10.1. 定義廣播接收者

Ÿ 定義類繼承 BroadcastReceiver ,重寫 onReceive 方法

Ÿ 清單文件中聲明<receiver>,須要在其中配置<intent-filter>指定接收廣播的動做

Ÿ 當接收到匹配廣播以後就會執行 onReceive 方法

Ÿ BroadcastReceiver 除了在清單文件中聲明,也能夠在代碼中聲明,使用 registerReceiver方法註冊 Receiver

10.2. 發送廣播

Ø 無序廣播

Ÿ 使用sendBroadcast方法發送

Ÿ 被全部廣播接收者接收,無序,不可中斷

Ÿ 廣播時可設置接收者權限,僅當接收者含有權限才能接收

Ÿ 接收者的<receiver>也可設置發送方權限,只接收含有權限應用的廣播

Ø 有序廣播

Ÿ 使用sendOrderedBroadcast方法發送

Ÿ 接收者能夠在<intent-filter>中定義android:priority定義優先級,數字越大優先級越高

Ÿ 被各個廣播接收者逐個接收,中途能夠中斷或者添加數據

abortBroadcast()  

getResultExtras( true ).putString( "data" ,  " 新增數據 " );

10.3. 監聽短信接收

Ÿ Android 系統在收到短信的時候會發送一條有序廣播,咱們若是定義一個接收者接收這個廣播,就能夠獲得短信內容,也能夠攔截短信

Ÿ 定義廣播接收者接收廣播 android.provider.Telephony.SMS_RECEIVED

Ÿ 在 onReceive 方法內部調用 Intent getExtras() 再調用 get(String) 獲取其中 pdus 字段,獲得一個 Object[],其中每個元素都是一個 byte[]

Ÿ 經過SmsMessage類的createFromPdu方法建立 SmsMessage 對象

Ÿ 從 SmsMessage 對象中便可獲取發送者號碼、短信內容、發送時間等信息

Ÿ 須要接收短信權限: < uses-permission  android:name ="android.permission.RECEIVE_SMS" />

Ÿ Android 系統中收到短信的通知是一個有序通知,咱們如需攔截垃圾短信,能夠配置較高的 priority,收到信息進行判斷是否abortBroadcast()

10.4. 監聽呼出電話

Ÿ 定義廣播接收者接收  android.intent.action.NEW_OUTGOING_CALL

Ÿ 須要權限  < uses-permission  android:name = "android.permission.PROCESS_OUTGOING_CALLS" />

Ÿ 在 onReceive 方法中使用 getResultData() 和  setResultData()  方法獲取和設置電話號碼

10.5. 生命週期

Ÿ 廣播接收者的生命週期是很是短暫的,在接收到廣播的時候建立, onReceive() 方法結束以後銷燬

Ÿ 廣播接收者中不要作一些耗時的工做,不然會彈出 Application No Response 錯誤對話框

Ÿ 最好也不要在廣播接收者中建立子線程作耗時的工做,由於廣播接收者被銷燬後進程就成爲了空進程,很容易被系統殺掉

Ÿ 耗時的較長的工做最好放在服務中完成

11. 服務 (Service)

11.1. 基本概念

Ÿ Service 是一種在後臺運行,沒有界面的組件,由其餘組件調用開始。

Ÿ 建立 Service ,定義類繼承 Service AndroidManifest.xml 中定義 <service>

Ÿ 開啓 Service ,在其餘組件中調用 startService方法

Ÿ 中止 Service ,調用 stopService方法

11.2. 電話錄音

須要權限: android.permission.READ_PHONE_STATE

TelephonyManager manager = (TelephonyManager) getSystemService( TELEPHONY_SERVICE );

manager.listen( new  MyListener(), PhoneStateListener. LISTEN_CALL_STATE );

private   final   class  MyListener  extends  PhoneStateListener {

private  String  num ;

private  MediaRecorder  recorder ;

public   void  onCallStateChanged( int  state, String incomingNumber) {

switch  (state) {

case  TelephonyManager. CALL_STATE_RINGING :

num  = incomingNumber;

break ;

case  TelephonyManager. CALL_STATE_OFFHOOK :

try  {

File  file  =  new  File(Environment.getExternalStorageDirectory(),  num  +  "_"  + System.currentTimeMillis() +  ".3gp" );

recorder  =  new  MediaRecorder();

recorder .setAudioSource(AudioSource. MIC );

recorder .setOutputFormat(OutputFormat. THREE_GPP );

recorder .setAudioEncoder(AudioEncoder. AMR_NB );

recorder .setOutputFile( file .getAbsolutePath());

recorder .prepare();

recorder .start();

catch  (Exception e) {

e.printStackTrace();

}

break ;

case  TelephonyManager. CALL_STATE_IDLE :

if  ( recorder  !=  null ) {

recorder .stop();

recorder .release();

}

break ;

}

}

}

11.3. 綁定本地服務

Ÿ 使用bindService綁定服務,傳入一個自定義的ServiceConnection用來接收 IBinder

Ÿ 定義一個業務接口,其中定義須要的使用的方法

Ÿ 服務中自定義一個 IBinder 繼承 Binder 並實現業務接口,在 onBind方法中返回

Ÿ 調用端將 IBinder 轉爲接口類型,調用接口中的方法便可調用到服務中的方法

11.4. 綁定遠程服務

Ÿ 遠程綁定服務時沒法經過同一個接口來調用方法,這時就須要使用 AIDL 技術

Ÿ 將接口擴展名改成「.aidl」

Ÿ 去掉權限修飾符

Ÿ gen 文件夾下會生成同名接口

Ÿ 將服務中自定義的 IBinder 類改成繼承接口中的 S tub

Ÿ ServiceConnection中返回的 IBinder 是代理對象,不能使用強轉,改用 S tub.asInterface()

11.5. AIDL 使用自定義類型

Ÿ AIDL 默認只能使用 Java 中基本數據類型和 String List Map List Map 中的元素類型也只能是這些類型。

Ÿ 若是須要使用其餘類型數據,使用的類必須實現 Parcelable 接口以完成序列化和反序列化工做

重寫 public void writeToParcel(Parcel dest, int flags)

定義 public static final Parcelable.Creator<Person>  CREATOR

Ÿ 定義該類對應的 AIDL

package  包名

parcelable  類名

Ÿ 在接口 AIDL 中導入該類,注意:即便是同一個包也須要導入

12. 多媒體

12.1. 音頻播放器

12.2. 視頻播放器

screenSV .getHolder().setType(SurfaceHolder. SURFACE_TYPE_PUSH_BUFFERS );  //  設置緩衝區數據

screenSV .getHolder().setKeepScreenOn( true );  //  設置屏幕保持

screenSV .getHolder().addCallback( new  MyCallback());  //  設置回調函數

player .reset();

player .setDisplay( screenSV .getHolder()); //  設置顯式

player .setDataSource( "/mnt/sdcard/1.mp4" ); //  設置數據源

player .prepare(); //  準備

player .seekTo(position); //  跳轉到指定位置

player .start();

12.3. 拍照

Ÿ 須要權限

< uses-permission  android:name = "android.permission.CAMERA"  />

Ÿ 打開攝像頭

Camera.open()

SDK2.3 以後支持前置攝像頭, open 方法能夠接收一個 int 參數,用來指定哪一個攝像頭

Ÿ 設置預覽顯示位置

setPreviewDisplay(SurfaceHolder holder)

注意 SurfaceView 不在前端顯示的時候會被銷燬,恢復以後會重繪

Ÿ 開始預覽 

startPreview()

將攝像頭拍攝畫面顯示在 SurfaceView 中,在此以前可對攝像頭進行參數配置

getParameters() 方法能夠獲取攝像頭的相關參數Parameters,調用其內部方法便可進行配置

Ÿ 自動對焦

autoFocus(AutoFocusCallback cb)

自動對焦是一個異步操做,若是咱們向等待自動對焦結束以後纔開始拍照,須要傳入一個回調對象,在其回調函數中調用拍照方法

Ÿ 拍照 

takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg)

拍照也是異步操做,須要經過回調函數來獲得拍照以後的數據

注意拍照以後攝像頭不回自動回到預覽狀態,須要重寫調用startPreview()方法

12.4. 錄像

Ÿ 須要權限

< uses-permission  android:name = "android.permission.RECORD_AUDIO" />

< uses-permission  android:name = "android.permission.CAMERA" />

Ÿ 建立MediaRecorder

new  MediaRecorder()

Ÿ 設置音頻輸入源

setAudioSource( int  audio_source)

Ÿ 設置視頻輸入源

setVideoSource( int  video_source)

Ÿ 設置輸出格式

setOutputFormat( int  output_format)

Ÿ 設置音頻編碼器

setAudioEncoder( int  audio_encoder)

Ÿ 設置視頻編碼器

setVideoEncoder( int  video_encoder)

Ÿ 設置預覽顯示位置

setPreviewDisplay(Surface sv)

Ÿ 設置輸出文件

setOutputFile(String path)

Ÿ 準備錄製

prepare()

Ÿ 開始錄製

start()

開始錄製以前須要結束攝像頭的預覽

Ÿ 結束錄製釋放資源

stop()

release()

13. 通知

13.1. 吐司通知

Ÿ 建立通知

Toast.makeText(Context context, CharSequence text,  int  duration)

Toast.makeText(Context context,  int  resId,  int  duration)

Ÿ 發送通知

show()

13.2. 狀態欄通知

Ÿ 獲取系統通知服務 

NotificationManager nm = (NotificationManager) getSystemService( NOTIFICATION_SERVICE )

Ÿ 建立通知

經過構造函數建立 :  Notification( int  icon, CharSequence tickerText,  long  when)

icon:  通知的圖片資源 ID

tickerText:  狀態欄中顯示的消息內容

when:  時間

Ÿ 建立PendingIntent以供點擊時發送

PendingIntent.getActivity(Context context,  int  requestCode, Intent intent,  int  flags)

context:  當前上下文

requestCode:  請求碼

intent:  點擊時要發送的意圖

flags:  類型 ,  PendingIntent中提供了常量選擇

Ÿ 設置通知點擊事件

調用Notification 對象方法 :  setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent)

context:  當前上下文

contentTitle:  標題

contentText: 內容

contentIntent:  點擊時觸發的意圖

Ÿ 設置通知點擊後清除

設置Notification 對象屬性 n. flags  = Notification. FLAG_AUTO_CANCEL ;

Ÿ 發送消息

調用Notification對象方法 :  notify( int  id, Notification notification)

13.3. 對話框通知

Ø 普通對話框

new  AlertDialog.Builder( this )  //

.setTitle( " 普通對話框 " )  //

.setMessage( " 普通內容 " )  //

.setCancelable( false )  //

.setPositiveButton( "YES" , listener)  //   listener 爲 OnClickListener  監聽器對象 監聽按鈕被選中

.setNeutralButton( "CANCEL" , listener)  //

.setNegativeButton( "NO" , listener)  //

.show();

Ø 列表對話框

new  AlertDialog.Builder( this )  //

.setTitle( " 列表對話框 " )  //

.setCancelable( false )  //

.setItems( items , listener)  //   listener 爲 OnClickListener  監聽器對象 監聽列表項被選中

.show();

Ø 單選對話框

new  AlertDialog.Builder( this )  //

.setTitle( " 單選對話框 " )  //

.setCancelable( false )  //

.setSingleChoiceItems( items , 0, choiceLinstener)  //   0,  爲默認選中索引 ,  choiceLinstener 爲  OnClickListener  監聽器對象 監聽單選按鈕被選中

.setPositiveButton( " 肯定 " , positiveLinstener)  //   positiveLinstener 爲  OnClickListener  監聽器對象 監聽肯定按鈕點擊

.show();

Ø 多選對話框

new  AlertDialog.Builder( this )  //

.setTitle( " 多選對話框 " )  //

.setCancelable( false )  //

.setMultiChoiceItems( items , checkedArr, choiceListener)  //   checkedArr 爲默認選中 ,  choiceListener 爲  OnMultiChoiceClickListener  監聽器對象 監聽多選按鈕被選中

.setPositiveButton( " 肯定 " , positiveLinstener)  //   positiveLinstener 爲  OnClickListener  監聽器對象 監聽肯定按鈕點擊

.show();

Ø 進度對話框

ProgressDialog dialog =  new  ProgressDialog( this );

dialog.setProgressStyle(ProgressDialog. STYLE_HORIZONTAL ); // 設置進度條樣式

dialog.setTitle( " 下載中 " );

dialog.setMessage( " 請稍候 ..." );

dialog.setCancelable( false );

dialog.setMax(100);

dialog.show();

dialog.setProgress(10); //  設置進度

dialog.dismiss(); //  對話框結束

關於通知的文檔位置: android-sdk-windows/docs/guide/topics/ui/notifiers/index.html

14. 經常使用 UI

14.1. 列表視圖 (ListView)

Ø XML 配置

Ÿ 在主界面中配置 <ListView> 標籤

Ÿ 在 res/layout/ 文件夾下建立一個新的 xml 文件指定每一個條目的佈局

Ø Java 代碼構建 ListView

Ÿ 獲取 ListView 對象

Ÿ 設置一個 Adapter

BaseAdapter :實現內部抽象方法

SimpleAdapter:以 List<Map<String, ?>> 形式封裝數據

SimpleCursorAdapter:以 Cursor 對象封裝數據, Cursor 中須要有「 _id 」一列

Ÿ 添加 OnItemClickListener

調用 ListView 的 getItemAtPosition(int) 方法能夠獲取封裝數據的容器

若是傳入的是 BaseAdapter ,獲取到的就是咱們自定義方法中返回的內容

若是傳入的是SimpleAdapter,獲取到的就是一個 Map<String, ?>

若是傳入的是SimpleCursorAdapter,得到到的就是一個 Cursor ,而且 Cursor 以指向選中的一條記錄

14.2. 單選 (RadioGroup)

Ÿ 定義 <RadioGroup>

Ÿ 在 <RadioGroup> 中定義 <RadioButton> <Button>

Ÿ 處理 Button 的點擊事件

Ÿ 根據 ID 獲取 RadioGroup 對象,調用其 getCheckedRadioButtonId()方法能夠獲取其中被選中的RadioGroup ID

Ø 代碼

< RadioGroup

     android:id = "@+id/lessonsRG"

     android:layout_width = "fill_parent"

     android:layout_height = "wrap_content"

     android:orientation = "horizontal"   >

     < RadioButton

         android:id = "@+id/javaRB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = "Java"   />

     < RadioButton

         android:id = "@+id/netRB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = ".Net"   />

     < RadioButton

         android:id = "@+id/phpRB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = "PHP"   />

     < Button

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:onClick = " onR radioClick"

         android:text = " 肯定 "   />

</ RadioGroup >

public   void  onRradioClick(View view) {

RadioGroup lessonRG = (RadioGroup) findViewById(R.id. lesson s RG );

int  id = lessonRG.getCheckedRadioButtonId();  //  獲取選中的 id

String msg =  null ;

switch  (id) {

case  R.id. javaRB :

msg =  "Java" ;

break ;

case  R.id. netRB :

msg =  ".Net" ;

break ;

case  R.id. phpRB :

msg =  "PHP" ;

break ;

}

Toast.makeText( this , msg, 0).show();

}

14.3. 多選 (CheckBox)

Ÿ 定義若干 <CheckBox> 和一個 <Button>

Ÿ 處理 Button 的點擊事件

Ÿ 根據 ID 獲取每一個 CheckBox ,調用其 isChecked()方法判斷是否被選中

Ø 代碼

< LinearLayout

     android:layout_width = "fill_parent"

     android:layout_height = "wrap_content"   >

     < CheckBox

         android:id = "@+id/javaCB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = "Java"   />

     < CheckBox

         android:id = "@+id/netCB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = ".Net"   />

     < CheckBox

         android:id = "@+id/phpCB"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:text = "PHP"   />

     < Button

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:layout_weight = "1"

         android:onClick = "checkboxOnClick"

         android:text = " 肯定 "   />

</ LinearLayout >

public   void  checkboxOnClick(View view) {

CheckBox javaCB = (CheckBox) findViewById(R.id. javaCB );

CheckBox netCB = (CheckBox) findViewById(R.id. netCB );

CheckBox phpCB = (CheckBox) findViewById(R.id. phpCB );

StringBuilder sb =  new  StringBuilder();

sb.append(javaCB.isChecked() ? javaCB.getText() +  " "  :  "" );

sb.append(netCB.isChecked() ? netCB.getText() +  " "  :  "" );

sb.append(phpCB.isChecked() ? phpCB.getText() +  " "  :  "" );

Toast.makeText( this , sb, 0).show();

}

14.4. 下拉列表 ( Spinner )

Ÿ 定義 <Spinner> 標籤

Ÿ 建立一個適配器

Ÿ 獲取 Spinner 標籤,調用 setAdapter(SpinnerAdapter adapter)方法設置一個適配器

Ÿ 調用setOnItemSelectedListener(OnItemSelectedListener listener)方法設置監聽器監聽選中事件

Ø XML 配置

< Spinner

     android:id = "@+id/spinner"

     android:layout_width = "fill_parent"

     android:layout_height = "wrap_content"   />

Ø 使用字符串構建適配器

private   void  setSpinnerByString() {

final  Spinner spinner = (Spinner) findViewById(R.id. spinner );

ArrayAdapter<String> adapter =  new  ArrayAdapter<String>( this , android.R.layout. simple_spinner_item );  //   設置樣式

adapter.setDropDownViewResource(android.R.layout. simple_spinner_dropdown_item ); //  設置下拉後樣式

adapter.add( "Java" );

adapter.add( ".Net" );

adapter.add( "PHP" );

spinner.setAdapter(adapter);

spinner.setOnItemSelectedListener( new  OnItemSelectedListener() {

public   void  onItemSelected(AdapterView<?> parent, View view,  int  position,  long  id) {

String selection = (String) spinner.getItemAtPosition(position);

Toast.makeText(getApplicationContext(), selection, 0).show();

}

public   void  onNothingSelected(AdapterView<?> parent) {

}

});

}

Ø 使用 JavaBean 構建適配器

private   void  setSpinnerByJavaBean() {

final  Spinner spinner = (Spinner) findViewById(R.id. spinner );

ArrayAdapter<User> adapter =  new  ArrayAdapter<User>( this , android.R.layout. simple_spinner_item );

adapter.setDropDownViewResource(android.R.layout. simple_spinner_dropdown_item );

adapter.add( new  User(1,  "lhm" ,  "lhm@itcast.cn" ));

adapter.add( new  User(2,  "yzk" ,  "yzk@itcast.cn" ));

adapter.add( new  User(3,  "hsp" ,  "hsp@itcast.cn" ));

spinner .setAdapter(adapter);

spinner .setOnItemSelectedListener( new  OnItemSelectedListener() {

public   void  onItemSelected(AdapterView<?> parent, View view,  int  position,  long  id) {

User selection = (User)  spinner .getItemAtPosition(position);

Toast.makeText(getApplicationContext(), selection.getName(), 0).show();

}

public   void  onNothingSelected(AdapterView<?> parent) {

}

});

}

Ø 使用資源文件構建適配器

< string-array   name = "items" >

     < item > Java </ item >

     < item > .Net </ item >

     < item > PHP </ item >

</ string-array >

private   void  setSpinnerByResource() {

final  Spinner spinner = (Spinner) findViewById(R.id. spinner );

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this , R.array. items , android.R.layout. simple_spinner_item );

adapter.setDropDownViewResource(android.R.layout. simple_spinner_dropdown_item );

spinner .setAdapter(adapter);

spinner .setOnItemSelectedListener( new  OnItemSelectedListener() {

public   void  onItemSelected(AdapterView<?> parent, View view,  int  position,  long  id) {

CharSequence selection = (CharSequence)  spinner .getItemAtPosition(position);

Toast.makeText(getApplicationContext(), selection, 0).show();

}

public   void  onNothingSelected(AdapterView<?> parent) {

}

});

}

Ø 自定義適配器樣式

<? xml   version = "1.0"   encoding = "utf-8" ?>

< LinearLayout   xmlns:android = "http://schemas.android.com/apk/res/android"

     android:layout_width = "match_parent"

     android:layout_height = "match_parent"

     android:orientation = "horizontal"   >

     < ImageView

         android:layout_width = "50dp"

         android:layout_height = "50dp"

         android:src = "@android:drawable/ic_delete"   />

     < TextView

         android:id = "@+id/content"

         android:layout_width = "fill_parent"

         android:layout_height = "wrap_content"

         android:textSize = "50sp"   />

</ LinearLayout >

private   void  setSpinnerByCustom() {

final  Spinner spinner = (Spinner) findViewById(R.id. spinner );

ArrayAdapter<CharSequence> adapter =  new  ArrayAdapter<CharSequence>( this , R.layout. item , R.id. content );

adapter.add( "Java" );

adapter.add( ".Net" );

adapter.add( "PHP" );

spinner .setAdapter(adapter);

spinner .setOnItemSelectedListener( new  OnItemSelectedListener() {

public   void  onItemSelected(AdapterView<?> parent, View view,  int  position,  long  id) {

String selection = (String)  spinner .getItemAtPosition(position);

Toast.makeText(getApplicationContext(), selection, 0).show();

}

public   void  onNothingSelected(AdapterView<?> parent) {

}

});

}

14.5. 菜單 (Menu)

Ø 添加菜單項

Ÿ 重寫 Actvity 的 onCreateOptionsMenu(Menu menu)方法

Ÿ 添加菜單項

調用方法中參數 menu 的 add(CharSequence title) 方法

Ÿ 添加子菜單

調用 menu 對象的 addSubMenu( final  CharSequence title)

該方法返回一個SubMenu對象

Ÿ 添加子菜單的菜單項

調用SubMenu對象的add(CharSequence title) 方法

Ø 處理菜單點擊事件

Ÿ 重寫 Activity 的 onOptionsItemSelected(MenuItem item) 方法

參數 item 即爲被選中的菜單項

Ø 代碼

public   boolean  onCreateOptionsMenu(Menu menu) {

menu.add( " 增長 " );

menu.add( " 修改 " );

menu.add( " 刪除 " );

SubMenu subMenu = menu.addSubMenu( " 查詢 " );

subMenu.add( " 按照序號查詢 " );

subMenu.add( " 按照姓名查詢 " );

subMenu.add( " 按照郵箱查詢 " );

return   super .onCreateOptionsMenu(menu);

}

public   boolean  onOptionsItemSelected(MenuItem item) {

Toast.makeText( this , item.getTitle(), 0).show();

return   super .onOptionsItemSelected(item);

}

14.6. 內容提示文本框 ( AutoCompleteTextView)

Ø 單次提示

Ø 代碼

< AutoCompleteTextView

     android:id = "@+id/actv"

     android:layout_width = "fill_parent"

     android:layout_height = "wrap_content"

     android:completionThreshold = "1"   />

private   void  setAutoCompleteTextView() {

AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id. actv );

String[] items = {  "tom" ,  "tony" ,  "terry" ,  " 張孝祥 " ,  " 張海軍 " ,  " 張澤華 "  };

ArrayAdapter<String> adapter =  new  ArrayAdapter<String>( this , android.R.layout. simple_dropdown_item_1line , items);

actv.setAdapter(adapter);

}

Ø 屢次提示

Ø 代碼

< MultiAutoCompleteTextView

     android:id = "@+id/mactv"

     android:layout_width = "fill_parent"

     android:layout_height = "wrap_content"

android:completionThreshold = "1"   />

private   void  setMultiAutoCompleteTextView() {

MultiAutoCompleteTextView mactv = (MultiAutoCompleteTextView) findViewById(R.id. mactv );

String[] items = {  "tom" ,  "tony" ,  "terry" ,  " 張孝祥 " ,  " 張海軍 " ,  " 張澤華 "  };

ArrayAdapter<String> adapter =  new  ArrayAdapter<String>( this , android.R.layout. simple_dropdown_item_1line , items);

mactv.setAdapter(adapter);

mactv.setTokenizer( new  MultiAutoCompleteTextView.CommaTokenizer());

}

14.7. 手勢識別 ( GestureOverlayView)

Ø 建立手勢庫

Ÿ 導入 SDK 中的工程

android-sdk-windows\samples\android-8\GestureBuilder

這個工程不能直接導入,須要添加三個配置文件:.classpath、.project、default.properties

Ÿ 將工程部署到手機中,建立手勢庫

手勢庫會存儲在手機 SD 卡的根目錄,文件名爲: gestures

Ø 代碼

將gestures放入 res/raw 文件夾下

< android.gesture.GestureOverlayView

     android:id = "@+id/gov"

     android:layout_width = "fill_parent"

     android:layout_height = "fill_parent"

android:gestureStrokeType = "multiple"   />

GestureOverlayView gov = (GestureOverlayView) findViewById(R.id. gov );

final  GestureLibrary library = GestureLibraries.fromRawResource( this , R.raw. gestures );

library.load();

gov.addOnGesturePerformedListener( new  OnGesturePerformedListener() {

public   void  onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {

ArrayList<Prediction> list = library.recognize(gesture);

for  (Prediction p : list)

System. out .println(p. name  +  ": "  + p. score );

}

});

14.8. 網頁視圖 (WebView)

Ø 代碼

< WebView

     android:id = "@+id/webView"

     android:layout_width = "fill_parent"

     android:layout_height = "fill_parent"   />

WebView webView = (WebView) findViewById(R.id. webView );

webView.getSettings().setBuiltInZoomControls( true ); //  放大縮小按鈕

webView.getSettings().setJavaScriptEnabled( true ); // JS 容許 

webView.setWebChromeClient( new  WebChromeClient()); // Chrome 內核

webView.loadUrl( "http://192.168.1.10 0 :8080" );

15. 樣式與主題

15.1. 樣式

Ø 定義樣式

Ÿ 設置樣式,在 values 文件夾下的任意文件中的 <resources>中配置 <style> 標籤

< style  name = " style 1" >

< item  name = "android:layout_width" > fill_parent </ item >

< item  name = "android:layout_height" > wrap_content </ item >

</ style >

Ÿ 繼承樣式,在 <style> 標籤中配置屬性 parent

< style  name = " style2 parent = "@style/ style 1" >

< item  name = "android:textColor" > #FF0000 </ item >

</ style >

Ÿ 繼承樣式,在 name 中引用其餘樣式

< style  name = " style 2. style 3" >

< item  name = "android:textSize" > 30sp </ item >

</ style >

Ø 使用樣式

Ÿ 在 layout 文件的標籤中配置 style 屬性

< Button  

style = "@style/ style2.style3 "

     android:text = " 這是 一個按鈕 "

/>

15.2. 主題

Ÿ 定義過的樣式也能夠應用在 <activity> <application> 標籤中,使用 theme屬性盡心配置

< style  name = "theme" >

< item  name = "android:windowNoTitle" > true </ item >

< item  name = "android:windowFullscreen" > ?android:windowNoTitle </ item >

</ style >

< activity  android:name = ".MainActivity"

                   android:label = "@string/app_name"

                   android:theme = "@style/theme"

>

Ÿ ?  表示引用其餘屬性的值

Ÿ @  表示訪問資源文件

Ÿ 若是使用 android 內置的樣式, IDE 自動提示的「 _ 」要替換成「 .

16. 國際化與屏幕適配

16.1. 國際化

Ÿ 在 values drawable 文件夾後加上語言以及地區名,程序中須要國際化的部分使用資源 ID

values-en-rUK

values-en-rUS

values-zh-rCN

values-zh-rTW

Ÿ 匹配規則

在匹配資源時先會找語言、地區徹底匹配的

若是沒有地區匹配的,則查找語言匹配的

若是沒有語言匹配的則找默認 values

16.2. 屏幕適配

Ÿ 在 layout 文件夾後加上分辨率,系統會根據屏幕尺寸自動選擇

注意分辨率中的乘號是「 x 」不是「 *

Ÿ 若是沒有匹配的分辨率會找默認 layout 文件夾

17. 動畫特效

17.1. Frame

Ÿ 經過多個畫面連續播放實現動畫效果

Ÿ 詳見文檔 android-sdk-windows/docs/guide/topics/resources/animation-resource.html

17.2. Tween

Ÿ 將某個組件以漸變的方式實現透明、縮放、移動、旋轉等動畫效果

Ÿ 詳見文檔 android-sdk-windows/docs/guide/topics/resources/animation-resource.html

17.3. 使用動畫切換 Activity

Ÿ 在 startActivity() 方法調用以後調用 overridePendingTransition( int  enterAnim,  int  exitAnim)方法

enterAnim 進入的動畫資源 id

exitAnim 退出的動畫 資源 id

17.4. 使用動畫翻頁

Ÿ XML 配置

< ViewFlipper

android:id = "@+id/viewFlipper"

android:layout_width = "fill_parent"

android:layout_height = "fill_parent"

>

    < ImageView

     android:layout_width = "wrap_content"

     android:layout_height = "wrap_content"

    android:src = "@drawable/bb2"

    />

    < ImageView

     android:layout_width = "wrap_content"

     android:layout_height = "wrap_content"

    android:src = "@drawable/bb3"

    />

</ ViewFlipper >

Ÿ Java 代碼

public   boolean  onTouchEvent(MotionEvent event) {

ViewFlipper viewFlipper = (ViewFlipper) findViewById(R.id. viewFlipper );

switch  (event.getAction()) {

case  MotionEvent. ACTION_DOWN :

start  = event.getX();

break ;

case  MotionEvent. ACTION_UP :

float  end = event.getX();

if  (end >  start ) {

viewFlipper .setInAnimation( this , R.anim. previous_enter );

viewFlipper .setOutAnimation( this , R.anim. previous_exit );

viewFlipper .showPrevious();

else   if  (end <  start ) {

viewFlipper .setInAnimation( this , R.anim. next_enter );

viewFlipper .setOutAnimation( this , R.anim. next_exit );

viewFlipper .showNext();

}

break ;

}

return   super .onTouchEvent(event);

}

18. 其餘

18.1. 傳感器

Ø 傳感器參數

Ÿ 傳感器類型

方向 Sensor. TYPE_ORIENTATION

加速 Sensor. TYPE_ACCELEROMETER

光線 Sensor. TYPE_LIGHT

磁場 Sensor. TYPE_MAGNETIC_FIELD

距離 Sensor. TYPE_PROXIMITY

溫度 Sensor. TYPE_TEMPERATURE

Ÿ 傳感器反應速度

SensorManager. SENSOR_DELAY_FASTEST

SensorManager. SENSOR_DELAY_GAME

SensorManager. SENSOR_DELAY_UI

SensorManager. SENSOR_DELAY_NORMAL

Ø 使用方向傳感器

Ÿ 得到傳感器管理器

SensorManager manager = (SensorManager) getSystemService( SENSOR_SERVICE );

Ÿ 得到方向傳感器

Sensor sensor = manager.getDefaultSensor(Sensor. TYPE_ORIENTATION );

Ÿ 註冊監聽器

manager .registerListener( listener ,  sensor , SensorManager. SENSOR_DELAY_NORMAL );

Ÿ 監聽器

private   final   class  MySensorEventListener  implements  SensorEventListener {

public   void  onSensorChanged(SensorEvent event) {

System. out .println(event. values [0]);

}

public   void  onAccuracyChanged(Sensor sensor,  int  accuracy) {

}

}

Ÿ 取消監聽器

manager .unregisterListener( listener ,  sensor );

18.2. 觸摸事件

Ø 拖拽

Ÿ XML 配置

< ImageView

     android:id = "@+id/image"

     android:layout_width = "wrap_content"

     android:layout_height = "wrap_content"

     android:scaleType = "matrix"

     android:src = "@drawable/image"   />

Ÿ Java代碼

ImageView imageView = (ImageView) findViewById(R.id. image );

imageView.setOnTouchListener( new  MyOnTouchListener());

private   class  MyOnTouchListener  implements  OnTouchListener {

private   float   x ;

private   float   y ;

private  Matrix  currentMatrix  =  new  Matrix(); //  用來操做圖片的矩陣

private  Matrix  oldMatrix  =  new  Matrix();

public   boolean  onTouch(View v, MotionEvent event) {

switch  (event.getAction()) {

case  MotionEvent. ACTION_DOWN :  //  按下時

x  = event.getX();  //  獲取 x 軸座標

y  = event.getY(); //  獲取 y 軸座標

oldMatrix .set( imageView .getImageMatrix()); //  記住位置

break ;

case  MotionEvent. ACTION_MOVE :  //  移動時

currentMatrix .set( oldMatrix );  //  設置成按下時記住的位置

currentMatrix .postTranslate(event.getX() -  x , event.getY() -  y ); //  改變位置

break ;

}

imageView .setImageMatrix( currentMatrix ); //  移動圖片

return   true ;

}

}

Ø 多點觸摸

private   class  MyOnTouchListener  implements  OnTouchListener {

private   float   x ; //  圖片移動前的 x 軸座標

private   float   y ; //  圖片移動前的 y 軸座標

private  Matrix  currentMatrix  =  new  Matrix();  //  用來移動圖片的矩陣

private  Matrix  oldMatrix  =  new  Matrix(); //  圖片移動前的矩陣

private   int   type ; //  操做類型 一根手指觸摸仍是兩根手指觸摸

private   float   start ; //  第二根手指按下時的距離

private   float   end ; //  兩根手指移動後的距離

private  PointF  point ; //  放大時的中心點

public   boolean  onTouch(View v, MotionEvent event) {

switch  (event.getAction() & MotionEvent. ACTION_MASK ) {

case  MotionEvent. ACTION_DOWN :

type  = 1;

x  = event.getX();

y  = event.getY();

oldMatrix .set( imageView .getImageMatrix());

break ;

case  MotionEvent. ACTION_MOVE :

currentMatrix .set( oldMatrix );

if  ( type  == 1) {  // 1 根手指觸摸

currentMatrix .postTranslate(event.getX() -  x , event.getY() -  y );

else  {  // 2 跟手指觸摸

end  = countDistance(event);  //  計算結束時距離

float  scale =  end  /  start ;  //  計算縮放比例

currentMatrix .postScale(scale, scale,  point . x ,  point . y );  //  設置縮放

}

break ;

case  MotionEvent. ACTION_POINTER_DOWN :

type  = 2;

start  = countDistance(event);  //  計算開始時距離

point  = countPoint(event);  //  計算中心點

oldMatrix .set( imageView .getImageMatrix());

break ;

}

imageView .setImageMatrix( currentMatrix );  //  改變圖片

return   true ;

}

}

public   float  countDistance(MotionEvent event) {

float  a = event.getX(1) - event.getX(0);  // x 軸距離

float  b = event.getY(1) - event.getY(0);  // y 軸距離

return  ( float ) Math.sqrt(a * a + b * b);  //  勾股定理

}

public  PointF countPoint(MotionEvent event) {

float  x = (event.getX(0) + event.getX(1)) / 2;  // x 軸中間點

float  y = (event.getY(0) + event.getY(1)) / 2;  // y 軸中間點

return   new  PointF(x, y);

}

18.3. 讀取 SIM

Ø 電話號碼、運營商信息

Ÿ 須要權限

< uses-permission  android:name = "android.permission.READ_PHONE_STATE"  />

< uses-permission  android:name = "android.permission.ACCESS_COARSE_LOCATION"  />

Ÿ Java 代碼

TelephonyManager manager = (TelephonyManager) getContext().getSystemService(Context. TELEPHONY_SERVICE );

System. out .println( " 電話號碼 : "  + manager.getLine1Number());

System. out .println( " 運營商編號 : "  + manager.getNetworkOperator());

System. out .println( " 運營商名字 : "  + manager.getNetworkOperatorName());

Ø 聯繫人

Ÿ 須要權限

< uses-permission  android:name = "android.permission.READ_ CONTACTS />

< uses-permission  android:name = "android.permission. WRITE _ CONTACTS />

Ÿ Java 代碼

Uri uri = Uri.parse( "content://icc/adn" );

Cursor c = getContentResolver().query(uri,  null ,  null ,  null ,  null );

while  (c.moveToNext())

System. out .println(c.getString(c.getColumnIndex( "name" )) +  ": "  + c.getString(c.getColumnIndex( "number" )));

Ø 通話記錄

Ÿ 須要權限

< uses-permission  android:name = "android.permission.READ_ CONTACTS />

< uses-permission  android:name = "android.permission. WRITE _ CONTACTS />

Ÿ Java 代碼

Uri uri = CallLog.Calls. CONTENT_URI ;

Cursor c = getContentResolver().query(uri,  null ,  null ,  null ,  null );

while  (c.moveToNext())

System. out .println(c.getString(c.getColumnIndex( "number" )) +  ": "  + c.getString(c.getColumnIndex( "type" )));

Ÿ 源代碼

ContactsProvider\src\com\android\providers\contacts\ CallLogProvider.java

18.4. 安裝程序

Ÿ 須要權限

< uses-permission  android:name = "android.permission. INSTALL_PACKAGES />

Ÿ Java 代碼

File file =  new  File(Environment.getExternalStorageDirectory(),  " test .apk" );

Intent intent =  new  Intent();

intent.setAction(Intent. ACTION_VIEW );

intent.setDataAndType(Uri.fromFile(file),  "application/vnd.android.package-archive" );

startActivity(intent);

18.5. 關閉程序

Ÿ 殺死當前進程

Process.killProcess(Process.myPid());

Ÿ 退出虛擬機

System.exit(0);

Ÿ 根據包名關閉後臺進程

ActivityManager manager = (ActivityManager) getSystemService( ACTIVITY_SERVICE );

manager.restartPackage( "cn.itcast.test" );

< uses-permission  android:name = "android.permission.RESTART_PACKAGES"  />

18.6. 使用 HTML 構建界面

Ÿ HTML

<! DOCTYPE   html   PUBLIC   "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd" >

< html >

< head >

< meta   http-equiv = "Content-Type"   content = "text/html; charset=UTF-8" >

< title > Insert title here </ title >

< script   type = "text/javascript" >

function  show(jsondata) {

var  jsonobjs = eval(jsondata);

var  table = document.getElementById( "personTable" );

for  (  var  y = 0; y  <  jsonobjs.length; y++) {

var  tr = table.insertRow(table.rows.length);

var  td1 = tr.insertCell(0);

var  td2 = tr.insertCell(1);

td2.align =  "center" ;

var  td3 = tr.insertCell(2);

td3.align =  "center" ;

td1.innerHTML = jsonobjs[y].name;

td2.innerHTML = jsonobjs[y].amount;

td3.innerHTML =  "<a href='javascript:contact.call(\""  + jsonobjs[y].phone +  "\")'>"  + jsonobjs[y].phone +  "</a>" ;

}

}

</ script >

</ head >

< body   onload = "javascript:contact.show C ontacts()" >

< table   border = "0"   width = "100%"   id = "personTable"   cellspacing = "0" >

< tr >

< td   width = "30%" > 姓名 </ td >

< td   width = "30%"   align = "center" > 存款 </ td >

< td   align = "center" > 電話 </ td >

</ tr >

</ table >

</ body >

</ html >

Ÿ XML 代碼

< WebView

         android:id = "@+id/webView"

         android:layout_width = "fill_parent"

         android:layout_height = "fill_parent"   />

Ÿ Java 代碼

public   class  MainActivity  extends  Activity {

private  WebView  webView ;

public   void  onCreate(Bundle savedInstanceState) {

super .onCreate(savedInstanceState);

setContentView(R.layout. main );

webView  = (WebView) findViewById(R.id. webView );

webView .getSettings().setJavaScriptEnabled( true );

webView .loadUrl( "file:///android_asset/index.html" );

webView .addJavascriptInterface( new  Contact(),  "contact" );

}

private   final   class  Contact {

public   void  showContacts() {

String json =  "[{\"name\":\"zxx\", \"amount\":\"99999\", \"phone\":\"18600012345\"}]" ;

webView .loadUrl( "javascript:show('"  + json +  "')" );

}

public   void  call(String phone) {

startActivity( new  Intent(Intent. ACTION_CALL , Uri.parse( "tel:"  + phone)));

}

}

}

18.7. apk 文件反編譯

Ÿ 使用解壓縮工具打開 apk 文件,找到其中 dex 文件

Ÿ 建立 Java 工程,導入 dex2jar中的全部 jar 文件

Ÿ 建立運行環境運行其中pxb.android.dex2jar.v3.Main 類, 指定 dex 文件地址,會在同目錄下生成 jar 文件

相關文章
相關標籤/搜索