LocationClient getLastLocation () 반환 null
내가 테스트하기 전에 누군가가 만난 질문과 마찬가지로 nexus s (4.0.4 with google play service available) 및 avd (4.2.2 with google api), 두 경우 모두 locationclient의 getLastLocation()
항상 return 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) {}
}
대부분은 Google에서 제공 한 예제에서 나왔습니다. 위의 코드에서 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) {}
});
을 ( onConnected()
를) 호출하기 전에 들어 getLastLocation()
왔지만 여전히 운이 없습니다. 실수는 어디에 있습니까, 미리 감사드립니다.
현재 Fused Location Provider
하나 이상의 클라이언트가 연결된 경우에만 백그라운드 위치를 유지합니다. 첫 번째 클라이언트가 연결되면 즉시 위치를 가져 오려고 시도합니다. 활동이 첫 번째 클라이언트이고 getLastLocation()
에서 즉시 전화를 거는 onConnected()
경우 첫 번째 위치가 들어오는 데 충분한 시간이 아닐 수 있습니다.
튜토리얼 의 지침을 따를 때 동일한 문제가 발생했습니다 . 전화에서는 작동했고 (Genymotion) 에뮬레이터에서는 작동하지 않았습니다.
해결책
AndroidManifest.xml에서 다음을 변경하십시오.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
이에:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
... 그리고 즉시 위치를 알 수 있습니다. 위치 업데이트를 듣기 위해 코드를 변경할 필요가 없습니다.
이 문제는 장치에 "Wi-Fi 및 모바일 네트워크 위치"가 활성화되어 있지 않기 때문에 발생할 수도 있습니다.
LocationClient (융합 위치 공급자)는 GPS와 WiFi를 모두 사용합니다. GPS는 Wi-Fi가 훨씬 빠르지 만 위치를 찾는 데 시간이 걸립니다. 그러나이 두 서비스 중 하나가 연결되면 onConnected 콜백 메서드가 호출됩니다. 그리고 onConnected 메서드에서 LocationClient.getLastLocation ()을 즉시 호출하려는 경우 Wi-Fi 위치 서비스가 비활성화 된 경우 null 값을 얻을 가능성이 높습니다. GPS가 충분히 빠르지 않기 때문입니다.
로컬에서 직접 문제를 해결하려면 "Wi-Fi 및 모바일 네트워크 위치"를 활성화하십시오. "설정> 개인> 위치 액세스> Wi-Fi 및 모바일 네트워크 위치"로 이동하여 수행 할 수 있습니다.
그러나 앱 사용자의 문제를 해결하려면 getLastLocation ()이 null을 반환하는지 확인하는 것이 좋습니다. 그렇다면 사용자에게 Google지도와 마찬가지로 서비스를 활성화하도록 요청하십시오.
도움이 되었기를 바랍니다.
비슷한 문제에 직면했습니다.
전화 mLocationClient.getLastLocation()
에서 onConnected
또는 구글 플레이 서비스에 연결 한 후이 설립되었습니다. 위치 클라이언트가 연결되기 전에이 메서드를 호출하는 경우 반환되는 위치는 null
.
위치 클라이언트가로 연결되어 있는지 확인할 수 있습니다 mLocationClient.isConnected()
.
도움이 되었기를 바랍니다.
사용자가 Wi-Fi / GSM 또는 GPS를 통해 위치를 활성화했는지 확인해야합니다. 사용 가능한 위치 공급자가 없으면 null
.
이 코드는 위치 설정이있는 화면을 표시합니다.
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
이것은 아마도 약간 다른 상황에서 정확히 작동하는 솔루션입니다. 하지만 누구나 정확한 개념을 알 수 있도록 약간의 설명 단계를 추가하고 싶었습니다.
1)에서 onCreate () 안드로이드 구성 요소 (예,의 활동 , 조각 또는 서비스 . 참고 : IntentService ), 빌드 다음과 연결 아래와 같이 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 단계에서는 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 () 메서드를 호출했습니다 . 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 () 콜백에서 새 위치를 얻습니다.
@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]
이 세 단계를 수행하려면 아래와 같이 build.gradle을 구성해야합니다.
compile 'com.google.android.gms:play-services-location:10.2.1'
나는 삼성 휴대 전화를 사용한 테스트에서 비슷한 문제에 직면했습니다 (높은 사용자 정의 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) {
}
});
SDK 버전 23
에 당신은 또한이 필요합니다 명시 적으로 런타임시 위치 권한을 요청 에 따라, https://developer.android.com/training/permissions/requesting.html 매니페스트 파일을 가지고뿐만 아니라.
런타임 중에 권한이없는 경우 명시적인 오류가 발생하지 않으며 위치 공급자는 null을 반환합니다.
Google이 이것을 문서화하고 null을 반환하는 대신 예외를 던지면 도움이 될 것입니다. null을 반환하는 것은이 상황에서 가장 도움이되지 않는 일입니다.
나는 또한 내 앱에서 같은 문제에 직면하고 있었고 유일한 누락 된 것은 앱이 ACCESS_FINE_LOCATION이 아닌 ACCESS_COARSE_LOCATION에 대해서만 요청했다는 것입니다. 나는 나중에 권한을 추가했고 모든 것이 정상적으로 작동했습니다.
Google Play 서비스 위치 정보는 GPS와 무관하게 인터넷 연결 없이는 작동하지 않습니다. 따라서 모바일 데이터가 켜져있는 앱을 확인하십시오.
위치에 대한 업데이트 요청 만 있으면됩니다. 26 개의 Android SDK 허용이 모두 정상인 경우 :
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;
}
}
});
}
그리고 onConnected 콜백 메소드에서 :
@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();
}
나는 Nexus 7 기기에서 완벽하게 작동합니다. 실수로 새 API와 함께 사용되지 않는 이전 버전 LocationListener를 작성했습니다.
새로운 LocationListener로 설정해야합니다.
이 클래스를 가져온 다음 시도해야합니다.
import com.google.android.gms.location.LocationListener;
그리고 그것은 새로운 API에 따라 유일한 방법을 재정의합니다.
@Override
public void onLocationChanged(final Location newLocation)
{}
이 방법을 시도하고 여전히 문제가 발생하면 알려주십시오.
감사.
The easiest fix, albeit slows it down a little, is to use a helper function. My problem was that it would connect, but before there was a location found, I would try to access it and hit a null pointer.
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();
}
}
Just use this in onConnected
and set whatever you wanted the location to be using this function, passing your location client.
@Override
public void onConnected(Bundle dataBundle) {
Location temp = getLocation(mLocationClient);
mLocation = temp;
}
Also if you don't want to get the location from onConnected
for whatever reason, you can use the same helper function anywhere as long as you pass your locationClient
.
ReferenceURL : https://stackoverflow.com/questions/16830047/locationclient-getlastlocation-return-null
'Development Tip' 카테고리의 다른 글
C # 보호 메서드 단위 테스트 (0) | 2020.12.15 |
---|---|
Haskell에 암시 적 병렬성이없는 이유는 무엇입니까? (0) | 2020.12.15 |
Android M에서 단일 요청으로 여러 권한을 확인하는 방법은 무엇입니까? (0) | 2020.12.15 |
프로그래밍 방식으로 log4net 로깅 수준 변경 (0) | 2020.12.15 |
XAML에서 매개 변수가있는 생성자 호출 (0) | 2020.12.15 |