0

您好我目前正在嘗試使用GoogleApiClient獲取我的Android設備的緯度和高度值。我一直在這裏跟隨指南:Android:使用GoogleApiClient時的空位置

GoogleApiClient: Last Known Location Guide

我也想從我的服務,而不是活動做到這一點,這裏是我的代碼以供參考片段:

public class AppService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { 

private GoogleApiClient googleApiClient; 

@Override 
public IBinder onBind(Intent arg0) { 
    return null; 
} 

@Override 
public int onStartCommand(final Intent intent, int flags, int startId) { 
    if (googleApiClient == null) { 
     googleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 
    googleApiClient.connect(); 
    try { 
     Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); 
     Log.d("location", String.valueOf(lastLocation.getLatitude())); 
     Log.d("location", String.valueOf(lastLocation.getLongitude())); 
    } catch (SecurityException e) { 
     Log.e("Location error", "Location object is null."); 
    } 

    googleApiClient.disconnect(); 

    //Stop service once it finishes its task 
    stopSelf(); 
    return Service.START_STICKY; 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 

} 

@Override 
public void onConnectionSuspended(int i) { 

} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

} 
} 

每次我嘗試訪問Location變量來獲取緯度和高度時,我都會得到一個NullPointerException,爲什麼?

還希望包括我的AndroidManifest文件,以防萬一,我有所需的權限,據我所知:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="app" 
     android:versionCode="1" 
     android:versionName="1.0" > 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
<application android:label="@string/app_name" > 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" 
     android:theme="@style/Theme.AppCompat.Light"> 
     <intent-filter> 
      <action android:name="android.intent.action.BOOT_COMPLETED" /> 
     </intent-filter> 
    </activity> 
    <receiver 
      android:name=".AutoStart" 
      android:enabled="true" > 
     <intent-filter> 
      <action android:name="android.intent.action.BOOT_COMPLETED" /> 
      <action android:name="android.intent.action.QUICKBOOT_POWERON" /> 
     </intent-filter> 
    </receiver> 
    <service android:name=".AppService"/> 
</application> 
</manifest> 
+0

您是否使用運行時權限? –

+0

如果我的應用程序沒有用戶界面,這會工作嗎?該應用程序旨在作爲後臺服務運行。 – Tuco

回答

1

googleApiClient.connect()調用根據文檔是異步的:

public abstract void connect()

將客戶端連接到Google Play服務。此方法立即返回 ,並在後臺連接到該服務。如果 連接成功,則調用onConnected(Bundle),並且將執行 個項目。在失敗時,調用onConnectionFailed(ConnectionResult) 。

如果客戶端已經連接或連接,此方法沒有任何內容 。

因此,您應該等待onConnected回調被執行,並將您的位置檢索代碼放在那裏。

@Override 
public int onStartCommand(final Intent intent, int flags, int startId) { 
    if (googleApiClient == null) { 
    googleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
    } 
    googleApiClient.connect(); 
    return Service.START_STICKY; 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 
    try { 
    Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); 
    Log.d("location", String.valueOf(lastLocation.getLatitude())); 
    Log.d("location", String.valueOf(lastLocation.getLongitude())); 
    } catch (SecurityException e) { 
    Log.e("Location error", "Location object is null."); 
    } 

    googleApiClient.disconnect(); 
    stopSelf(); 
} 
+0

哦,我明白了,如果我需要在我的服務中使用緯度和高度值,該怎麼辦?獲得這些值後,我需要在我的服務的OnStartCommand方法內創建的線程中使用它們: 'Thread thread = new Thread(new Runnable(){ @Override public void run(){ // Application邏輯,我需要使用值 } }); thread.start();' – Tuco

+0

我發佈瞭解決方案。您需要等待google api客戶端連接,然後才能從中檢索位置。那麼你應該開始你的線程,只要你真的有位置,而不是當你開始你的服務。 –

相關問題