> 編寫:[spencer198711](https://github.com/spencer198711) - 原文:[http://developer.android.com/training/contacts-provider/display-contact-badge.html](http://developer.android.com/training/contacts-provider/display-contact-badge.html)
這一課展示了如何在我們的應用界面上添加一個[QuickContactBadge](),以及如何為它綁定數據。QuickContactBadge是一個在初始情況下顯示聯系人縮略圖頭像的widget。盡管我們可以使用任何[Bitmap](http://developer.android.com/reference/android/graphics/Bitmap.html)作為縮略圖頭像,但是我們通常會使用從聯系人照片縮略圖中解碼出來的Bitmap。
這個小的圖片是一個控件,當用戶點擊它時,QuickContactBadge會展開一個包含以下內容的對話框:
-
一個大的聯系人頭像
與這個聯系人關聯的大的頭像,如果此人沒有設置頭像,則顯示預留的圖案。
-
應用程序圖標
根據聯系人詳情數據,顯示每一個能夠被手機中的應用所處理的數據的圖標。例如,如果聯系人的數據包含一個或多個email地址,就會顯示email應用的圖標。當用戶點擊這個圖標的時候,這個聯系人所有的email地址都會顯示出來。當用戶點擊其中一個email地址時,email應用將會顯示一個界面,讓用戶為選中的地址撰寫郵件。
QuickContactBadge視圖提供了對聯系人數據的即時訪問,是一種與聯系人溝通的快捷方式。用戶不用查詢一個聯系人,查找并復制信息,然后把信息粘貼到合適的應用中。他們可以點擊QuickContactBadge,選擇他們想要的溝通方式,然后直接把信息發送給合適的應用中。
### 添加一個QuickContactBadge視圖
為了添加一個QuickContactBadge視圖,需要在布局文件中插入一個QuickContactBadge。例如:
~~~
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<QuickContactBadge
android:id=@+id/quickbadge
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="centerCrop"/>
...
</RelativeLayout>
~~~
### 獲取Contacts Provider的數據
為了能在QuickContactBadge中顯示聯系人,我們需要這個聯系人的內容URI和顯示頭像的Bitmap。我們可以從在Contacts Provider中獲取到的數據列中生成這兩個數據。需要指定這些列作為查詢映射去把數據加載到Cursor中。
對于Android 3.0(API版本為11)以及以后的版本,需要在查詢映射中添加以下列:
- [Contacts._ID](http://developer.android.com/reference/android/provider/BaseColumns.html#_ID)
- [Contacts.LOOKUP_KEY](http://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#LOOKUP_KEY)
- [Contacts.PHOTO_THUMBNAIL_URI](http://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#PHOTO_THUMBNAIL_URI)
對于Android 2.3.3(API版本為10)以及之前的版本,則使用以下列:
- [Contacts._ID](http://developer.android.com/reference/android/provider/BaseColumns.html#_ID)
- [Contacts.LOOKUP_KEY](http://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#LOOKUP_KEY)
這一課的剩余部分假設你已經獲取到了包含這些以及其他你可能選擇的數據列的Cursor對象。想要學習如何獲取這些列對象的Cursor,請參閱課程[獲取聯系人列表](#)。
### 設置聯系人URI和縮略圖
一旦我們已經擁有了所需的數據列,那么我們就可以為QuickContactBadge視圖綁定數據了。
### 設置聯系人URI
為了設置聯系人URI,需要調用[getLookupUri(id, lookupKey)]()去獲取[CONTENT_LOOKUP_URI](http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#CONTENT_LOOKUP_URI),然后調用[assignContactUri()](http://developer.android.com/reference/android/widget/QuickContactBadge.html#assignContactUri(android.net.Uri))去為QuickContactBadge設置對應的聯系人。例如:
~~~
// The Cursor that contains contact rows
Cursor mCursor;
// The index of the _ID column in the Cursor
int mIdColumn;
// The index of the LOOKUP_KEY column in the Cursor
int mLookupKeyColumn;
// A content URI for the desired contact
Uri mContactUri;
// A handle to the QuickContactBadge view
QuickContactBadge mBadge;
...
mBadge = (QuickContactBadge) findViewById(R.id.quickbadge);
/*
* Insert code here to move to the desired cursor row
*/
// Gets the _ID column index
mIdColumn = mCursor.getColumnIndex(Contacts._ID);
// Gets the LOOKUP_KEY index
mLookupKeyColumn = mCursor.getColumnIndex(Contacts.LOOKUP_KEY);
// Gets a content URI for the contact
mContactUri =
Contacts.getLookupUri(
mCursor.getLong(mIdColumn),
mCursor.getString(mLookupKeyColumn)
);
mBadge.assignContactUri(mContactUri);
~~~
當用戶點擊QuickContactBadge圖標的時候,這個聯系人的詳細信息將會自動展現在對話框中。
### 設置聯系人照片的縮略圖
為QuickContactBadge設置聯系人URI并不會自動加載聯系人的縮略圖照片。為了加載聯系人照片,需要從聯系人的Cursor對象的一行數據中獲取照片的URI,使用這個URI去打開包含壓縮的縮略圖文件,并把這個文件讀到Bitmap對象中。
> **Note:**[PHOTO_THUMBNAIL_URI](http://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#PHOTO_THUMBNAIL_URI)這一列在Android 3.0之前的版本是不存在的。對于這些版本,我們必須從[Contacts.Photo](http://developer.android.com/reference/android/provider/ContactsContract.Contacts.Photo.html)表中獲取照片的URI。
首先,為包含Contacts._ID和Contacts.LOOKUP_KEY的Cursor數據列設置對應的變量,這在之前已經有描述:
~~~
// The column in which to find the thumbnail ID
int mThumbnailColumn;
/*
* The thumbnail URI, expressed as a String.
* Contacts Provider stores URIs as String values.
*/
String mThumbnailUri;
...
/*
* Gets the photo thumbnail column index if
* platform version >= Honeycomb
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mThumbnailColumn =
mCursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI);
// Otherwise, sets the thumbnail column to the _ID column
} else {
mThumbnailColumn = mIdColumn;
}
/*
* Assuming the current Cursor position is the contact you want,
* gets the thumbnail ID
*/
mThumbnailUri = mCursor.getString(mThumbnailColumn);
...
~~~
定義一個方法,使用與這個聯系人的照片有關的數據和目標視圖的尺寸作為參數,返回一個尺寸合適的縮略圖Bitmap對象。下面先構建一個指向這個縮略圖的URI:
~~~
/**
* Load a contact photo thumbnail and return it as a Bitmap,
* resizing the image to the provided image dimensions as needed.
* @param photoData photo ID Prior to Honeycomb, the contact's _ID value.
* For Honeycomb and later, the value of PHOTO_THUMBNAIL_URI.
* @return A thumbnail Bitmap, sized to the provided width and height.
* Returns null if the thumbnail is not found.
*/
private Bitmap loadContactPhotoThumbnail(String photoData) {
// Creates an asset file descriptor for the thumbnail file.
AssetFileDescriptor afd = null;
// try-catch block for file not found
try {
// Creates a holder for the URI.
Uri thumbUri;
// If Android 3.0 or later
if (Build.VERSION.SDK_INT
>=
Build.VERSION_CODES.HONEYCOMB) {
// Sets the URI from the incoming PHOTO_THUMBNAIL_URI
thumbUri = Uri.parse(photoData);
} else {
// Prior to Android 3.0, constructs a photo Uri using _ID
/*
* Creates a contact URI from the Contacts content URI
* incoming photoData (_ID)
*/
final Uri contactUri = Uri.withAppendedPath(
Contacts.CONTENT_URI, photoData);
/*
* Creates a photo URI by appending the content URI of
* Contacts.Photo.
*/
thumbUri =
Uri.withAppendedPath(
contactUri, Photo.CONTENT_DIRECTORY);
}
/*
* Retrieves an AssetFileDescriptor object for the thumbnail
* URI
* using ContentResolver.openAssetFileDescriptor
*/
afd = getActivity().getContentResolver().
openAssetFileDescriptor(thumbUri, "r");
/*
* Gets a file descriptor from the asset file descriptor.
* This object can be used across processes.
*/
FileDescriptor fileDescriptor = afd.getFileDescriptor();
// Decode the photo file and return the result as a Bitmap
// If the file descriptor is valid
if (fileDescriptor != null) {
// Decodes the bitmap
return BitmapFactory.decodeFileDescriptor(
fileDescriptor, null, null);
}
// If the file isn't found
} catch (FileNotFoundException e) {
/*
* Handle file not found errors
*/
}
// In all cases, close the asset file descriptor
} finally {
if (afd != null) {
try {
afd.close();
} catch (IOException e) {}
}
}
return null;
}
~~~
在代碼中調用loadContactPhotoThumbnail()去獲取縮略圖Bitmap對象,使用獲取的Bitmap對象去設置QuickContactBadge頭像縮略圖。
~~~
...
/*
* Decodes the thumbnail file to a Bitmap.
*/
Bitmap mThumbnail =
loadContactPhotoThumbnail(mThumbnailUri);
/*
* Sets the image in the QuickContactBadge
* QuickContactBadge inherits from ImageView, so
*/
mBadge.setImageBitmap(mThumbnail);
~~~
### 把QuickContactBadge添加到ListView
QuickContactBadge對于一個展示聯系人列表的ListView來說是一個非常有用的添加功能。使用QuickContactBadge去為每一個聯系人顯示一個縮略圖,當用戶點擊這個縮略圖時,QuickContactBadge對話框將會顯示。
### 為ListView添加QuickContactBadge
首先,在列表項布局文件中添加QuickContactBadge視圖元素。例如,如果我們想為獲取到的每一個聯系人顯示QuickContactBadge和名字,把以下的XML內容放到對應的布局文件中:
~~~
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<QuickContactBadge
android:id="@+id/quickcontact"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="centerCrop"/>
<TextView android:id="@+id/displayname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/quickcontact"
android:gravity="center_vertical"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"/>
</RelativeLayout>
~~~
在以下的章節中,這個文件被稱為`contact_item_layout.xml`。
### 設置自定義的CursorAdapter
定義一個繼承自CursorAdapter的adapter來將CursorAdapter綁定到一個包含QuickContactBadge的ListView中。這種方式允許我們在綁定數據到QuickContactBadge之前對Cursor中的數據進行處理。同時也能將多個Cursor中的列綁定到QuickContactBadge。而使用普通的CursorAdapter是不能完成這些操作的。
我們定義的CursorAdapter的子類必須重寫以下方法:
-
[CursorAdapter.newView()]()
填充一個View對象去持有列表項布局。在重寫這個方法的過程中,需要保存這個布局的子View的handles,包括QuickContactBadge的handles。通過采用這種方法,避免了每次在填充新的布局時都去獲取子View的handles。
我們必須重寫這個方法以便能夠獲取每個子View對象的handles。這種方法允許我們控制這些子View對象在CursorAdapter.bindView()方法中的綁定。
-
[CursorAdapter.bindView()]()
將數據從當前Cursor行綁定到列表項布局的子View對象中。必須重寫這個方法以便能夠將聯系人的URI和縮略圖信息綁定到QuickContactBadge。這個方法的默認實現僅僅允許在數據列和View之間的一對一映射。
以下的代碼片段是一個包含了自定義CursorAdapter子類的例子。
### 定義自定義的列表Adapter
定義CursorAdapter的子類包括編寫這個類的構造方法,以及重寫newView()和bindView():
~~~
private class ContactsAdapter extends CursorAdapter {
private LayoutInflater mInflater;
...
public ContactsAdapter(Context context) {
super(context, null, 0);
/*
* Gets an inflater that can instantiate
* the ListView layout from the file.
*/
mInflater = LayoutInflater.from(context);
...
}
...
/**
* Defines a class that hold resource IDs of each item layout
* row to prevent having to look them up each time data is
* bound to a row.
*/
private class ViewHolder {
TextView displayname;
QuickContactBadge quickcontact;
}
..
@Override
public View newView(
Context context,
Cursor cursor,
ViewGroup viewGroup) {
/* Inflates the item layout. Stores resource IDs in a
* in a ViewHolder class to prevent having to look
* them up each time bindView() is called.
*/
final View itemView =
mInflater.inflate(
R.layout.contact_list_layout,
viewGroup,
false
);
final ViewHolder holder = new ViewHolder();
holder.displayname =
(TextView) view.findViewById(R.id.displayname);
holder.quickcontact =
(QuickContactBadge)
view.findViewById(R.id.quickcontact);
view.setTag(holder);
return view;
}
...
@Override
public void bindView(
View view,
Context context,
Cursor cursor) {
final ViewHolder holder = (ViewHolder) view.getTag();
final String photoData =
cursor.getString(mPhotoDataIndex);
final String displayName =
cursor.getString(mDisplayNameIndex);
...
// Sets the display name in the layout
holder.displayname = cursor.getString(mDisplayNameIndex);
...
/*
* Generates a contact URI for the QuickContactBadge.
*/
final Uri contactUri = Contacts.getLookupUri(
cursor.getLong(mIdIndex),
cursor.getString(mLookupKeyIndex));
holder.quickcontact.assignContactUri(contactUri);
String photoData = cursor.getString(mPhotoDataIndex);
/*
* Decodes the thumbnail file to a Bitmap.
* The method loadContactPhotoThumbnail() is defined
* in the section "Set the Contact URI and Thumbnail"
*/
Bitmap thumbnailBitmap =
loadContactPhotoThumbnail(photoData);
/*
* Sets the image in the QuickContactBadge
* QuickContactBadge inherits from ImageView
*/
holder.quickcontact.setImageBitmap(thumbnailBitmap);
}
~~~
### 設置變量
在代碼中,設置相關變量,添加一個包括必須數據列的Cursor。
> **Note:**以下的代碼片段使用了方法`loadContactPhotoThumbnail()`,這個方法是在[設置聯系人URI和縮略圖]()那一節中定義的。
例如:
~~~
public class ContactsFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor> {
...
// Defines a ListView
private ListView mListView;
// Defines a ContactsAdapter
private ContactsAdapter mAdapter;
...
// Defines a Cursor to contain the retrieved data
private Cursor mCursor;
/*
* Defines a projection based on platform version. This ensures
* that you retrieve the correct columns.
*/
private static final String[] PROJECTION =
{
Contacts._ID,
Contacts.LOOKUP_KEY,
(Build.VERSION.SDK_INT >=
Build.VERSION_CODES.HONEYCOMB) ?
Contacts.DISPLAY_NAME_PRIMARY :
Contacts.DISPLAY_NAME
(Build.VERSION.SDK_INT >=
Build.VERSION_CODES.HONEYCOMB) ?
Contacts.PHOTO_THUMBNAIL_ID :
/*
* Although it's not necessary to include the
* column twice, this keeps the number of
* columns the same regardless of version
*/
Contacts_ID
...
};
/*
* As a shortcut, defines constants for the
* column indexes in the Cursor. The index is
* 0-based and always matches the column order
* in the projection.
*/
// Column index of the _ID column
private int mIdIndex = 0;
// Column index of the LOOKUP_KEY column
private int mLookupKeyIndex = 1;
// Column index of the display name column
private int mDisplayNameIndex = 3;
/*
* Column index of the photo data column.
* It's PHOTO_THUMBNAIL_URI for Honeycomb and later,
* and _ID for previous versions.
*/
private int mPhotoDataIndex =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
3 :
0;
...
~~~
### 設置ListView
在[Fragment.onCreate()](http://developer.android.com/reference/android/support/v4/app/Fragment.html#onCreate(android.os.Bundle))方法中,實例化自定義的adapter對象,獲得一個ListView的handle。
~~~
@Override
public void onCreate(Bundle savedInstanceState) {
...
/*
* Instantiates the subclass of
* CursorAdapter
*/
ContactsAdapter mContactsAdapter =
new ContactsAdapter(getActivity());
/*
* Gets a handle to the ListView in the file
* contact_list_layout.xml
*/
mListView = (ListView) findViewById(R.layout.contact_list_layout);
...
}
...
~~~
在[onActivityCreated()](http://developer.android.com/reference/android/support/v4/app/Fragment.html#onActivityCreated(android.os.Bundle))方法中,將ContactsAdapter綁定到ListView。
~~~
@Override
public void onActivityCreated(Bundle savedInstanceState) {
...
// Sets up the adapter for the ListView
mListView.setAdapter(mAdapter);
...
}
...
~~~
當獲取到一個包含聯系人數據的Cursor時(通常在onLoadFinished()的時候),調用swapCursor()把Cursor中的數據綁定到ListView。這將會為聯系人列表中的每一項都顯示一個QuickContactBadge。
~~~
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
// When the loader has completed, swap the cursor into the adapter.
mContactsAdapter.swapCursor(cursor);
}
~~~
當我們使用CursorAdapter或其子類中將Cursor中的數據綁定到ListView,并且使用了CursorLoader去加載Cursor數據時,記得要在onLoaderReset()方法的實現中清理對Cursor對象的引用。例如:
~~~
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// Removes remaining reference to the previous Cursor
mContactsAdapter.swapCursor(null);
}
~~~
- 序言
- Android入門基礎:從這里開始
- 建立第一個App
- 創建Android項目
- 執行Android程序
- 建立簡單的用戶界面
- 啟動其他的Activity
- 添加ActionBar
- 建立ActionBar
- 添加Action按鈕
- 自定義ActionBar的風格
- ActionBar的覆蓋層疊
- 兼容不同的設備
- 適配不同的語言
- 適配不同的屏幕
- 適配不同的系統版本
- 管理Activity的生命周期
- 啟動與銷毀Activity
- 暫停與恢復Activity
- 停止與重啟Activity
- 重新創建Activity
- 使用Fragment建立動態的UI
- 創建一個Fragment
- 建立靈活動態的UI
- Fragments之間的交互
- 數據保存
- 保存到Preference
- 保存到文件
- 保存到數據庫
- 與其他應用的交互
- Intent的發送
- 接收Activity返回的結果
- Intent過濾
- Android分享操作
- 分享簡單的數據
- 給其他App發送簡單的數據
- 接收從其他App返回的數據
- 給ActionBar增加分享功能
- 分享文件
- 建立文件分享
- 分享文件
- 請求分享一個文件
- 獲取文件信息
- 使用NFC分享文件
- 發送文件給其他設備
- 接收其他設備的文件
- Android多媒體
- 管理音頻播放
- 控制音量與音頻播放
- 管理音頻焦點
- 兼容音頻輸出設備
- 拍照
- 簡單的拍照
- 簡單的錄像
- 控制相機硬件
- 打印
- 打印照片
- 打印HTML文檔
- 打印自定義文檔
- Android圖像與動畫
- 高效顯示Bitmap
- 高效加載大圖
- 非UI線程處理Bitmap
- 緩存Bitmap
- 管理Bitmap的內存
- 在UI上顯示Bitmap
- 使用OpenGL ES顯示圖像
- 建立OpenGL ES的環境
- 定義Shapes
- 繪制Shapes
- 運用投影與相機視圖
- 添加移動
- 響應觸摸事件
- 添加動畫
- View間漸變
- 使用ViewPager實現屏幕側滑
- 展示卡片翻轉動畫
- 縮放View
- 布局變更動畫
- Android網絡連接與云服務
- 無線連接設備
- 使得網絡服務可發現
- 使用WiFi建立P2P連接
- 使用WiFi P2P服務
- 執行網絡操作
- 連接到網絡
- 管理網絡
- 解析XML數據
- 高效下載
- 為網絡訪問更加高效而優化下載
- 最小化更新操作的影響
- 避免下載多余的數據
- 根據網絡類型改變下載模式
- 云同步
- 使用備份API
- 使用Google Cloud Messaging
- 解決云同步的保存沖突
- 使用Sync Adapter傳輸數據
- 創建Stub授權器
- 創建Stub Content Provider
- 創建Sync Adpater
- 執行Sync Adpater
- 使用Volley執行網絡數據傳輸
- 發送簡單的網絡請求
- 建立請求隊列
- 創建標準的網絡請求
- 實現自定義的網絡請求
- Android聯系人與位置信息
- Android聯系人信息
- 獲取聯系人列表
- 獲取聯系人詳情
- 使用Intents修改聯系人信息
- 顯示聯系人頭像
- Android位置信息
- 獲取最后可知位置
- 獲取位置更新
- 顯示位置地址
- 創建和監視地理圍欄
- Android可穿戴應用
- 賦予Notification可穿戴特性
- 創建Notification
- 在Notifcation中接收語音輸入
- 為Notification添加顯示頁面
- 以Stack的方式顯示Notifications
- 創建可穿戴的應用
- 創建并運行可穿戴應用
- 創建自定義的布局
- 添加語音功能
- 打包可穿戴應用
- 通過藍牙進行調試
- 創建自定義的UI
- 定義Layouts
- 創建Cards
- 創建Lists
- 創建2D-Picker
- 創建確認界面
- 退出全屏的Activity
- 發送并同步數據
- 訪問可穿戴數據層
- 同步數據單元
- 傳輸資源
- 發送與接收消息
- 處理數據層的事件
- Android TV應用
- 創建TV應用
- 創建TV應用的第一步
- 處理TV硬件部分
- 創建TV的布局文件
- 創建TV的導航欄
- 創建TV播放應用
- 創建目錄瀏覽器
- 提供一個Card視圖
- 創建詳情頁
- 顯示正在播放卡片
- 幫助用戶在TV上探索內容
- TV上的推薦內容
- 使得TV App能夠被搜索
- 使用TV應用進行搜索
- 創建TV游戲應用
- 創建TV直播應用
- TV Apps Checklist
- Android企業級應用
- Ensuring Compatibility with Managed Profiles
- Implementing App Restrictions
- Building a Work Policy Controller
- Android交互設計
- 設計高效的導航
- 規劃屏幕界面與他們之間的關系
- 為多種大小的屏幕進行規劃
- 提供向下和橫向導航
- 提供向上和歷史導航
- 綜合:設計樣例 App
- 實現高效的導航
- 使用Tabs創建Swipe視圖
- 創建抽屜導航
- 提供向上的導航
- 提供向后的導航
- 實現向下的導航
- 通知提示用戶
- 建立Notification
- 當啟動Activity時保留導航
- 更新Notification
- 使用BigView風格
- 顯示Notification進度
- 增加搜索功能
- 建立搜索界面
- 保存并搜索數據
- 保持向下兼容
- 使得你的App內容可被Google搜索
- 為App內容開啟深度鏈接
- 為索引指定App內容
- Android界面設計
- 為多屏幕設計
- 兼容不同的屏幕大小
- 兼容不同的屏幕密度
- 實現可適應的UI
- 創建自定義View
- 創建自定義的View類
- 實現自定義View的繪制
- 使得View可交互
- 優化自定義View
- 創建向后兼容的UI
- 抽象新的APIs
- 代理至新的APIs
- 使用舊的APIs實現新API的效果
- 使用版本敏感的組件
- 實現輔助功能
- 開發輔助程序
- 開發輔助服務
- 管理系統UI
- 淡化系統Bar
- 隱藏系統Bar
- 隱藏導航Bar
- 全屏沉浸式應用
- 響應UI可見性的變化
- 創建使用Material Design的應用
- 開始使用Material Design
- 使用Material的主題
- 創建Lists與Cards
- 定義Shadows與Clipping視圖
- 使用Drawables
- 自定義動畫
- 維護兼容性
- Android用戶輸入
- 使用觸摸手勢
- 檢測常用的手勢
- 跟蹤手勢移動
- Scroll手勢動畫
- 處理多觸摸手勢
- 拖拽與縮放
- 管理ViewGroup中的觸摸事件
- 處理鍵盤輸入
- 指定輸入法類型
- 處理輸入法可見性
- 兼容鍵盤導航
- 處理按鍵動作
- 兼容游戲控制器
- 處理控制器輸入動作
- 支持不同的Android系統版本
- 支持多個控制器
- Android后臺任務
- 在IntentService中執行后臺任務
- 創建IntentService
- 發送工作任務到IntentService
- 報告后臺任務執行狀態
- 使用CursorLoader在后臺加載數據
- 使用CursorLoader執行查詢任務
- 處理查詢的結果
- 管理設備的喚醒狀態
- 保持設備的喚醒
- 制定重復定時的任務
- Android性能優化
- 管理應用的內存
- 代碼性能優化建議
- 提升Layout的性能
- 優化layout的層級
- 使用include標簽重用layouts
- 按需加載視圖
- 使得ListView滑動順暢
- 優化電池壽命
- 監測電量與充電狀態
- 判斷與監測Docking狀態
- 判斷與監測網絡連接狀態
- 根據需要操作Broadcast接受者
- 多線程操作
- 在一個線程中執行一段特定的代碼
- 為多線程創建線程池
- 啟動與停止線程池中的線程
- 與UI線程通信
- 避免出現程序無響應ANR
- JNI使用指南
- 優化多核處理器(SMP)下的Android程序
- Android安全與隱私
- Security Tips
- 使用HTTPS與SSL
- 為防止SSL漏洞而更新Security
- 使用設備管理條例增強安全性
- Android測試程序
- 測試你的Activity
- 建立測試環境
- 創建與執行測試用例
- 測試UI組件
- 創建單元測試
- 創建功能測試
- 術語表