Android LocationClient getLastLocation()返回null
就像以前遇到的问题一样 我测试了nexus s(提供google play服务的4.0.4)和avd(使用google api的4.2.2),在这两种情况下locationclient的Android LocationClient getLastLocation()返回null,android,gps,location,Android,Gps,Location,就像以前遇到的问题一样 我测试了nexus s(提供google play服务的4.0.4)和avd(使用google api的4.2.2),在这两种情况下locationclient的getLastLocation()始终返回null public class MainActivity extends Activity implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks,
getLastLocation()
始终返回null
public class MainActivity extends Activity implements LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
boolean mUpdatesRequested = false;
boolean mConnected = false;
SharedPreferences mPrefs;
SharedPreferences.Editor mEditor;
private TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView) findViewById(R.id.text);
mLocationRequest = LocationRequest.create();
mLocationRequest
.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest
.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mUpdatesRequested = false;
mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES,
Context.MODE_PRIVATE);
mEditor = mPrefs.edit();
mLocationClient = new LocationClient(this, this, this);
}
@Override
public void onStart() {
super.onStart();
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
mLocationClient.connect();
}
@Override
protected void onResume() {
super.onResume();
// If the app already has a setting for getting location updates, get it
if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) {
mUpdatesRequested = mPrefs.getBoolean(
LocationUtils.KEY_UPDATES_REQUESTED, false);
// Otherwise, turn off location updates until requested
} else {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
mEditor.commit();
}
}
@Override
public void onStop() {
// If the client is connected
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
// After disconnect() is called, the client is considered "dead".
mLocationClient.disconnect();
super.onStop();
}
@Override
public void onPause() {
// Save the current setting for updates
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED,
mUpdatesRequested);
mEditor.commit();
super.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void getLocation(View v) {
// If Google Play Services is available
if (isGooglePlayServicesAvailable()) {
if (!mConnected)
mText.setText("location client is not connected to service yet");
else {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
// Display the current location in the UI
mText.setText(LocationUtils.getLocationString(currentLocation));
}
}
}
private boolean isGooglePlayServicesAvailable() {
// 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(LocationUtils.APPTAG, "google play service is available");
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode,
this, 0);
if (dialog != null) {
Log.e(LocationUtils.APPTAG,
"google play service is unavailable");
}
return false;
}
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
// mConnectionState.setText(R.string.location_updates_stopped);
}
@Override
public void onConnectionFailed(ConnectionResult arg0) {
mConnected = false;
Log.d(LocationUtils.APPTAG, "connection failed");
}
@Override
public void onConnected(Bundle arg0) {
mConnected = true;
Log.d(LocationUtils.APPTAG,
"location client connected to the location server");
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0,
new android.location.LocationListener() {
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onLocationChanged(final Location location) {
}
});
Log.d(LocationUtils.APPTAG, "done trying to get location");
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
mConnected = false;
Log.d(LocationUtils.APPTAG,
"location client disconnected from the location server");
}
@Override
public void onLocationChanged(Location arg0) {}
}
其中大部分来自谷歌给出的例子。在上面的代码中,hava尝试了如下方法:
LocationRequest request = LocationRequest.create();
request.setNumUpdates(1);
mLocationClient.requestLocationUpdates(request, this);
及
在调用getLastLocation()
之前,在onConnected()
中,但仍然没有运气。
错误在哪里,请提前感谢。您必须检查用户是否通过Wi-Fi/GSM或GPS启用了定位功能。如果没有任何可用的位置提供程序,则会得到
null
public class MainActivity extends Activity implements LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
boolean mUpdatesRequested = false;
boolean mConnected = false;
SharedPreferences mPrefs;
SharedPreferences.Editor mEditor;
private TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView) findViewById(R.id.text);
mLocationRequest = LocationRequest.create();
mLocationRequest
.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest
.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mUpdatesRequested = false;
mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES,
Context.MODE_PRIVATE);
mEditor = mPrefs.edit();
mLocationClient = new LocationClient(this, this, this);
}
@Override
public void onStart() {
super.onStart();
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
mLocationClient.connect();
}
@Override
protected void onResume() {
super.onResume();
// If the app already has a setting for getting location updates, get it
if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) {
mUpdatesRequested = mPrefs.getBoolean(
LocationUtils.KEY_UPDATES_REQUESTED, false);
// Otherwise, turn off location updates until requested
} else {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
mEditor.commit();
}
}
@Override
public void onStop() {
// If the client is connected
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
// After disconnect() is called, the client is considered "dead".
mLocationClient.disconnect();
super.onStop();
}
@Override
public void onPause() {
// Save the current setting for updates
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED,
mUpdatesRequested);
mEditor.commit();
super.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void getLocation(View v) {
// If Google Play Services is available
if (isGooglePlayServicesAvailable()) {
if (!mConnected)
mText.setText("location client is not connected to service yet");
else {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
// Display the current location in the UI
mText.setText(LocationUtils.getLocationString(currentLocation));
}
}
}
private boolean isGooglePlayServicesAvailable() {
// 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(LocationUtils.APPTAG, "google play service is available");
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode,
this, 0);
if (dialog != null) {
Log.e(LocationUtils.APPTAG,
"google play service is unavailable");
}
return false;
}
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
// mConnectionState.setText(R.string.location_updates_stopped);
}
@Override
public void onConnectionFailed(ConnectionResult arg0) {
mConnected = false;
Log.d(LocationUtils.APPTAG, "connection failed");
}
@Override
public void onConnected(Bundle arg0) {
mConnected = true;
Log.d(LocationUtils.APPTAG,
"location client connected to the location server");
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0,
new android.location.LocationListener() {
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onLocationChanged(final Location location) {
}
});
Log.d(LocationUtils.APPTAG, "done trying to get location");
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
mConnected = false;
Log.d(LocationUtils.APPTAG,
"location client disconnected from the location server");
}
@Override
public void onLocationChanged(Location arg0) {}
}
此代码显示带有位置设置的屏幕:
startActivity(新意图(设置、动作、位置、源设置));
当前,如果至少有一个客户端连接到融合位置提供程序,则融合位置提供程序将只维护后台位置。一旦第一个客户端连接,它将立即尝试获取位置。如果您的活动是第一个连接的客户端,并且您立即在onConnected()
中调用getLastLocation()
,那么可能没有足够的时间让第一个位置进入。我在三星手机的测试中遇到了类似的问题(高度定制的android,没有开发人员支持)
LocationManager和LocationClient无法从提供商处获得GPS。每次你需要他们的位置时,他们都需要被踢。在调用LocationManager.getLastKnownLocation
或LocationClient.getLastLocation
之前执行此操作。这些API将返回
YOUR_APPLICATION_CONTEXT.getLocationManager().requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(final Location location) {
}
});
我也面临着类似的问题 在连接的
onConnected
中调用mLocationClient.getLastLocation()
,或在与Google Play服务建立连接后调用。如果在连接Location客户端之前调用此方法,则返回的位置将为null
您可以检查位置客户端是否通过mLocationClient.isConnected()
连接
希望这能有所帮助。我在Nexus 7设备上运行,工作非常完美。 你们错误地编写了旧版本的LocationListener,它没有与新API一起使用 您必须设置新的LocationListener 您需要导入此类,然后重试
import com.google.android.gms.location.LocationListener;
根据新的API,它覆盖了唯一的一个方法
@Override
public void onLocationChanged(final Location newLocation)
{}
请尝试这种方式,如果您仍然面临任何问题,请告诉我
谢谢。谷歌play服务地理定位如果没有互联网连接就无法工作,对GPS来说就不重要了。所以,请在手机数据打开的情况下检查应用程序 我的应用程序也面临着同样的问题,唯一缺少的是该应用程序只请求访问粗略位置,而不请求访问精细位置。
我添加了稍后的权限,一切正常。问题也可能是由于您的设备未启用“Wi-Fi和移动网络位置” LocationClient(融合位置提供商)同时使用GPS和WiFi。GPS需要一段时间才能找到你的位置,而wifi要快得多。但是,如果这两个服务中的任何一个已连接,则将调用回调方法onConnected。如果您试图立即在OnConnect方法中调用LocationClient.getLastLocation(),则如果禁用wifi定位服务,则很可能会得到空值。这仅仅是因为GPS的速度不够快 要在本地解决问题,请启用“Wi-Fi和移动网络定位”。您可以通过进入“设置>个人>位置访问>Wi-Fi和移动网络位置”来完成此操作 但是,如果要为应用程序的用户解决此问题,最好检查getLastLocation()是否返回null。如果确实如此,请像谷歌地图一样提示用户启用该服务
希望这能有所帮助 我在遵循来自的说明时遇到了相同的问题。 在手机上它工作,在(Genymotion)模拟器上它没有 解决方案 在AndroidManifest.xml中,更改以下内容:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
为此:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
…你马上就能找到位置。无需更改代码(以收听位置更新)。最简单的修复方法是使用帮助函数,尽管速度会减慢一点。我的问题是它会连接,但在找到位置之前,我会尝试访问它并点击空指针
public Location getLocation(LocationClient locationClient){
if(locationClient.getLastLocation() == null){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return getLocation(locationClient);
}else{
return locationClient.getLastLocation();
}
}
只需在onConnected
中使用此函数,并通过location客户端设置您想要的位置
@Override
public void onConnected(Bundle dataBundle) {
Location temp = getLocation(mLocationClient);
mLocation = temp;
}
此外,如果出于任何原因不想从连接的onConnected
获取位置,只要在SDK版本23上传递locationClient
,您就可以在任何地方使用相同的helper函数
您还需要在运行时明确请求位置权限,如
以及将其保存在清单文件中
如果您在运行时没有权限,则不会发生显式错误,位置提供程序将只返回null
如果谷歌记录了这一点,并抛出一个异常,而不仅仅是返回null,这将有所帮助。在这种情况下,返回null几乎是最没有帮助的事情。这正是有效的解决方案,可能在稍微不同的情况下。但我想添加一些小的解释步骤,以便任何人都能得到确切的概念: 1) 一旦创建Android组件(例如,活动,片段或服务。注意:不是IntentService),构建,然后连接GoogleAppClient,如下所示
buildGoogleApiClient();
mGoogleApiClient.connect();
其中,buildGoogleAppClient()实现是
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
稍后在onDestroy()上,您可以断开GoogleAppClient,如下所示:
@Override
public void onDestroy() {
Log.i(TAG, "Service destroyed!");
mGoogleApiClient.disconnect();
super.onDestroy();
}
步骤1确保您构建并连接GoogleAppClient。
1) GoogleAppClient实例首次获得co
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.i(TAG, "GoogleApiClient connected!");
buildLocationSettingsRequest();
createLocationRequest();
location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.i(TAG, " Location: " + location); //may return **null** because, I can't guarantee location has been changed immmediately
}
protected void createLocationRequest() {
//remove location updates so that it resets
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); //Import should not be **android.Location.LocationListener**
//import should be **import com.google.android.gms.location.LocationListener**;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//restart location updates with the new interval
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "Location Changed!");
Log.i(TAG, " Location: " + location); //I guarantee,I get the changed location here
}
compile 'com.google.android.gms:play-services-location:10.2.1'
private void setLocation(Context context) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(2000);
locationRequest.setFastestInterval(2000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
showMessage(" All location settings are satisfied.");
mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallbacks)
.addOnConnectionFailedListener(connectionFailedListener)
.build();
mGoogleApiClient.connect();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
l.a(" Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
showMessage("PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
showMessage("Location settings are inadequate, and cannot be fixed here. Dialog not created.");
break;
}
}
});
}
@Override
public void onConnected(@Nullable Bundle bundle) {
l.a(3232);
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if(null==mLastLocation){// !!!!!!!!!!!! here it can happen !!!!!!!
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
locationWasFound = true;
sevumPora.setLocation(mLastLocation);
mGoogleApiClient.disconnect();
}
});
return;
}
locationWasFound = true;
sevumPora.setLocation(mLastLocation);
mGoogleApiClient.disconnect();
}