development

OnLocationChanged 콜백은 호출되지 않습니다.

big-blog 2020. 11. 28. 09:44
반응형

OnLocationChanged 콜백은 호출되지 않습니다.


을 사용하여 사용자의 현재 위치를 가져 오려고합니다 LocationManager. 나는 많은 연구를 해왔고 같은 문제를 가진 사람을 찾을 수없는 것 같습니다. OnLocationChanged콜백 호출되지 않는 것 같습니다. 아래는 내 다양한 ​​코드와 logcat입니다.

protected LocationListener locationListener;
protected LocationManager locationManager;
protected Context context;

OnCreate()방법

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(TAG, "IN ON CREATE");

    this.context = getActivity();

    registerLocationUpdates();
}

registerLocationUpdates방법

void registerLocationUpdates() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_LOW);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);

    locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);

    provider = locationManager.getBestProvider(criteria, true);

    // Cant get a hold of provider
    if (provider == null) {
        Log.v(TAG, "Provider is null");
        showNoProvider();
        return;
    } else {
        Log.v(TAG, "Provider: " + provider);
    }

    locationListener = new MyLocationListener();

    locationManager.requestLocationUpdates(provider, 1L, 1f, locationListener);

    // connect to the GPS location service
    Location oldLocation = locationManager.getLastKnownLocation(provider);

    if (oldLocation != null)  {
        Log.v(TAG, "Got Old location");
        latitude = Double.toString(oldLocation.getLatitude());
        longitude = Double.toString(oldLocation.getLongitude());
        waitingForLocationUpdate = false;
        getNearbyStores();
    } else {
        Log.v(TAG, "NO Last Location found");
    }
}

나의 LocationListener

private class MyLocationListener implements LocationListener {

    public void onLocationChanged(Location location) {
        latitude = Double.toString(location.getLatitude());
        longitude = Double.toString(location.getLongitude());

        Log.v(TAG, "IN ON LOCATION CHANGE");

        if (waitingForLocationUpdate) {
            getNearbyStores();
            waitingForLocationUpdate = false;
        }

        locationManager.removeUpdates(this);
    }

    public void onStatusChanged(String s, int i, Bundle bundle) {
        Log.v(TAG, "Status changed: " + s);
    }

    public void onProviderEnabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }

    public void onProviderDisabled(String s) {
        Log.e(TAG, "PROVIDER DISABLED: " + s);
    }
}

AndroidManifest의 내 권한

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

그리고 마지막으로 내 앱을 실행 한 후 logcat

01-25 09:43:10.963: VERBOSE/NearbyListFragment(3060): IN ON CREATE
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.963: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.973: VERBOSE/LocationManagerService(1329): getProviders
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): Provider: gps
01-25 09:43:10.983: DEBUG/LocationManager(3060): requestLocationUpdates: provider = gps, listener = co.fusionweb.dealsplus.app.NearbyItems$NearbyListFragment$MyLocationListener@46ef4680
01-25 09:43:10.983: DEBUG/GpsLocationProvider(1329): setMinTime 1
01-25 09:43:10.983: VERBOSE/NearbyListFragment(3060): NO Last Location found
01-25 09:43:10.983: VERBOSE/LocationManagerService(1329): _requestLocationUpdates: listener = Receiver{47421e68 Listener android.os.BinderProxy@47421a68}
01-25 09:43:11.003: VERBOSE/countingFragment(3060): IN ON CREATE VIEW
01-25 09:43:11.003: WARN/GpsLocationProvider(1329): Duplicate add listener for co.fusionweb.dealsplus
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): In Constructor
01-25 09:43:11.013: VERBOSE/ScrollListener(3060): Scrolling
01-25 09:43:11.033: DEBUG/GpsLocationProvider(1329): startNavigating
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_time_out(standalone = 60, agps = 89)
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_qos_accuracy(accuracy = 50)
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): persist.radio.agps.mode: []
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_set_position mode, client = 1, interval = 1, mode = 1
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl called: client = 1, ioctl_type = 2
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_ioctl
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [96]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): loc_api_sync_ioctl: select_id = 0, loc_ioctl returned 0
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.043: VERBOSE/locapi_rpc_glue(1329): Callback received: 80 (cb_id=0x5310000 handle=1)
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.043: VERBOSE/lib_locapi(1329): loc_eng_ioctl result: client = 1, ioctl_type = 2, SUCCESS
01-25 09:43:11.043: DEBUG/lib_locapi(1329): loc_eng_start
01-25 09:43:11.043: DEBUG/locapi_rpc_glue(1329): loc_start_fix
01-25 09:43:11.043: DEBUG/RPC(1329): written RPC packet size: [44]
01-25 09:43:11.043: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.053: DEBUG/RPC(1329): read RPC packet size: [28]
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.103: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.113: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.113: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_SESSION_BEGIN
01-25 09:43:11.113: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.113: VERBOSE/GpsLocationProvider(1329): reportStatus status: 1
01-25 09:43:11.113: DEBUG/GpsLocationProvider(1329): Acquiring wakelock
01-25 09:43:11.123: DEBUG/RPC(1329): written RPC packet size: [28]
01-25 09:43:11.183: DEBUG/PowerManagerService(1329): New lightsensor value:40, lcdValue:77
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet
01-25 09:43:11.273: DEBUG/RPC(1329): read RPC packet size: [80]
01-25 09:43:11.273: VERBOSE/locapi_rpc_glue(1329): Callback received: 100 (cb_id=0x5310000 handle=1)
01-25 09:43:11.273: VERBOSE/lib_locapi(1329): process_deferred_action: pthread_cond_wait returned
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: GPS_STATUS_ENGINE_ON
01-25 09:43:11.273: DEBUG/lib_locapi(1329): loc_eng_report_status: update status
01-25 09:43:11.273: VERBOSE/GpsLocationProvider(1329): reportStatus status: 3

그리고 logcat의 Android SDK 위치 부분은 계속 반복합니다. 나는 내가 생각할 수 있고 Google과 stackoverflow에서 본 모든 것을 시도했습니다. Als requestSingleUpdate는 API 9에서 사용할 수 있는를 사용하고 A Deep Dive into Location 가이드 를 따라 2.3 장치에서 작동하도록 만들 수 있었지만 2.1 또는 2.2 이상에서 작동해야합니다. 이전 SDK. 따라서 힌트가 있거나 더 많은 것을 알고 싶다면 저에게 알려주십시오. 미리 감사드립니다.


설정이 제대로 작동하지 않는 것 같습니다. 문제를 해결하기 위해 가능한 한 간단하게 예제를 작성하겠습니다. 나는 당신의 요청을 다음과 같이 만들 것입니다.

requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

이렇게하면 가능한 모든 업데이트를 얻을 수 있습니다. 그리고 마지막으로 알려진 위치를 얻는 것에 대한 부분을 주석으로 처리하십시오. 아직 필요하지 않습니다.

그런 다음에 onLocationChanged(), 바로이

Log.v(TAG, "IN ON LOCATION CHANGE, lat=" + latitude + ", lon=" + longitude);

청취자가 계속 활동할 수 있도록 나머지는 주석 처리하십시오. 이것은 실제 장치에서 업데이트 스트림을 제공합니다. 에뮬레이터에서 DDMS를 사용해야하며 보내기를 누를 때마다 GPS 업데이트가 하나씩 제공됩니다.


교체

LocationManager.GPS_PROVIDER

LocationManager.NETWORK_PROVIDER

내 문제를 해결했습니다.

다음은 내 위치 관리자의 코드 스 니펫입니다.

 LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE);

// 위치 권한, Marshmallow 이상 확인

        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.

            Toast.makeText(getActivity(), "Not Enough Permission", Toast.LENGTH_SHORT).show();
            return;
        }

// 시작할 현재 위치 가져 오기

        Location myLocation = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);

        currentLatitude = myLocation.getLatitude();
        currentLongitude = myLocation.getLongitude();

// LocationManager.NETWORK_PROVIDER를 사용하여 위치 업데이트 요청

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, MapFragment.this);

GPS 제공자 장치가 저전력이거나 절전 모드를 사용할 때 비활성화되며이 경우 수신 할 수 없습니다.onLocationChanged

GPS 제공자는 집이나 건물에 머무르면 위치를 거의 반환하지 않습니다 (실외에서만 잘 작동).

따라서, 내 응용 프로그램에서 나는 모두를 사용 GPS_PROVIDER하고 NETWORK_PROVIDER받을 수 onLocationChanged()더 나은

https://developer.android.com/guide/topics/location/strategies.html#Updates

GPS 제공 업체에 위치 업데이트를 요청하려면 NETWORK_PROVIDER 대신 GPS_PROVIDER를 사용하세요. 또한 requestLocationUpdates ()를 두 번 (NETWORK_PROVIDER에 대해 한 번, GPS_PROVIDER에 대해 한 번) 호출하여 GPS 및 네트워크 위치 제공자 모두에서 위치 업데이트를 요청할 수 있습니다.


Steve Blackwell이 썼 듯이 설정이 좋습니다. 시도 있는 것은 GPS 고정 신호가 100 % 있는지 이해하는 것입니다! (Play 스토어에서) 멋진 GPS 테스터 응용 프로그램 을 설치했으며 수정 사항이 있는지 여부와 연결된 위성 및 연결 강도가 무엇인지 보여줍니다. 이것이 내 OnLocationChanged ()가 호출되지 않은 이유입니다. 건물 내에서 실행 해 보았습니다.

행운을 빕니다!


비슷한 문제가 발생했습니다. 권한이 있고 서비스를 요청했지만 업데이트가 없습니다. 내가해야 할 일은 단순히 기다리는 것뿐이라는 것이 밝혀졌습니다. 인터넷에서 문제를 검색하는 동안 응용 프로그램을 실행하고 몇 분 후에 업데이트를 받기 시작했습니다. 그런 다음 앱을 종료하고 다시 실행해도 업데이트가 즉시 이루어졌습니다. 시스템 문제, 일부 최적화, 아마도 장치가 전혀 움직이지 않았기 때문일 것입니다 (btw. , Pixel입니다).


나는 같은 상황을 가졌고, 내 코드에서 실수를했다고 생각하여 onlocationchage 메서드가 호출되지 않고 마침내 이렇게 해결했습니다.

Step 1 :
Close your application and Open Google Map Application.

Step 2 :
Touch the location finder button or icon over the Google Map app then It will show, currently where you are located.

Step 3 :
Now Run your app and check onlocationchage will call. 

그런 오래된 스레드를 부딪쳐서 미안하지만이 질문은 Google 검색에서 상대적으로 높은 순위를 차지하기 때문에 다른 사람들에게 유용 할 수 있습니다.

비슷한 문제가 있었고 onlocationchanged가 해고되지 않았지만 코드에서 잘못된 것을 찾을 수 없었습니다. 모든 종류의 조합을 시도한 결과, 문제의 근본 원인은 내가 서비스에 리스너를 등록하고 있다는 사실임을 깨달았습니다.

이 서비스는 포 그라운드 서비스 였으므로 작동해야하는 Google 문서에 따르면 그렇지 않았습니다!

초기화를 메서드로 래핑하고 서비스를 만들거나 바인딩 한 활동에서 메서드를 호출하여 문제를 해결했습니다.

이것은 내 서비스에서 내 방법입니다.

void start_gps_track(int i) {
        if (myCarLocationListener!=null) {
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            return;
        }
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
            myCarLocationListener=new CarLocationListener(this,adjust_audio);
            if (i==1) //if start night
                myCarLocationListener.setNightstart(true);
            else if (i==2) //if start GPS
                myCarLocationListener.setLocationStart(true);
            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, myCarLocationListener);
                Log.d("HU","Registered location listener");
                Location lastlocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (lastlocation == null)
                    lastlocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (lastlocation != null)
                    myCarLocationListener.onLocationChanged(lastlocation);
            }
            catch (SecurityException e){
                Log.e("HU-GPS","No permission to access Location");
            }
        }
        else
        {
            Log.e("HU-GPS","No GPS provider or no permission");
        }
    }

서비스 자체에서 이것을 호출하면 위치 업데이트를 수신하지 않습니다 (다시 메모 서비스는 FOREGROUND 서비스이며 실제로 현재 실행중인 활동에 바인딩됩니다).

However if I call this method from the activity which created/bound to the service like below it works fine:

@Override
public void onServiceConnected(ComponentName className,
                               IBinder service) {
    // We've bound to LocalService, cast the IBinder and get LocalService instance
    TransporterService.LocalBinder binder = (TransporterService.LocalBinder) service;
    mService = binder.getService();
    mService.updatePlayer(player.this);
    try {
        mService.start_gps_track(0);
    }
    catch (Exception e) {            //This should only happen if there is no GPS provider available, but it might happen quickly after boot when the device is not yet ready.
        mService.recheck_gps(0);
    }

    mBound = true;
  }

@Override
public void onServiceDisconnected(ComponentName arg0) {
    mBound = false;

}
};

Hope this helps some others who come across this problem.


I faced same issue. I was getting getLastKnownLocation as null. Issue is resolved when I restarted both the device and Location service in device.


If you are trying with NETWORK_PROVIDER, it is really difficult to test:

  • on Emulator: never work
  • on Real Device: only getLastKnownLocation() works, to receive onLocationChanged(), you have to use mobile data and go outside with the risk of losing phone from robber :P

I guess the reason is that it just the location of network provider only not your device itself, and the network provider never move, so the onLocationChanged() never call. It might happen only when switching between mobile data and wifi and vice versa. Please correct me if I am wrong.

So I suggest to use GPS_PROVIDER to experiment before considering performance and battery usage. It works nicely on both emulators and real devices. For the best practice: https://developer.android.com/guide/topics/location/strategies.html

It took me several hours to test with NETWORK_PROVIDER without any results, so hopefully my suggestion helpful.


I had the same problem (onLocationChanged() never called with NETWORK_PROVIDER) on my real device (M, app's targetSDK 23) until I restarted it.


As Phan Van Linh answered , it's probably because you are inside a building. There are explanation here on how to mock GPS for the emulator. Also, there is this app that mocks GPS data.


LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (manager != null) {
        List<String> providers = manager.getAllProviders();
        for (String provider : providers) {
           manager.requestLocationUpdates(provider, TIME_BW_UP, DISTANCE_BW_UP, locationListener);
        }
}

I have 2 devices: Samsung Galaxy S4 (Android 5.0.1) and Vertex Win (Android 8.1).

On Samsung everything works right and fast, GPS coordinates are found, and onLocationChanged is called.

On Vertex in prioity PRIORITY_BALANCED_POWER_ACCURACY it probably interacts with network provider first, so it finds coordinates via Wi-Fi. But it can't detect right, whether location service is turned on (after some time the device thinks it is turned on, while it is off, and calls addOnSuccessListener method of LocationServices.getSettingsClient. So I switched to PRIORITY_HIGH_ACCURACY and got another surprise. Network provider turned off, but onLocationChanged wasn't called, so I couldn't get coordinates. I downloaded GPS tester (as @Li3ro advised) from Play Market and saw that sattelites are visible, but without fixed signal. I couldn't receive a signal inside a building.

Even standalone maps couldn't receive coordinates, but outdoor could. So, after I walked away, I could find my coordindinates in an application.

See also https://stackoverflow.com/a/27828929/2914140, where it is said about priorities and error recognition (disabling GPS after some time if no coordinsates found).


This should be happen due to your phone settings. In phones Location settings, If the Location service Mode set to GPS only, then OnLocationChanged callback calls when there is GPS Fix. By selecting Use GPS, WI-FI And mobile networks options, location will be determine by using those three providers. This will take less time to locate your device location. ***Path to access to location services could be change device to device. Thanks

참고URL : https://stackoverflow.com/questions/9007600/onlocationchanged-callback-is-never-called

반응형