LocationClient getLastLocation()返回null
就像我在testing一个nexus s(4.0.4提供google play服务)和avd(4.2.2 with google api)之前遇到的问题一样,在这两种情况下,locationclient的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);
和
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) {} });
在调用getLastLocation()
onConnected()
之前在onConnected()
,但仍然没有运气。 哪里错了,提前致谢。
目前,如果至less有一个客户端连接到Fused Location Provider
则只能保持后台位置。 一旦第一个客户端连接,它将立即尝试获得一个位置。 如果您的活动是第一个连接的客户端,并且您立即在onConnected()
调用getLastLocation()
,那么第一个位置可能不够用。
按照教程的指示,我遇到了同样的问题。 在电话上,它的工作和(Genymotion)模拟器没有。
解
在你的AndroidManifest.xml中,改变这个:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
对此:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
…你立即得到的位置。 无需更改您的代码(以侦听位置更新)。
该问题也可能是由于您的设备没有启用“Wi-Fi和移动networking位置”引起的。
LocationClient(融合的位置提供商)使用GPS和WiFi。 GPS需要一段时间才能find你的位置,而无线networking要快得多。 但是,如果连接了这两个服务中的任何一个,就会调用onConnected的callback方法。 如果您正尝试立即在onConnected方法中调用LocationClient.getLastLocation(),那么如果您的wifi位置服务被禁用,则最有可能得到空值。 这仅仅是因为GPS速度不够快。
要在本地解决问题,请启用“Wi-Fi和移动networking位置”。 您可以转到“设置>个人>位置访问> Wi-Fi和移动networking位置”。
但是,如果要为应用程序的用户解决问题,最好检查getLastLocation()是否返回null。 如果是这样,请提示您的用户启用服务,就像谷歌地图。
希望这有助于
我正面临类似的问题。
在onConnected
或在build立与Google Play服务的连接后,拨打mLocationClient.getLastLocation()
。 如果您在位置客户端连接之前调用此方法,则返回的位置将为null
。
您可以通过mLocationClient.isConnected()
来检查位置客户端是否连接。
希望这可以帮助。
您必须检查用户是否通过Wi-Fi / GSM或GPS启用了位置。 如果没有任何可用的位置提供程序,则会得到null
。
此代码显示具有位置设置的屏幕:
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
我在testing三星手机时遇到了类似的问题(高度自定义的android,没有开发者支持)。
LocationManager和LocationClient不从提供者获取GPS。 他们需要每当你需要从他们的位置开始kickstarted。 在您的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) { } });
在SDK版本23上
您还需要在运行时显式请求位置权限 ,如https://developer.android.com/training/permissions/requesting.html以及清单文件中所示。;
如果您在运行时没有权限,则不会发生明确的错误,位置提供程序将只返回null。
如果Googlelogging这一点,这将有所帮助,并且抛出exception而不是仅仅返回null。 在这种情况下,返回null是最没有帮助的事情。
这是完全可行的解决scheme,很可能在稍有不同的情况下。 但是我想添加一些小的解释步骤,以便任何人都能得到确切的概念:
1)Android组件的onCreate()(例如, Activity , Fragment或者Service 。 注意:不是IntentService ),按如下方式构build并连接 GoogleApiClient。
buildGoogleApiClient(); mGoogleApiClient.connect();
其中,构buildGoogleApiClient()的实现是,
protected synchronized void buildGoogleApiClient() { Log.i(TAG, "Building GoogleApiClient"); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); }
稍后onDestroy(),你可以断开连接的GoogleApiClient,
@Override public void onDestroy() { Log.i(TAG, "Service destroyed!"); mGoogleApiClient.disconnect(); super.onDestroy(); }
第1步确保您构build并连接GoogleApiClient。
1)首次将GoogleApiClient实例连接到onConnected()方法上。 现在,你的下一步应该看onConnected()方法。
@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 }
上面,你调用了一个方法createLocationRequest()来创build位置请求。 createLocationRequest()方法如下所示。
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); }
3)现在,在LocationListener接口的onLocationChange()callback函数中,获取新的位置。
@Override public void onLocationChanged(Location location) { Log.i(TAG, "Location Changed!"); Log.i(TAG, " Location: " + location); //I guarantee,I get the changed location here }
在Logcat: 03-22 18:34:17.336 817-817 / com.LiveEarthquakesAlerts I / LocationTracker:Location:Location [fused 37.421998,-122.084000 acc = 20 et = + 15m35s840ms alt = 0.0]
为了能够完成这三个步骤,你应该已经configuration了你的build.gradle,如下所示:
compile 'com.google.android.gms:play-services-location:10.2.1'
我也在我的应用程序面临同样的问题,唯一缺less的是,该应用程序只请求ACCESS_COARSE_LOCATION而不是ACCESS_FINE_LOCATION。 我添加了以后的权限,一切正常。
如果没有互联网连接,Google播放服务地理位置无法正常工作,对于GPS无所谓。 所以,请检查与移动数据打开的应用程序。
我运行,并在Nexus 7设备完美的工作。 你们错误地写了旧版本的LocationListener,而不是使用新的API。
您必须使用新的LocationListener进行设置。
你需要导入这个类,然后尝试。
import com.google.android.gms.location.LocationListener;
它根据新的API重写唯一的一个方法
@Override public void onLocationChanged(final Location newLocation) {}
请尝试这种方式,让我知道如果你仍然面临任何问题。
谢谢。
最简单的修复方法,虽然减慢了一点,但是使用了辅助函数。 我的问题是,它会连接,但之前有一个位置find,我会尝试访问它,并命中空指针。
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
使用这个,并设置任何你想要使用此function的位置,通过你的位置客户端。
@Override public void onConnected(Bundle dataBundle) { Location temp = getLocation(mLocationClient); mLocation = temp; }
同样,如果你不想从onConnected
获取位置,只要你通过你的locationClient
就可以在任何地方使用相同的帮助函数。