Android : LocationManager 및 Google Play 서비스 LocationManager수업 을

사용자의 현재 위치를 얻는 데 중점을 둔 앱을 만들고 Google Places API 를 통해 자신과 가까운 관심 지점 (예 : 바, 레스토랑 등)을 찾고 싶습니다 .

웹을 시작할 장소를 검색 할 때 LocationManager수업 을 사용하는 일부 자습서 와 사용자 위치를 찾기 위해 Google Play 서비스 를 사용하는 일부 자습서를 보았습니다.

첫눈에 두 사람 모두 같은 일을하지만, 이것에 익숙하지 않아서 약간 혼란 스러웠으며 어떤 방법이 내 요구에 가장 적합한 지 알 수 없습니다. 그래서 나는 당신에게 묻고 싶습니다 :

위치를 찾는 두 가지 방법의 차이점은 무엇입니까?



답변

Android의 사용자 위치

안드로이드에서 사용자의 위치를 ​​얻는 것은 iOS보다 덜 간단합니다. 혼란을 시작하기 위해 완전히 다른 두 가지 방법이 있습니다. 첫 번째는의 Android API를 사용 android.location.LocationListener하고 두 번째는 Google Play Services API를 사용하는 것 com.google.android.gms.location.LocationListener입니다. 두 가지를 모두 살펴 보자.

  1. 안드로이드의 위치 API

    Android의 위치 API는 세 가지 다른 제공 업체를 사용하여 위치를 얻습니다.

    • LocationManager.GPS_PROVIDER—이 공급자는 위성을 사용하여 위치를 결정합니다. 조건에 따라이 공급자는 위치 수정을 반환하는 데 시간이 걸릴 수 있습니다.
    • LocationManager.NETWORK_PROVIDER—이 공급자는 셀 타워 및 WiFi 액세스 포인트의 가용성에 따라 위치를 결정합니다. 결과는 네트워크 조회를 통해 검색됩니다.
    • LocationManager.PASSIVE_PROVIDER—이 제공자는 다른 제공자가 생성 한 위치를 반환합니다. 다른 응용 프로그램이나 서비스가 실제로 위치를 직접 요청하지 않고 요청하면 위치 업데이트를 수동으로받습니다.

요점은 LocationManager시스템에서 객체를 가져 와서 구현 LocationListener하고를 호출한다는 requestLocationUpdatesLocationManager입니다.

다음은 코드 스 니펫입니다.

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      // Called when a new location is found by the network location provider.
      makeUseOfNewLocation(location);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}
  };

// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

위치 전략에 대한 Google API 가이드코드를 꽤 잘 설명합니다. 그러나 대부분의 경우 Google 위치 서비스 API를 대신 사용하면 배터리 성능이 향상되고 정확성이 향상 됩니다. 이제 혼란이 시작됩니다!

  1. Google의 위치 서비스 API

Google의 위치 서비스 API는 Google Play 서비스 APK의 일부입니다 ( 설정 방법 ). 그것들은 Android API 위에 구축되었습니다. 이 API는 위에서 언급 한 공급자 대신 “퓨즈 위치 공급자”를 제공합니다. 이 공급자는 정확도, 배터리 사용량 등을 기준으로 사용할 기본 공급자를 자동으로 선택합니다. 시스템 전체 서비스에서 위치를 지속적으로 업데이트하여 업데이트하므로 속도가 빠릅니다. 지오 펜싱과 같은 고급 기능을 사용할 수 있습니다.

Google의 위치 서비스를 사용하려면 앱이에 연결되어 있어야합니다 GooglePlayServicesClient. 클라이언트에 연결하려면 활동 (또는 조각 등)을 구현 GooglePlayServicesClient.ConnectionCallbacks하고 GooglePlayServicesClient.OnConnectionFailedListener인터페이스 해야합니다 . 샘플 코드는 다음과 같습니다.

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        locationClient = new LocationClient(this, this, this);
    }

    @Override
    public void onConnected(Bundle bundle) {
    Location location = locationClient.getLastLocation() ;
        Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDisconnected() {
    Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // code to handle failed connection
        // this code can be found here — http://developer.android.com/training/location/retrieve-current.html 
    }
  • locationClient.getLastLocation()null입니까?

locationClient.getLastLocation()클라이언트에서 마지막으로 알려진 위치를 가져옵니다. 그러나 Fused Location Provider는 하나 이상의 클라이언트가 연결된 경우에만 백그라운드 위치를 유지합니다. 첫 번째 클라이언트가 연결되면 즉시 위치를 가져 오려고 시도합니다. 당신의 활동이 연결하는 첫 번째 클라이언트이며 호출하면 getLastLocation()즉시에서 onConnected()첫 번째 위치에 올 수있는 충분한 시간이되지 않을 수도.이 발생합니다 location되고 null.

이 문제를 해결하려면 공급자가 위치 getLastLocation()를 파악할 때까지 (불확실하게) 기다렸다가을 호출 해야합니다. 또 다른 (더 나은) 옵션은 com.google.android.gms.location.LocationListener주기적 위치 업데이트를 수신 하도록 인터페이스 를 구현하는 것입니다 (첫 번째 업데이트를 받으면 끄십시오).

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
    // . . . . . . . . more stuff here 
    LocationRequest locationRequest;
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // . . . . other initialization code
        locationClient = new LocationClient(this, this, this);
    locationRequest = new LocationRequest();
    // Use high accuracy
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
    locationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    }
    // . . . . . . . . other methods 
    @Override
    public void onConnected(Bundle bundle) {
        Location location = locationClient.getLastLocation();
        if (location == null)
            locationClient.requestLocationUpdates(locationRequest, this);
        else
            Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
    }
    // . . . . . . . . other methods
    @Override
    public void onLocationChanged(Location location) {
        locationClient.removeLocationUpdates(this);
        // Use the location here!!!
    }

이 코드에서는 클라이언트에 이미 마지막 위치 ( onConnected) 가 있는지 확인합니다 . 그렇지 않은 경우 위치 업데이트를 요청하고 업데이트를 받으면 onLocationChanged()즉시 콜백으로 요청을 끕니다 .

(가) 참고 locationClient.requestLocationUpdates(locationRequest, this);가이 안에 있어야하는 onConnected콜백, 그렇지 않으면 당신은 얻을 것이다 IllegalStateException당신은 구글 플레이 서비스 클라이언트에 연결하지 않고 위치에 대한 요청하려고 할 것이기 때문에.

  • 사용자가 위치 서비스를 사용 중지했습니다

많은 경우 사용자는 배터리를 절약하거나 개인 정보 보호를 위해 위치 서비스를 비활성화했습니다. 이 경우 위의 코드는 여전히 위치 업데이트를 요청하지만 onLocationChanged호출되지는 않습니다. 사용자가 위치 서비스를 비활성화했는지 확인하여 요청을 중지 할 수 있습니다.

앱에서 위치 서비스를 활성화해야하는 경우 메시지 또는 토스트를 표시하려고합니다. 안타깝게도 사용자가 Google의 위치 서비스 API에서 위치 서비스를 사용 중지했는지 확인하는 방법은 없습니다. 이를 위해서는 Android API를 사용해야합니다.

당신의 onCreate방법에서 :

    LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    locationEnabled = false;
    Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;

그리고 메소드 locationEnabled에서 다음 onConnected과 같이 플래그를 사용하십시오 .

    if (location != null) {
    Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
    locationClient.requestLocationUpdates(locationRequest, this);
}

최신 정보

대화 상자에서 한 번의 클릭으로 문서가 업데이트되고 LocationClient가 제거되고 API가 GPS를 활성화하도록 지원합니다.

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

링크 https://developer.android.com/training/location/change-location-settings#prompt

새로운 위치 클라이언트 : FusedLocationProviderClient

  private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}

위치 작업을 수행하기 전에 https://developer.android.com/training/location 을 방문하는 것이 좋습니다 .


답변

내 경험상 “적절한 정확도”가 더 좋은 의미는 아닙니다. 내가 빠진 것이 아니라면 GPS를 사용하고 싶다면 LocationManager가 유일한 방법입니다. 우리는 앱으로 차량을 추적하며, 누락 된 부분이없는 한 Google Play 서비스는 매우 부정확 한 위치를 제공합니다.


답변

LocationManager 대신 Google Play 서비스 위치 API를 사용해야합니다. 문서에 따르면 :

Google Play 서비스 위치 API는 앱에 위치 인식을 추가하는 방법으로 Android 프레임 워크 위치 API (android.location)보다 선호됩니다. 현재 Android 프레임 워크 위치 API를 사용중인 경우 가능한 빨리 Google Play 서비스 위치 API로 전환하는 것이 좋습니다.

전환해야하는 이유에 대해 Google은 다음과 같이 말합니다.

Google Play 서비스의 일부인 Google 위치 서비스 API는 위치 제공 업체, 사용자 이동 및 위치 정확도를 자동으로 처리하는보다 강력한 고급 프레임 워크를 제공합니다. 또한 제공하는 전력 소비 매개 변수를 기반으로 위치 업데이트 예약을 처리합니다. 대부분의 경우 위치 서비스 API를 사용하면 배터리 성능이 향상되고 정확도가 향상됩니다.


답변

꽤 오랫동안 Google 위치 서비스 API를 사용하고 있습니다. 위치 결정을위한 여러 소스를 갖는 복잡성을 캡슐화하기 때문에 장점이 있습니다. 그러나 그것은 너무 무겁게 캡슐화 되어 이상한 위치를 얻을 때 그 이상한 위치가 어디에서 왔는지 결정할 방법이 없습니다.

실생활에서 나는 실제 위치에서 10 킬로미터 떨어진 몇 가지 괴물 값이 나타났습니다. 유일한 설명은 이러한 미친 위치는 Google Wi-Fi 또는 NWK 데이터베이스의 오류에서 비롯된다는 것입니다. Wi-Fi 및 네트워크 토폴로지는 매일 바뀌기 때문에 항상 존재하는 오류입니다. 그러나 불행히도 (그리고 놀랍게도) API는 개별 위치가 어떻게 도출되었는지에 대한 정보를 제공하지 않습니다.

속도, 가속도, 베어링 등의 타당성 검사를 기반으로 괴물 값을 필터링 해야하는 문제가 있습니다.

… 또는 좋은 오래된 프레임 워크 API로 돌아가서 GPS 만 사용하십시오 .Google이 융합 API를 개선 할 때까지하기로 결정했습니다.


답변

Google Play 서비스의 일부인 Google 위치 서비스 API 위치 제공 업체 , 사용자 이동 위치 정확도 를 자동으로 처리하는보다 강력한 고급 프레임 워크를 제공 합니다 . 또한 제공하는 전력 소비 매개 변수를 기반으로 위치 업데이트 예약을 처리합니다. 대부분의 경우위치 서비스 API를 사용하면 배터리 성능이 향상 되고 정확도가 향상됩니다.

두 가지 API Google Play 서비스 위치 APIAndroid 프레임 워크 위치 API의 자세한 차이점은 여기에서 확인할 수 있습니다 .


답변

예, Google Play 서비스 위치 서비스 API는 매우 잘못된 위치 정보를 제공 할 수 있습니다. WiFi 모뎀이 이동하고 WiFi 모뎀이 잘못된 위치 정보로 업데이트됩니다 (예 : WiFi 모뎀의 위치를 ​​업데이트하는 Android 장치에 의해 위치가 스푸핑 된 경우) WiFi 모뎀 삼각 측량에서 잘못된 위치 데이터를 초래할 수있는 다른 상황이 많이 있습니다. 정확한 위치가 필수 인 모든 앱에서 GPS 만 사용합니다.


답변

GPS 서비스를 기반으로하는 두 가지 API Google Play 서비스 위치 API와 Android 프레임 워크 위치 API의 차이점

FusedLocationProviderClient

  1. 첫 번째 가져 오기의 경우 위치는 null이 아니어야합니다 (예 : 일부 다른 앱은 GoogleplayService 데이터베이스에서 Lastknown 위치를 업데이트해야합니다. null 인 경우 해결해야 함)
  2. 다음 순차 Fetch의 경우 requestLocationUpdates()메소드를 사용 하여 위치를 페치합니다.
  3. 위치 가져 오기에만 기반으로 locationRequest.setInterval(milliseconds)하고 setFastestInterval(milliseconds)기반으로하지, 사용자 위치 변경
  4. 리턴 값 LatLng를 포함 갖는다 단지 7 진수 값 : (11.9557996, 79.8234599 예) 정확하지 등을
  5. 앱 요구 사항에서 현재 위치 거리를 무시할 수있는 정확도 (50-100 미터)를 사용하는 경우 권장
  6. 배터리 사용에 효과적입니다.

위치 관리자 API

  1. locationManager.requestLocationUpdates ()를 사용하여 사용자 위치 가져 오기가 호출됩니다.
  2. 사용자 위치 변경시간 간격을 기반으로 한 위치 가져 오기 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)

  3. 반환 된 LatLng 값에는 소수점 이하 14 개의 값 (예 : 11.94574594963342 79.81166719458997)이 있습니다.

  4. 미터 단위의 정확도가 더 필요한 위치 기반 앱에 권장 됩니다.
  5. 배터리 사용량은 가져 오기 간격과 가져 오기 거리를 기준으로합니다.