注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/location/retrieve-current.html
地點(diǎn)服務(wù)自動維護(hù)用戶當(dāng)前的地點(diǎn),所以你的應(yīng)用所要做的事情就是在需要時去獲取它。地點(diǎn)的精確度是基于你所申請的地點(diǎn)查詢權(quán)限,以及當(dāng)前設(shè)備上激活的的位置傳感器。
地點(diǎn)服務(wù)會通過定位客戶端(定位服務(wù)類的一個實(shí)例:
LocationClient
),將當(dāng)前的位置發(fā)送給你的應(yīng)用,所有地點(diǎn)信息的請求都通過這一客戶端。
Note:
在你開始這節(jié)課之前,請確定你的開發(fā)環(huán)境和測試設(shè)備都已經(jīng)配置正確。可以閱讀 Setup 獲取更多這方面的信息。
一). 指定應(yīng)用權(quán)限
使用位置服務(wù)的應(yīng)用必須請求定位權(quán)限。Android有兩個定位權(quán)限: ACCESS_COARSE_LOCATION (粗定位)和 ACCESS_FINE_LOCATION (精定位)。你所選擇的權(quán)限決定了定位的精度。如果你只請求粗定位,位置服務(wù)所范圍的地點(diǎn)信息大致會精確到一個城市街區(qū)。
如果請求 ACCESS_FINE_LOCATION ,它也暗含了 ACCESS_COARSE_LOCATION 的權(quán)限。
例如,要添加
ACCESS_COARSE_LOCATION
,將下面的代碼作為
<manifest>
元素的子元素:
< uses-permission android:name ="android.permission.ACCESS_COARSE_LOCATION" />
二). 檢查Google Play服務(wù)
位置服務(wù)是Google Play服務(wù)APK的其中一部分。由于用戶設(shè)備的狀態(tài)時難以預(yù)料的,你應(yīng)該一直在你嘗試連接定位服務(wù)之前,檢查APK是否已經(jīng)安裝。要檢查APK是否安裝,可以調(diào)用
GooglePlayServicesUtil.isGooglePlayServicesAvailable()
,它會返回一個整形的結(jié)果碼,其含義可以參閱:
ConnectionResult
。如果你遇到了一個錯誤,可以調(diào)用
GooglePlayServicesUtil.getErrorDialog()
,來獲取一個本地的對話框,引導(dǎo)用戶執(zhí)行正確地行為,之后將這一對話框顯示在一個
DialogFragment
上。這一對話框可能允許用戶解決當(dāng)前的問題,此時Google Play服務(wù)會發(fā)回一個結(jié)果到你的activity中。要處理這一結(jié)果,需要覆寫
onActivityResult()
方法。
由于你一直需要在你的代碼多個地方檢查Google Play服務(wù),所以應(yīng)該定義一個方法將檢查行為進(jìn)行封裝,之后在每次連接嘗試之前進(jìn)行檢查。下面的代碼片段包含了檢查Google Play服務(wù)所需要的代碼:
public class MainActivity extends FragmentActivity { ... // Global constants /* * Define a request code to send to Google Play services * This code is returned in Activity.onActivityResult */ private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000 ; ... // Define a DialogFragment that displays the error dialog public static class ErrorDialogFragment extends DialogFragment { // Global field to contain the error dialog private Dialog mDialog; // Default constructor. Sets the dialog field to null public ErrorDialogFragment() { super (); mDialog = null ; } // Set the dialog to display public void setDialog(Dialog dialog) { mDialog = dialog; } // Return a Dialog to the DialogFragment. @Override public Dialog onCreateDialog(Bundle savedInstanceState) { return mDialog; } } ... /* * Handle results returned to the FragmentActivity * by Google Play services */ @Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { // Decide what to do based on the original request code switch (requestCode) { ... case CONNECTION_FAILURE_RESOLUTION_REQUEST : /* * If the result code is Activity.RESULT_OK, try * to connect again */ switch (resultCode) { case Activity.RESULT_OK : /* * Try the request again */ ... break ; } ... } } ... private boolean servicesConnected() { // Check that Google Play services is available int resultCode = GooglePlayServicesUtil. isGooglePlayServicesAvailable( this ); // If Google Play services is available if (ConnectionResult.SUCCESS == resultCode) { // In debug mode, log the status Log.d("Location Updates" , "Google Play services is available." ); // Continue return true ; // Google Play services was not available for some reason } else { // Get the error code int errorCode = connectionResult.getErrorCode(); // Get the error dialog from Google Play services Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog( errorCode, this , CONNECTION_FAILURE_RESOLUTION_REQUEST); // If Google Play services can provide an error dialog if (errorDialog != null ) { // Create a new DialogFragment for the error dialog ErrorDialogFragment errorFragment = new ErrorDialogFragment(); // Set the dialog in the DialogFragment errorFragment.setDialog(errorDialog); // Show the error dialog in the DialogFragment errorFragment.show(getSupportFragmentManager(), "Location Updates" ); } } } ... }
在后續(xù)章節(jié)的代碼片段中,都會調(diào)用這一方法來驗(yàn)證是否可獲取Google Play服務(wù)。
三). 定義位置服務(wù)回調(diào)函數(shù)
要獲取當(dāng)前的地點(diǎn),創(chuàng)建一個地點(diǎn)客戶端,將它連接至定位服務(wù),之后調(diào)用它的 getLastLocation() 方法。返回的值是最佳最新的地理位置,它基于你應(yīng)用所請求的權(quán)限以及當(dāng)前設(shè)備上已激活的定位傳感器。
在你創(chuàng)建定位客戶端之前,實(shí)現(xiàn)定位服務(wù)的接口,以和你的應(yīng)用進(jìn)行交互:
指定當(dāng)定位連接上或者沒有連接上時,定位服務(wù)調(diào)用的方法。
指定當(dāng)嘗試連接到定位客戶端時,如果出現(xiàn)了錯誤,定位服務(wù)調(diào)用的方法。這一方法使用之前定義的 showErrorDialog 方法來顯示一個錯誤對話框,它嘗試使用Google Play服務(wù)來解決這一問題。
下面的樣例代碼展示了如何指定接口和定義相關(guān)的函數(shù):
public class MainActivity extends FragmentActivity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener { ... /* * Called by Location Services when the request to connect the * client finishes successfully. At this point, you can * request the current location or start periodic updates */ @Override public void onConnected(Bundle dataBundle) { // Display the connection status Toast.makeText( this , "Connected" , Toast.LENGTH_SHORT).show(); } ... /* * Called by Location Services if the connection to the * location client drops because of an error. */ @Override public void onDisconnected() { // Display the connection status Toast.makeText( this , "Disconnected. Please re-connect." , Toast.LENGTH_SHORT).show(); } ... /* * Called by Location Services if the attempt to * Location Services fails. */ @Override public void onConnectionFailed(ConnectionResult connectionResult) { /* * Google Play services can resolve some errors it detects. * If the error has a resolution, try sending an Intent to * start a Google Play services activity that can resolve * error. */ if (connectionResult.hasResolution()) { try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult( this , CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (IntentSender.SendIntentException e) { // Log the error e.printStackTrace(); } } else { /* * If no resolution is available, display a dialog to the * user with the error. */ showErrorDialog(connectionResult.getErrorCode()); } } ... }
四). 連接定位客戶端
現(xiàn)在回調(diào)函數(shù)已經(jīng)就位了,創(chuàng)建定位客戶端并且連接它至定位服務(wù)。
你應(yīng)該在 onCreate() 方法中創(chuàng)建定位客戶端,之后再 onStart() 方法中進(jìn)行連接。這樣定位服務(wù)就能在你的應(yīng)用完全可見時維護(hù)當(dāng)前的定位信息。在 onStop() 方法中關(guān)閉連接,這樣當(dāng)應(yīng)用不可見時,定位服務(wù)就會停止更新地點(diǎn)。這樣的連接方式還能節(jié)省電量。
Note:
只有在定位客戶端連接到了定位服務(wù)后,當(dāng)前的地點(diǎn)才能維護(hù)。假設(shè)沒有其他應(yīng)用連接到定位服務(wù),如果你關(guān)閉了客戶端,過一段時間后,調(diào)用了 getLastLocation() ,獲得的結(jié)果可能將是過期的。
例如:
public class MainActivity extends FragmentActivity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener { ... @Override protected void onCreate(Bundle savedInstanceState) { ... /* * Create a new location client, using the enclosing class to * handle callbacks. */ mLocationClient = new LocationClient( this , this , this ); ... } ... /* * Called when the Activity becomes visible. */ @Override protected void onStart() { super .onStart(); // Connect the client. mLocationClient.connect(); } ... /* * Called when the Activity is no longer visible. */ @Override protected void onStop() { // Disconnecting the client invalidates it. mLocationClient.disconnect(); super .onStop(); } ... }
五). 獲取當(dāng)前地點(diǎn)
要獲取當(dāng)前地點(diǎn),調(diào)用 getLastLocation() ,例如:
public class MainActivity extends FragmentActivity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener { ... // Global variable to hold the current location Location mCurrentLocation; ... mCurrentLocation = mLocationClient.getLastLocation(); ... }
在下一節(jié)課中,將會向你展示從定位服務(wù)定期地接受地點(diǎn)更新的方法。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
