必須總是activity中內(nèi)嵌fragment對象
service運行在后臺,運行時間不限,不提供界面
分為本地service和遠程service帆焕。
不能在service主線程執(zhí)行好事操作
所有的服務都在抽象類 android.app.Service 的子類中帖旨,而 android.app.Service 類則是
Context 的間接子類。
一彬呻、用戶界面范例
1.自定義窗口
系統(tǒng)主題或自定義主題都必須在清單文件中設置衣陶。
所有通過 Activity.requestWindowFeature()方法修改窗口特性的請求都必須在調(diào)用
Activity.setContentView()之前完成柄瑰。在此之后的所有改動都不會生效。
//設置自定義標題的布局資源
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.custom_title);
2.動態(tài)開關系統(tǒng)的UI控件
夜間模式 API Level 11
任何視圖中調(diào)用 setSystemUiVisibility()
即可剪况。而想要恢復到默認模式教沾,需要以同樣的方式調(diào)用 SYSTEM_UI_FLAG_VISIBLE。通
過調(diào)用 getSystemUiVisibility()并檢查標識的當前狀態(tài)就可以知道我們現(xiàn)在所處的模式了译断。
XML 布局文件中的根元素是 LayoutInflater. inflate()返回的 View 元素
3.屏幕分辨率
低分辨率(ldpi): 120 dpi 尺寸是 mdpi 的 75%
中分辨率(mdpi): 160 dpi 原始的圖片尺寸
高分辨率(hdpi): 240 dpi 尺寸是 mdpi 的 150%
超高分辨率(xhdpi): 320 dpi (API Level 8 新增) 尺寸是 mdpi 的 200%
超級高(xxhdpi): 480 dpi (API Level 16 新增) 尺寸是 mdpi 的 300%
4.鎖定Activity方向
android:screenOrientation="portrait"或 android:screenOrientation="landscape"
如果為 Activity 設置了 android:screenOrientation="behind"授翻, Activity 就會跟 Activity 棧中前一個 Activity 的方向保持一致
android:configChanges="orientation|keyboardHidden" />
在一條賦值語句中可以注冊多種變動,用“ |”符號將它們分開即可孙咪。
5.彈出菜單
也可以調(diào)用 Activity.openContextMenu()來觸發(fā)任意視圖的 ContextMenu堪唐,傳入之前注
冊的視圖即可。
程序清單 2-29 自定義布局的 AlertDialog
public class CustomItemActivity extends Activity
implements DialogInterface.OnClickListener, View.OnClickListener {
private static final String[] ZONES = {"Pacific Time", "Mountain Time",
"Central Time", "Eastern Time", "Atlantic Time"};
private static final String[] OFFSETS =
{"GMT-08:00", "GMT-07:00", "GMT-06:00", "GMT-05:00", "GMT-04:00"};
Button mButton;
AlertDialog mActions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Activity");
mButton = new Button(this);
mButton.setText("Click for Time Zones");
mButton.setOnClickListener(this);
ArrayAdapter adapter = new ArrayAdapter(this,
R.layout.list_item) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row == null) {
row = getLayoutInflater().inflate(R.layout.list_item,
parent, false);
}
TextView name = (TextView) row.findViewById(R.id.text_name);
TextView detail = (TextView) row.findViewById(R.id.text_detail);
name.setText(ZONES[position]);
detail.setText(OFFSETS[position]);
return row;
}
@Override
public int getCount() {
return ZONES.length;
}};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Time Zone");
builder.setAdapter(adapter, this);
//這里的取消動作只會讓對話框消失翎蹈,但在用戶單擊 Cancel 按鈕時淮菠,也可以添加一個
//監(jiān)聽器來處理一些其他的操作
builder.setNegativeButton("Cancel", null);
mActions = builder.create();
setContentView(mButton);
}
//這里處理列表的選擇事件
@Override
public void onClick(DialogInterface dialog, int which) {
String selected = ZONES[which];
mButton.setText(selected);
}
//這里處理 Button 的單擊事件(彈出對話框)
@Override
public void onClick(View v) {
mActions.show();
}
}
6.模擬home鍵
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
7.TextView
SDK 中有一些很方便的預定義的用于格式化文本輸入的 TextWatcher 實例
8.動畫
Android SDK的AnimationUtils 類加載
滑入和漸顯AnimationUtils.makeInAnimation()用布爾參數(shù)決定滑入的方向是左側還是右側向上
滑入和漸顯 AnimationUtils.makeInChildBottomAnimation() 視圖總是從屏幕的底部向上滑入
滑出和漸隱 AnimationUtils.makeOutAnimation() 用布爾參數(shù)決定滑入的方向是左側還是右側
漸隱 AnimationUtils.loadAnimation() 將 int 參數(shù)設為 android.R.anim.fade_out
漸顯 AnimationUtils.loadAnimation() 將 int 參數(shù)設為 android.R.anim.fade_in
AlphaAnimation 以動畫的定時改變視圖的透明度。
RotateAnimation 以動畫的形式改變視圖的旋轉角度荤堪。中心點是可配置的兜材,默認是左上角。
ScaleAnimation 以動畫的形式改變視圖的縮放比例(大小)逞力。中心點是默認是左上角曙寡。
TranslateAnimation 以動畫的形式改變視圖的位置。
動畫視圖 ViewPropertyAnimator
ObjectAnimator
在 XML 中用標簽定義 Drawable 時寇荧,實際上是創(chuàng)建了一個 GradientDrawable
對象举庶。對象的形狀可以是矩形、橢圓揩抡、線條或圓圈户侥,最常見的背景形狀是矩形杜恰。具體來說奴烙,
在使用矩形時致稀,可以用下面這些參數(shù)定義形狀:
● 角半徑 定義 4 個角的半徑薛匪,或是分別定義各個角的半徑。
● 漸變 線性和橙、放射或 sweep 漸變汪茧。兩個或三個顏色值螟蝙。方向可以是 45°的任何倍數(shù)(0 就是從左到右装黑, 90 就是從下到上副瀑,以此類推)。
● 固定顏色 用一種顏色填充形狀恋谭。 如果同時定義了漸變的話糠睡,效果會受影響。
● 邊線 對象形狀的邊界疚颊。 定義寬度和顏色狈孔。
● 大小和 padding
XML 中顏色的種類限制是 3 種信认,但是 GradientDrawable 的構造函數(shù)中的顏色參數(shù)是一個整型數(shù)組int[],傳遞多少顏色都可以均抽。
Activity 間的過渡動畫嫁赏, 可以使用 overridePendingTransition()
Fragment 的過渡動畫,可以使用 onCreateAnimation()或 onCreateAnimator()
通過調(diào)用 setCustomAnimations()覆寫單個 FragmentTransaction 的
過渡動畫到忽。
setCustomAnimations()必須在 add()、 replace()和其他動作方法之前調(diào)用清寇,否則動畫將不
會運行喘漏。
9.圓角遮罩
首先在 Canvas 中根據(jù)所需的圓角半徑創(chuàng)建一個圓角矩形,然后以 PorterDuff.Mode.SRC_IN 為畫筆在同一個 Canvas 上繪制源圖华烟,得到的就是帶圓角的源圖翩迈。
10.Dialog
呈現(xiàn)給用戶的界面需要在旋轉過程中保持狀態(tài),始終處于最前端盔夜,更好的辦法是
使用 Activity负饲。這樣就可以通過各種生命周期回調(diào)方法來保存和讀取狀態(tài)。
11.自定義Enter鍵
android:imeOptions
actionUnspecified:默認值喂链,根據(jù)設備的情況顯示動作返十。
actionGo:在 Enter 鍵上顯示 Go。
ActionSearch:在 Enter 鍵上顯示 Search椭微。
actionSend:在 Enter 鍵上顯示 Send洞坑。
antionNext:在 Enter 鍵上顯示 Next。
actionDone:在 Enter 鍵上顯示 Done蝇率。
自定義用戶按下按鍵時所觸發(fā)的動作迟杂。重
載動作的默認行為需要給相應的視圖加上 TextView.OnEditorActionListener。
用 InputMethodManager.hideSoftInputFromWindow()方法可以讓輸入法管理器隱藏可見
的輸入法本慕。
12.listview
ExpandableListView 控件及其適配器可以處理分節(jié)列表中的二維數(shù)據(jù)結構排拷。
13.getPageWidth()。
這個方法允許你在每個位置上設置圖片頁面大小相對于 ViewPager 頁面大小的百分比锅尘。默
認值為 1监氢,前面的示例也沒有改變該默認值。但如果要一次顯示幾個頁面藤违,可以通過調(diào)整
這個方法的返回值來實現(xiàn)
二忙菠、顯示web信息
1.通過url顯示的應用
訪問XX網(wǎng)站
通過web服務器顯示實時更新的頁面,可以動態(tài)更新
顯示大資源圖片纺弊,通過縮放來交互
2.顯示本地資源
可用assets目錄存儲本地資源 file:///android_asset
可顯示string資源或變量中的原始html代碼
3.通過WebviewClient攔截事件
WebViewClient.shouldOverrideUrlLoading()回調(diào)來攔截和監(jiān)控用戶的 Activity
shouldOverrideUrlLoading()會根據(jù)傳入的 URL 決定是否要在 WebView 中加
載內(nèi)容牛欢, 防止用戶離開想要展示 的網(wǎng)站。
WebView.addJavascriptInterface()會為 JavaScript 綁定一個 Java 對象淆游,這樣就可以在
WebView 中調(diào)用 Java 的方法傍睹。會存在javascript注入問題
4.下載圖片
完全在后臺下載使用DownloadManager API service 支持斷點續(xù)傳
DownloadManager.Request 請求對象隔盛,它代表了下載的內(nèi)容
Request.setAllowedNetworkTypes():指定下載所使用的網(wǎng)絡類型
Request.setAllowedOverRoaming():設定當設備處于漫游模式時是否要下載。
Request.setDescription():設置下載在系統(tǒng)通知欄中顯示的描述拾稳。
Request.setDestinationInExternalFilesDir():設置目標位置為外部存儲器中的一個隱藏目錄
Request.setDestinationInExternalPublicDir():設置目標位置為外部存儲器中的一公共目錄
Request.setDestinationUri():設置目標位置為位于外部存儲器中一個文件 Uri
三吮炕。通信
1.接收短信
注冊一個 BroadcastReceiver 來監(jiān)聽收到的消息,并在 onReceive()中處理它們访得。當收到一條短信時龙亲,操作系統(tǒng)會發(fā)送一個 action 值為 android.provider.Telephony.SMS_RECEIVED
的廣播 Intent。應用程序則可以注冊一個 BroadcastReceiver 過濾這個 Intent 并處理收到的
數(shù)據(jù)悍抑。接收短信需要在 manifest 中聲明 android.permission.RECEIVE_SMS 權限鳄炉。
2.藍牙通信
藍牙上的連接是通過發(fā)現(xiàn)可用的“服務”,并通過一個 128 位的 UUID 連接到相應的服務搜骡。
android.permission.BLUETOOTH 權限拂盯。另外,想要改變藍牙的可發(fā)現(xiàn)性以及啟用/禁用藍牙適配器记靡,還要在 manifest 中聲明android.permission.BLUETOOTH_ADMIN 權限
3.查詢網(wǎng)絡連接狀態(tài)
通過 ConnectivityManager 監(jiān)控設備的網(wǎng)絡連接狀態(tài)谈竿。
public boolean isNetworkReachable() {
ConnectivityManager mManage = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo current = mManager.getActiveNetworkInfo();
if(current == null) {
return false;
}
return (current.getState() == NetworkInfo.State.CONNECTED);
}
判斷鏈接類型
return (current.getType() == ConnectivityManager.TYPE_WIFI);
4.使用NFC傳輸數(shù)據(jù)
根據(jù)想要推送內(nèi)容的大小,有兩種機制可以用來在兩個設備間 Beam 數(shù)據(jù)摸吠。
第一種. 使用前臺 Push 進行 Beam空凸。如果使用 NFC 在設備間發(fā)送簡單的內(nèi)容, 可以使用前臺推送機制來創(chuàng)建一個 NfcMessage寸痢,它包含了一個或多個 NfcRecord 實例劫恒。
第二種,Android Application Record
5.使用 Beam 來發(fā)送大型圖片文件
6.USB鏈接
端點: USB 設備的最小構件轿腺。應用程序最終就是通過連接端點發(fā)送和接收數(shù)據(jù)的两嘴。主要分4 種類型:
y 控制傳輸:用于配置和狀態(tài)命令。每個設備至少一個控制端點族壳,即“端點 0”憔辫,不會關聯(lián)任何接口。
y 中斷傳輸:用于小量的仿荆、高優(yōu)先級的控制命令贰您。
y 批量傳輸:用于傳輸大數(shù)據(jù)。通常都是雙向成對出現(xiàn)的(1 IN 和 1 OUT)拢操。
同步傳輸:用于實時數(shù)據(jù)傳輸锦亦,如音頻。撰寫本書時最新的 Android SDK 還不支持這個功能令境。
● 接口:端點的集合杠园,用來表示一個“邏輯”設備。
y 多個物理 USB 設備對于主機來說可以呈現(xiàn)為多個邏輯設備舔庶, 即通過暴露接口來標識抛蚁。
● 配置:一個或多個接口的集合陈醒。 USB 強制規(guī)定一個設備在某一特定時間只能有一個配置是激活的。事實上瞧甩,多數(shù)設備也就只有一個配置钉跷,并把它作為設備的操作模式
四、設備硬件交互
1.定位
需要注意設備的電量以及尊重用戶的意愿
GPS 返回的信息更加精確(誤差為幾米)肚逸,但需要的時間更長并且更耗電爷辙,
而網(wǎng)絡位置通常精確到幾千米,但速度更快而且省電
android.permission.ACCESS_COARSE_LOCATION 或
android.permission.ACCESS_FINE_LOCATION 權限
(1) 判斷所需的位置信息源是否可用朦促。如果不可用的話膝晾,決定是要求用戶啟用它還是
嘗試其他的信息源。
(2) 用適當?shù)淖钚【嚯x和更新時間間隔注冊設備位置的變化情況思灰。
(3) 當不需要時玷犹,及時取消對設備位置變化情況的注冊混滔,以節(jié)約電量洒疚。
2.地圖位置
百度、高德坯屿、谷歌
3.拍攝照片和視頻
將保存圖片的文件位置指定為設備的外部存儲器指定 android.permission.
WRITE_EXTERNAL_STORAGE 權限油湖。
在攝像頭不用時及時調(diào)用Camera.release()方法在攝像頭不用時及時調(diào)用Camera.release()方法
錄音
private void resetRecorder() {
//告訴錄音機將使用設備的麥克作為音頻輸入源(AudioSource.MIC)
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(path.getAbsolutePath());
try {
recorder.prepare();
} catch (Exception e) {
e.printStackTrace();
}
}
通過 android.speech 包中的類可以使用 Android 設備中內(nèi)置的語音識別技術。
4.傳感器
使用 SensorManager 接收來自于加速度計傳感器持續(xù)的反饋數(shù)據(jù)
registerListener()的最后一個參數(shù)定義了更新頻率领跛。這里選擇的是 SENSOR_DELAY_UI乏德,它是接收更新的最快頻率,每次更新都會直接修改 UI吠昭。
每當傳感器有新值更新喊括,都會用 SensorEven 值一起調(diào)用已注冊監(jiān)聽器的 onSensorChanged()方法。這個 SensorEvent 值包含了 X/Y/Z 軸上的加速度值矢棚。
羅盤傳感器
設備的磁場傳感器和加速度計一起確定用戶面向的方向
使用 SensorManager 的 getOrientation()得到用戶在地球上的方向
5.從媒體內(nèi)容得到截圖的縮略圖或其他元數(shù)據(jù)
MediaMetadataRetriever 讀取媒體文件并返回有用的信息郑什,可以讀取和跟蹤專輯或藝術家數(shù)據(jù)、或者內(nèi)容數(shù)據(jù)本身蒲肋,抓取該幀的截圖
四蘑拯。數(shù)據(jù)持久化
1.存儲、修改和顯示用戶設置及應用設置
PreferenceActivity 和 XML Preference 文件
2.讀寫文件
內(nèi)部存儲
受保護的用于讀寫文件數(shù)據(jù)的目錄空間兜粘。
外部存儲
外部掛載的用于讀寫文件數(shù)據(jù)的空間申窘。
API Level 4 以上需要 WRITE_EXTERNAL_STORAGE 權限。通常都是設備的 SD 卡孔轴。
Assets
APK 中只讀的受保護空間剃法。用于放置不能/不應該被編譯的本地資源。
3.分享數(shù)據(jù)
ContentProvider作為應用程序數(shù)據(jù)對外的接口路鹰,可以向外部請求暴露任何類型的應用程序數(shù)據(jù)玄窝,包括應用程序各種資源(包括 assets 下的資源)
五牵寺。與系統(tǒng)交互
1.通知
通過所有的系統(tǒng)控件,如 Service恩脂、 BroadcastReceiver 或者 Activity帽氓,都可以將一個通
知發(fā)送到 NotificationManager。
Notification.Style展示更多的通知樣式
2.創(chuàng)建粘性操作
IntentService 會將要執(zhí)行的任務(用 Intent表示)放到隊列中俩块,然后逐個處理每個請求黎休,全部處理完成后會終止自己。
3.啟用其他應用程序
a玉凯。讀取PDF文件
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(file, "application/pdf");
b势腮、與好友分享內(nèi)容
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, update);
startActivity(Intent.createChooser(intent, "Share..."));
c。ShareActionProvider分享內(nèi)容
根據(jù)用戶使用習慣漫仆,頻繁使用的選項會排到列表的最上方
android:showAsAction="ifRoom"
android:title="Share"
android:actionProviderClass="android.widget.ShareActionProvider"/>
MenuItem item = menu.findItem(R.id.menu_share);
ShareActionProvider provider = (ShareActionProvider) item.getActionProvider();
4.啟動系統(tǒng)應用程序
a捎拯。瀏覽器
pageIntent.setAction(Intent.ACTION_VIEW);
pageIntent.setData(Uri.parse(“ http://WEB_ADDRESS_TO_VIEW” ));
b。電話撥號器
dialIntent.setAction(Intent.ACTION_DIAL);
dialIntent.setData(Uri.Parse(“ tel:8885551234” );
c盲厌。地圖
mapIntent.setAction(Intent.ACTION_VIEW);
mapIntent.setData(Uri.parse(“ geo:latitude,longitude” ));
d署照。電子郵件
mailIntent.setAction(Intent.ACTION_SEND);
mailIntent.setType(“ message/rfc822” );
mailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"recipient@gmail.com"}); 收件人
mailIntent.putExtra(Intent.EXTRA_CC, new String[] {"carbon@gmail.com"}); 抄送
mailIntent.putExtra(Intent.EXTRA_BCC, new String[] {"blind@gmail.com"}); 密件抄送
mailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject");
mailIntent.putExtra(Intent.EXTRA_TEXT, "Body Text");
mailIntent.putExtra(Intent.EXTRA_STREAM, URI_TO_FILE); 附件
e、短消息
smsIntent.setAction(Intent.ACTION_VIEW);
smsIntent.setType(“ vnd.android-dir/mms-sms” );
smsIntent.putExtra(“ address” , “ 8885551234” );
smsIntent.putExtra(“ sms_body” , “ Body Text” );
f吗浩。聯(lián)系人選擇器
pickIntent.setAction(Intent.ACTION_PICK);
pickIntent.setData(URI_TO_CONTACT_TABLE);
g建芙。Google Play
marketIntent.setAction(Intent.ACTION_VIEW);
marketIntent.setData(Uri.parse(“ market://details?id=PACKAGE_NAME_HERE” ));
六。Android NDK和Renderscript
七懂扼。應用程序設計指南
1.設計經(jīng)過濾的應用程序
2.設計高性能的應用程序
優(yōu)化代碼結構禁荸、少創(chuàng)建對象、減少浮點運算阀湿、使用 System.arraycopy()復制赶熟、
使用擴充版的循環(huán)(比如 for (Strings: strings) {})
3.設計快速響應的應用程序
注意使用線程
4.設計無縫銜接的應用程序
不要丟失數(shù)據(jù),不要提供原始數(shù)據(jù)陷嘴,發(fā)送通知映砖、用線程執(zhí)行長時間操作、避免ANR罩旋、擴展系統(tǒng)主題啊央、設計使用多種分辨率的用戶界面、注意網(wǎng)絡判斷涨醋、不要指定鍵盤布局瓜饥、節(jié)約用電。
5.設計安全的應用程序
部分Demo代碼地址https://github.com/beibeiMary/AndroidDevelopment-paradigmDemo.git/