2014-10-08 113 views
0

我一直在試圖獲取當前用戶位置。我打開GPS並啓動應用程序。一切似乎都沒問題,我可以得到當前的用戶位置。onLocationChanged甚至在GPS關閉時調用

問題是當我關閉GPS並運行應用程序。調用onLocationChanged。是否應該在GPS關閉的情況下調用?如果是這樣,爲什麼?

package company.com.locationservicesapi; 

import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.provider.Settings; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.TextView; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.common.api.PendingResult; 
import com.google.android.gms.common.api.Status; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

public class LocationServicesAPIActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { 
    private static final String TAG = "Location Service API"; 
    GoogleApiClient googleApiClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
      Log.i(TAG, "GPS turned on"); 
     } else { 
      Log.i(TAG, "GPS turned off"); 
     } 

     setContentView(R.layout.activity_location_services_api); 
     int result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
     if (result == ConnectionResult.SUCCESS) { 
      googleApiClient = new GoogleApiClient.Builder(this) 
        .addApi(LocationServices.API) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .build(); 
      googleApiClient.connect(); 
     } else { 
      GooglePlayServicesUtil.getErrorDialog(result, this, 1).show(); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.location_services_api, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.d(TAG, "Connected"); 
     LocationRequest locationRequest = LocationRequest.create() 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
       .setInterval(1000) 
       .setNumUpdates(1); 

     LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this); 
    } 

    public void onLocationChanged(Location location) { 
     Log.d(TAG, "Location Changed"); 
     TextView textView = (TextView) findViewById(R.id.textViewLocation); 
     textView.setText('@' + location.getLatitude() + "," + location.getLongitude()); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.d(TAG, "Connection Suspended"); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.d(TAG, "Connection Failed"); 
    } 
} 

activity_location_services_api.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context=".LocationServicesAPIActivity"> 

    <TextView 
     android:id="@+id/textViewLocation" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</RelativeLayout> 

的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="company.com.locationservicesapi"> 

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

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 
     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 

     <activity 
      android:name=".LocationServicesAPIActivity" 
      android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

logcat的輸出:

10-08 14:18:34.242 4208-4208/company.com.locationservicesapi I/Location Service API﹕ GPS turned off 
10-08 14:18:34.625 4208-4208/company.com.locationservicesapi D/Location Service API﹕ Connected 
10-08 14:18:35.765 4208-4208/company.com.locationservicesapi D/Location Service API﹕ Location Changed 
+0

不知道如果是這樣的話,但你可以檢索從蜂窩網絡的位置。它不是那麼準確,但是因爲你包含粗略和精細位置的權限,所以它可能會從那裏獲得它。 – dharms 2014-10-08 17:30:58

+0

如果我只有「android.permission.ACCESS_FINE_LOCATION」給出上述相同的行爲。如果我只有「android.permission.ACCESS_COARSE_LOCATION」,則應用程序會崩潰,出現異常:「java.lang.SecurityException:提供者gps需要ACCESS_FINE_LOCATION權限」。 – 2014-10-08 17:38:49

回答

0

FusedLocationApi不只是打電話onLocationChanged()當有效的GPS信號可用時。它使用WFPS,Cell-ID和傳感器來獲取有效位置。這就是FusedLocationApi的全部內容:使用設備的所有可能性獲取最準確的位置。

如果你只是想聽GPS信號,那麼唯一的辦法就是使用LocationManager,標記LocationManager.GPS_PROVIDER作爲你的提供者。

+0

不推薦使用嗎?如果我沒有錯過任何東西,我已閱讀了當前的API來自Google Play服務。 – 2014-10-08 17:46:24

+1

LocationManager不是,AFAICT永遠不會被棄用。 FusedLocationApi只不過是LocationManager的一個包裝器(作爲之前的LocationClient,已被棄用)。 – 2014-10-08 17:49:39

0

你在你的清單裏有<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />,所以它會使用網絡來訪問大概的位置。請參閱android manifest description

您可以在每次沒有任何連接時刪除位置更新。剛剛宣佈private LocationManager locationManager;第一,把

locationManager.removeUpdates(this); 
this.locationManager = null; 

public void onConnectionFailed(ConnectionResult connectionResult)

我希望這有助於

相關問題