在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 顯示位置地址
檢測(cè)常用的手勢(shì)
優(yōu)化layout的層級(jí)
用戶輸入
管理應(yīng)用的內(nèi)存
聯(lián)系人信息
開發(fā)輔助程序
Android多媒體
添加語(yǔ)音功能
顯示位置地址
提供向下與橫向?qū)Ш?/span>
支持游戲控制器
訪問(wèn)可穿戴數(shù)據(jù)層
處理多點(diǎn)觸控手勢(shì)
全屏沉浸式應(yīng)用
為多線程創(chuàng)建管理器
數(shù)據(jù)保存
Intent的發(fā)送
更新Notification
優(yōu)化下載以高效地訪問(wèn)網(wǎng)絡(luò)
打印
打包可穿戴應(yīng)用
接收從其他App傳送來(lái)的數(shù)據(jù)
發(fā)送與接收消息
建立靈活動(dòng)態(tài)的UI
處理鍵盤輸入
Building a Work Policy Controller
建立測(cè)試環(huán)境
創(chuàng)建表盤
分享文件
顯示Notification進(jìn)度
實(shí)現(xiàn)自適應(yīng)UI流(Flows)
使用設(shè)備管理策略增強(qiáng)安全性
使用能感知版本的組件
執(zhí)行網(wǎng)絡(luò)操作
建立文件分享
添加移動(dòng)
更新你的Security Provider來(lái)對(duì)抗SSL漏洞利用
支持鍵盤導(dǎo)航
創(chuàng)建和監(jiān)視地理圍欄
發(fā)送并同步數(shù)據(jù)
使用BigView樣式
無(wú)線連接設(shè)備
提供向上導(dǎo)航與歷史導(dǎo)航
最小化定期更新造成的影響
實(shí)現(xiàn)向下的導(dǎo)航
支持不同的屏幕大小
Android 可穿戴應(yīng)用
添加動(dòng)畫
顯示聯(lián)系人頭像
使用OpenGL ES顯示圖像
處理輸入法可見(jiàn)性
分享文件
保持設(shè)備喚醒
淡化系統(tǒng)Bar
使用NFC分享文件
保存到Preference
Android聯(lián)系人信息與位置信息
創(chuàng)建標(biāo)準(zhǔn)的網(wǎng)絡(luò)請(qǐng)求
使用Drawables
管理Bitmap的內(nèi)存使用
管理Activity的生命周期
按需加載視圖
傳輸資源
為可穿戴設(shè)備創(chuàng)建自定義UI
在一個(gè)線程中執(zhí)行一段特定的代碼
性能優(yōu)化
隱藏導(dǎo)航欄
創(chuàng)建目錄瀏覽器
為多種大小的屏幕進(jìn)行規(guī)劃
View間漸變
使用觸摸手勢(shì)
高效加載大圖
使用CursorLoader在后臺(tái)加載數(shù)據(jù)
創(chuàng)建抽屜式導(dǎo)航(navigation drawer)
管理音頻焦點(diǎn)
創(chuàng)建后臺(tái)服務(wù)
創(chuàng)建功能測(cè)試
創(chuàng)建使用Material Design的應(yīng)用
停止與重啟Activity
添加一個(gè)簡(jiǎn)便的分享功能
啟動(dòng)Activity時(shí)保留導(dǎo)航
TV應(yīng)用清單
創(chuàng)建向后兼容的UI
?# 優(yōu)化自定義View
創(chuàng)建單元測(cè)試
在UI上顯示Bitmap
建立OpenGL ES的環(huán)境
構(gòu)建表盤服務(wù)
JNI Tips
建立搜索界面
實(shí)現(xiàn)自定義View的繪制
使用HTTPS與SSL
按需操控BroadcastReceiver
分享簡(jiǎn)單的數(shù)據(jù)
繪制形狀
Android位置信息
創(chuàng)建并運(yùn)行可穿戴應(yīng)用
執(zhí)行 Sync Adpater
獲取最后可知位置
創(chuàng)建 Android 項(xiàng)目
實(shí)現(xiàn)高效的導(dǎo)航
退出全屏的Activity
創(chuàng)建Card
兼容音頻輸出設(shè)備
同步數(shù)據(jù)單元
傳輸數(shù)據(jù)時(shí)避免消耗大量電量
保存到文件
緩存Bitmap
提供配置 Activity
調(diào)度重復(fù)的鬧鐘
實(shí)現(xiàn)輔助功能
重復(fù)的下載是冗余的
隱藏狀態(tài)欄
實(shí)現(xiàn)自定義的網(wǎng)絡(luò)請(qǐng)求
規(guī)劃界面和他們之間的關(guān)系
使用Sync Adapter傳輸數(shù)據(jù)
TV應(yīng)用內(nèi)搜索
響應(yīng)觸摸事件
使用Google Cloud Messaging(已廢棄)
控制相機(jī)
Android網(wǎng)絡(luò)連接與云服務(wù)
請(qǐng)求分享一個(gè)文件
處理TV硬件
響應(yīng)UI可見(jiàn)性的變化
使用網(wǎng)絡(luò)服務(wù)發(fā)現(xiàn)
指定輸入法類型
優(yōu)化電池壽命
創(chuàng)建TV應(yīng)用
獲取聯(lián)系人列表
拖拽與縮放
啟動(dòng)與停止線程池中的線程
創(chuàng)建 Sync Adpater
使用 WiFi P2P 服務(wù)發(fā)現(xiàn)
開始使用Material Design
代理至新的APIs
使用include標(biāo)簽重用layouts
使得View可交互
高效顯示Bitmap
創(chuàng)建企業(yè)級(jí)應(yīng)用
Fragments之間的交互
創(chuàng)建與執(zhí)行測(cè)試用例
綜合:設(shè)計(jì)我們的樣例 App
繪制表盤
建立簡(jiǎn)單的用戶界面
自定義動(dòng)畫
開發(fā)輔助服務(wù)
避免出現(xiàn)程序無(wú)響應(yīng)ANR(Keeping Your App Responsive)
使用ViewPager實(shí)現(xiàn)屏幕滑動(dòng)
設(shè)計(jì)高效的導(dǎo)航
Android分享操作(Building Apps with Content Sharing)
提供向后的導(dǎo)航
保持向下兼容
創(chuàng)建TV播放應(yīng)用
縮放View
使用 WiFi 建立 P2P 連接
Android后臺(tái)任務(wù)
連接到網(wǎng)絡(luò)
為 Notification 添加頁(yè)面
使TV應(yīng)用是可被搜索的
添加Action Bar
使用Material的主題
啟動(dòng)另一個(gè)Activity
顯示正在播放卡片
適配不同的系統(tǒng)版本
輕松錄制視頻
創(chuàng)建可穿戴的應(yīng)用
創(chuàng)建自定義的布局
重新創(chuàng)建Activity
使用CursorLoader執(zhí)行查詢?nèi)蝿?wù)
使用舊的APIs實(shí)現(xiàn)新API的效果
使用備份API
安全要點(diǎn)
Android入門基礎(chǔ):從這里開始
保存并搜索數(shù)據(jù)
根據(jù)網(wǎng)絡(luò)連接類型來(lái)調(diào)整下載模式
使用Tabs創(chuàng)建Swipe視圖
SMP(Symmetric Multi-Processor) Primer for Android
解析 XML 數(shù)據(jù)
使用 Volley 傳輸網(wǎng)絡(luò)數(shù)據(jù)
建立ActionBar
Android交互設(shè)計(jì)
使用Intent修改聯(lián)系人信息
增加搜索功能
輕松拍攝照片
定義形狀
測(cè)試你的Activity
在 Notifcation 中接收語(yǔ)音輸入
與其他應(yīng)用的交互
管理系統(tǒng)UI
追蹤手勢(shì)移動(dòng)
Android界面設(shè)計(jì)
執(zhí)行 Android 程序
顯示確認(rèn)界面
創(chuàng)建Lists與Cards
打印HTML文檔
創(chuàng)建TV應(yīng)用
為多屏幕設(shè)計(jì)
定義Shadows與Clipping視圖
使用Fragment建立動(dòng)態(tài)UI
接收Activity返回的結(jié)果
布局變更動(dòng)畫
定位常見(jiàn)的問(wèn)題
自定義ActionBar的風(fēng)格
定義Layouts
發(fā)送簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求
啟動(dòng)與銷毀Activity
與UI線程通信
非UI線程處理Bitmap
創(chuàng)建TV布局
提升Layout的性能
報(bào)告任務(wù)執(zhí)行狀態(tài)
判斷并監(jiān)測(cè)網(wǎng)絡(luò)連接狀態(tài)
兼容不同的設(shè)備
處理按鍵動(dòng)作
優(yōu)化性能和電池使用時(shí)間
給其他App發(fā)送簡(jiǎn)單的數(shù)據(jù)
Implementing App Restrictions
向后臺(tái)服務(wù)發(fā)送任務(wù)請(qǐng)求
展示Card翻轉(zhuǎn)動(dòng)畫
管理ViewGroup中的觸摸事件
兼容不同的屏幕密度
通過(guò)藍(lán)牙進(jìn)行調(diào)試
為可穿戴設(shè)備創(chuàng)建Notification
控制音量與音頻播放
獲取聯(lián)系人詳情
在表盤上顯示信息
提供向上的導(dǎo)航
滾動(dòng)手勢(shì)動(dòng)畫
幫助用戶在TV上找到內(nèi)容
創(chuàng)建TV導(dǎo)航
為索引指定App內(nèi)容
ActionBar的覆蓋疊加
Android Wear 上的位置檢測(cè)
保護(hù)安全與隱私的最佳策略
Ensuring Compatibility with Managed Profiles
解決云同步的保存沖突
獲取位置更新
創(chuàng)建List
測(cè)試程序
管理網(wǎng)絡(luò)的使用情況
為App內(nèi)容開啟深度鏈接
推薦TV內(nèi)容
建立一個(gè)Notification
管理音頻播放
設(shè)計(jì)表盤
拍照
處理控制器輸入動(dòng)作
判斷并監(jiān)測(cè)設(shè)備的底座狀態(tài)與類型
處理查詢的結(jié)果
保存到數(shù)據(jù)庫(kù)
支持多個(gè)游戲控制器
創(chuàng)建 Stub Content Provider
使得ListView滑動(dòng)順暢
處理數(shù)據(jù)層的事件
創(chuàng)建TV應(yīng)用的第一步
使得你的App內(nèi)容可被Google搜索
將 Notification 放成一疊
創(chuàng)建 Stub 授權(quán)器
暫停與恢復(fù)Activity
管理設(shè)備的喚醒狀態(tài)
Android圖像與動(dòng)畫
打印照片
云同步
創(chuàng)建TV直播應(yīng)用
為Notification賦加可穿戴特性
提供一個(gè)Card視圖
建立請(qǐng)求隊(duì)列(RequestQueue)
適配不同的語(yǔ)言
創(chuàng)建詳情頁(yè)
測(cè)試UI組件
接收其他設(shè)備的文件
創(chuàng)建自定義View
建立第一個(gè)App
創(chuàng)建2D Picker
監(jiān)測(cè)電池的電量與充電狀態(tài)
打印自定義文檔
抽象出新的APIs
通知提示用戶
獲取文件信息
運(yùn)用投影與相機(jī)視角
在IntentService中執(zhí)行后臺(tái)任務(wù)
多線程操作
創(chuàng)建一個(gè)Fragment
添加Action按鈕
在不同的 Android 系統(tǒng)版本支持控制器
維護(hù)兼容性
發(fā)送文件給其他設(shè)備
創(chuàng)建TV游戲應(yīng)用
創(chuàng)建自定義的View類
代碼性能優(yōu)化建議
Intent過(guò)濾
適配不同的屏幕

顯示位置地址

編寫:penkzhou - 原文:http://developer.android.com/training/location/display-address.html

獲取最后可知位置獲取位置更新課程描述了如何以一個(gè)Location對(duì)象的形式獲取用戶的位置信息,這個(gè)位置信息包括了經(jīng)緯度。盡管經(jīng)緯度對(duì)計(jì)算地理距離和在地圖上顯示位置很有用,但是更多情況下位置的地址更有用。例如,如果我們想讓用戶知道他們?cè)谀睦?,那么一個(gè)街道地址比地理坐標(biāo)(經(jīng)度/緯度)更加有意義。

使用 Android 框架位置 APIs 的 Geocoder 類,我們可以將地址轉(zhuǎn)換成相應(yīng)的地理坐標(biāo)。這個(gè)過(guò)程叫做地理編碼?;蛘?,我們可以將地理位置轉(zhuǎn)換成相應(yīng)的地址。這種地址查找功能叫做反向地理編碼。

這節(jié)課介紹了如何用 getFromLocation() 方法將地理位置轉(zhuǎn)換成地址。這個(gè)方法返回與制定經(jīng)緯度相對(duì)應(yīng)的估計(jì)的街道地址。

獲取地理位置

設(shè)備的最后可知位置對(duì)于地址查找功能是很有用的基礎(chǔ)。獲取最后可知位置介紹了如何通過(guò)調(diào)用 fused location provider 提供的 getLastLocation() 方法找到設(shè)備的最后可知位置。

為了訪問(wèn) fused location provider,我們需要?jiǎng)?chuàng)建一個(gè) Google Play services API client 的實(shí)例。關(guān)于如何連接 client,請(qǐng)見(jiàn)連接 Google Play Services 。

為了讓 fused location provider 得到一個(gè)準(zhǔn)確的街道地址,在應(yīng)用的 manifest 文件添加位置權(quán)限 ACCESS_FINE_LOCATION,如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.android.gms.location.sample.locationupdates" >

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

定義一個(gè) Intent 服務(wù)來(lái)取得地址

Geocoder 類的 getFromLocation() 方法接收一個(gè)經(jīng)度和緯度,返回一個(gè)地址列表。這個(gè)方法是同步的,可能會(huì)花很長(zhǎng)時(shí)間來(lái)完成它的工作,所以我們不應(yīng)該在應(yīng)用的主線程和 UI 線程里調(diào)用這個(gè)方法。

IntentService 類提供了一種結(jié)構(gòu)使一個(gè)任務(wù)在后臺(tái)線程運(yùn)行。使用這個(gè)類,我們可以在不影響 UI 響應(yīng)速度的情況下處理一個(gè)長(zhǎng)時(shí)間運(yùn)行的操作。注意到,AsyncTask 類也可以執(zhí)行后臺(tái)操作,但是它被設(shè)計(jì)用于短時(shí)間運(yùn)行的操作。在 activity 重新創(chuàng)建時(shí)(例如當(dāng)設(shè)備旋轉(zhuǎn)時(shí)),AsyncTask 不應(yīng)該保存 UI 的引用。相反,當(dāng) activity 重建時(shí),不需要取消 IntentService。

定義一個(gè)繼承 IntentService 的類 FetchAddressIntentService。這個(gè)類是地址查找服務(wù)。這個(gè) Intent 服務(wù)在一個(gè)工作線程上異步地處理一個(gè) intent,并在它離開這個(gè)工作時(shí)自動(dòng)停止。Intent 外加的數(shù)據(jù)提供了服務(wù)需要的數(shù)據(jù),包括一個(gè)用于轉(zhuǎn)換成地址的 Location 對(duì)象和一個(gè)用于處理地址查找結(jié)果的 ResultReceiver 對(duì)象。這個(gè)服務(wù)用一個(gè) Geocoder 來(lái)獲取位置的地址,并且將結(jié)果發(fā)送給 ResultReceiver。

在應(yīng)用的 manifest 文件中定義 Intent 服務(wù)

在 manifest 文件中添加一個(gè)節(jié)點(diǎn)以定義 intent 服務(wù):

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.android.gms.location.sample.locationaddress" >
    <application
        ...
        <service
            android:name=".FetchAddressIntentService"
            android:exported="false"/>
    </application>
    ...
</manifest>

Note:manifest 文件里的 <service> 節(jié)點(diǎn)不需要包含一個(gè) intent filter,這是因?yàn)槲覀兊闹?activity 通過(guò)指定 intent 用到的類的名字來(lái)創(chuàng)建一個(gè)隱式的 intent。

創(chuàng)建一個(gè) Geocoder

將一個(gè)地理位置傳換成地址的過(guò)程叫做反向地理編碼。通過(guò)實(shí)現(xiàn) FetchAddressIntentService 類的 onHandleIntent() 來(lái)執(zhí)行 intent 服務(wù)的主要工作,即反向地理編碼請(qǐng)求。創(chuàng)建一個(gè) Geocoder 對(duì)象來(lái)處理反向地理編碼。

一個(gè)區(qū)域設(shè)置代表一個(gè)特定的地理上的或者語(yǔ)言上的區(qū)域。Locale 對(duì)象用于調(diào)整信息的呈現(xiàn)方式,例如數(shù)字或者日期,來(lái)適應(yīng)區(qū)域設(shè)置表示的區(qū)域的約定。傳一個(gè) Locale 對(duì)象到 Geocoder 對(duì)象,確保地址結(jié)果為用戶的地理區(qū)域作出了本地化。

@Override
protected void onHandleIntent(Intent intent) {
    Geocoder geocoder = new Geocoder(this, Locale.getDefault());
    ...
}

獲取街道地址數(shù)據(jù)

下一步是從 geocoder 獲取街道地址,處理可能出現(xiàn)的錯(cuò)誤,和將結(jié)果返回給請(qǐng)求地址的 activity。我們需要兩個(gè)分別代表成功和失敗的數(shù)字常量來(lái)報(bào)告地理編碼過(guò)程的結(jié)果。定義一個(gè) Constants 類來(lái)包含這些值,如下所示:

public final class Constants {
    public static final int SUCCESS_RESULT = 0;
    public static final int FAILURE_RESULT = 1;
    public static final String PACKAGE_NAME =
        "com.google.android.gms.location.sample.locationaddress";
    public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
    public static final String RESULT_DATA_KEY = PACKAGE_NAME +
        ".RESULT_DATA_KEY";
    public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
        ".LOCATION_DATA_EXTRA";
}

為了獲取與地理位置相對(duì)應(yīng)的街道地址,調(diào)用 getFromLocation(),傳入位置對(duì)象的經(jīng)度和緯度,以及我們想要返回的地址的最大數(shù)量。在這種情況下,我們只需要一個(gè)地址。geocoder 返回一個(gè)地址數(shù)組。如果沒(méi)有找到匹配指定位置的地址,那么它會(huì)返回空的列表。如果沒(méi)有可用的后臺(tái)地理編碼服務(wù),geocoder 會(huì)返回 null。

如下面代碼介紹來(lái)檢查下述這些錯(cuò)誤。如果出現(xiàn)錯(cuò)誤,就將相應(yīng)的錯(cuò)誤信息傳給變量 errorMessage,從而將錯(cuò)誤信息發(fā)送給發(fā)出請(qǐng)求的 activity:

  • No location data provided - Intent 的附加數(shù)據(jù)沒(méi)有包含反向地理編碼需要用到的 Location 對(duì)象。
  • Invalid latitude or longitude used - Location 對(duì)象提供的緯度和/或者經(jīng)度無(wú)效。
  • No geocoder available - 由于網(wǎng)絡(luò)錯(cuò)誤或者 IO 異常,導(dǎo)致后臺(tái)地理編碼服務(wù)不可用。
  • Sorry, no address found - geocoder 找不到指定緯度/經(jīng)度對(duì)應(yīng)的地址。

使用 Address 類中的 getAddressLine() 方法來(lái)獲得地址對(duì)象的個(gè)別行。然后將這些行加入一個(gè)地址 fragment 列表當(dāng)中。其中,這個(gè)地址 fragment 列表準(zhǔn)備好返回到發(fā)出地址請(qǐng)求的 activity。

為了將結(jié)果返回給發(fā)出地址請(qǐng)求的 activity,需要調(diào)用 deliverResultToReceiver() 方法(定義于下面的把地址返回給請(qǐng)求端。結(jié)果由之前提到的成功/失敗數(shù)字代碼和一個(gè)字符串組成。在反向地理編碼成功的情況下,這個(gè)字符串包含著地址。在失敗的情況下,這個(gè)字符串包含錯(cuò)誤的信息。如下所示:

@Override
protected void onHandleIntent(Intent intent) {
    String errorMessage = "";

    // Get the location passed to this service through an extra.
    Location location = intent.getParcelableExtra(
            Constants.LOCATION_DATA_EXTRA);

    ...

    List<Address> addresses = null;

    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = getString(R.string.service_not_available);
        Log.e(TAG, errorMessage, ioException);
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = getString(R.string.invalid_lat_long_used);
        Log.e(TAG, errorMessage + ". " +
                "Latitude = " + location.getLatitude() +
                ", Longitude = " +
                location.getLongitude(), illegalArgumentException);
    }

    // Handle case where no address was found.
    if (addresses == null || addresses.size()  == 0) {
        if (errorMessage.isEmpty()) {
            errorMessage = getString(R.string.no_address_found);
            Log.e(TAG, errorMessage);
        }
        deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
    } else {
        Address address = addresses.get(0);
        ArrayList<String> addressFragments = new ArrayList<String>();

        // Fetch the address lines using getAddressLine,
        // join them, and send them to the thread.
        for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
            addressFragments.add(address.getAddressLine(i));
        }
        Log.i(TAG, getString(R.string.address_found));
        deliverResultToReceiver(Constants.SUCCESS_RESULT,
                TextUtils.join(System.getProperty("line.separator"),
                        addressFragments));
    }
}

把地址返回給請(qǐng)求端

Intent 服務(wù)最后要做的事情是將地址返回給啟動(dòng)服務(wù)的 activity 里的 ResultReceiver。這個(gè) ResultReceiver 類允許我們發(fā)送一個(gè)帶有結(jié)果的數(shù)字代碼和一個(gè)包含結(jié)果數(shù)據(jù)的消息。這個(gè)數(shù)字代碼說(shuō)明了地理編碼請(qǐng)求是成功還是失敗。在反向地理編碼成功的情況下,這個(gè)消息包含著地址。在失敗的情況下,這個(gè)消息包含一些描述失敗原因的文本。

我們已經(jīng)可以從 geocoder 取得地址,捕獲到可能出現(xiàn)的錯(cuò)誤,調(diào)用 deliverResultToReceiver() 方法?,F(xiàn)在我們需要定義 deliverResultToReceiver() 方法來(lái)將結(jié)果代碼和消息包發(fā)送給結(jié)果接收端。

對(duì)于結(jié)果代碼,使用已經(jīng)傳給 deliverResultToReceiver() 方法的 resultCode 參數(shù)的值。對(duì)于消息包的結(jié)構(gòu),連接 Constants 類的 RESULT_DATA_KEY 常量(定義與獲取街道地址數(shù)據(jù)和傳給 deliverResultToReceiver() 方法的 message 參數(shù)的值。如下所示:

public class FetchAddressIntentService extends IntentService {
    protected ResultReceiver mReceiver;
    ...
    private void deliverResultToReceiver(int resultCode, String message) {
        Bundle bundle = new Bundle();
        bundle.putString(Constants.RESULT_DATA_KEY, message);
        mReceiver.send(resultCode, bundle);
    }
}

啟動(dòng) Intent 服務(wù)

上節(jié)課定義的 intent 服務(wù)在后臺(tái)運(yùn)行,同時(shí),該服務(wù)負(fù)責(zé)提取與指定地理位置相對(duì)應(yīng)的地址。當(dāng)我們啟動(dòng)服務(wù),Android 框架會(huì)實(shí)例化并啟動(dòng)服務(wù)(如果該服務(wù)沒(méi)有運(yùn)行),并且如果需要的話,創(chuàng)建一個(gè)進(jìn)程。如果服務(wù)正在運(yùn)行,那么讓它保持運(yùn)行狀態(tài)。因?yàn)榉?wù)繼承于 IntentService,所以當(dāng)所有 intent 都被處理完之后,該服務(wù)會(huì)自動(dòng)停止。

在我們應(yīng)用的主 activity 中啟動(dòng)服務(wù),并且創(chuàng)建一個(gè) Intent 來(lái)把數(shù)據(jù)傳給服務(wù)。我們需要?jiǎng)?chuàng)建一個(gè)顯式的 intent,這是因?yàn)槲覀冎幌胛覀兊姆?wù)響應(yīng)該 intent。詳細(xì)請(qǐng)見(jiàn) Intent Types。

為了創(chuàng)建一個(gè)顯式的 intent,需要為服務(wù)指定要用到的類名:FetchAddressIntentService.class。在 intent 附加數(shù)據(jù)中傳入兩個(gè)信息:

  • 一個(gè)用于處理地址查找結(jié)果的 ResultReceiver。
  • 一個(gè)包含想要轉(zhuǎn)換成地址的緯度和經(jīng)度的 Location 對(duì)象。

下面的代碼介紹了如何啟動(dòng) intent 服務(wù):

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {

    protected Location mLastLocation;
    private AddressResultReceiver mResultReceiver;
    ...

    protected void startIntentService() {
        Intent intent = new Intent(this, FetchAddressIntentService.class);
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
        startService(intent);
    }
}

當(dāng)用戶請(qǐng)求查找地理地址時(shí),調(diào)用上述的 startIntentService() 方法。例如,用戶可能會(huì)在我們應(yīng)用的 UI 上面點(diǎn)擊提取地址按鈕。在啟動(dòng) intent 服務(wù)之前,我們需要檢查是否已經(jīng)連接到 Google Play services。下面的代碼片段介紹在一個(gè)按鈕 handler 中調(diào)用 startIntentService() 方法。

public void fetchAddressButtonHandler(View view) {
    // Only start the service to fetch the address if GoogleApiClient is
    // connected.
    if (mGoogleApiClient.isConnected() && mLastLocation != null) {
        startIntentService();
    }
    // If GoogleApiClient isn't connected, process the user's request by
    // setting mAddressRequested to true. Later, when GoogleApiClient connects,
    // launch the service to fetch the address. As far as the user is
    // concerned, pressing the Fetch Address button
    // immediately kicks off the process of getting the address.
    mAddressRequested = true;
    updateUIWidgets();
}

如果用戶點(diǎn)擊了應(yīng)用 UI 上面的提取地址按鈕,那么我們必須在 Google Play services 連接穩(wěn)定之后啟動(dòng) intent 服務(wù)。下面的代碼片段介紹了調(diào)用 Google API Client 提供的 onConnected() 回調(diào)函數(shù)中的 startIntentService() 方法。

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    @Override
    public void onConnected(Bundle connectionHint) {
        // Gets the best and most recent location currently available,
        // which may be null in rare cases when a location is not available.
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);

        if (mLastLocation != null) {
            // Determine whether a Geocoder is available.
            if (!Geocoder.isPresent()) {
                Toast.makeText(this, R.string.no_geocoder_available,
                        Toast.LENGTH_LONG).show();
                return;
            }

            if (mAddressRequested) {
                startIntentService();
            }
        }
    }
}

獲取地理編碼結(jié)果

Intent 服務(wù)已經(jīng)處理完地理編碼請(qǐng)求,并用 ResultReceiver 將結(jié)果返回給發(fā)出請(qǐng)求的 activity。在發(fā)出請(qǐng)求的 activity 里,定義一個(gè)繼承于 ResultReceiverAddressResultReceiver,用于處理在 FetchAddressIntentService 中的響應(yīng)。

結(jié)果包含一個(gè)數(shù)字代碼(resultCode)和一個(gè)包含結(jié)果數(shù)據(jù)(resultData)的消息。如果反向地理編碼成功的話,resultData 會(huì)包含地址。如果失敗,resultData 包含描述失敗原因的文本。關(guān)于錯(cuò)誤信息更詳細(xì)的內(nèi)容,請(qǐng)見(jiàn)把地址返回給請(qǐng)求端

重寫 onReceiveResult() 方法來(lái)處理發(fā)送給接收端的結(jié)果,如下所示:

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener {
    ...
    class AddressResultReceiver extends ResultReceiver {
        public AddressResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            // Display the address string
            // or an error message sent from the intent service.
            mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
            displayAddressOutput();

            // Show a toast message if an address was found.
            if (resultCode == Constants.SUCCESS_RESULT) {
                showToast(getString(R.string.address_found));
            }

        }
    }
}