Подтвердить что ты не робот

OnLocationChanged callback никогда не вызывается

Я пытаюсь получить текущее местоположение пользователей с помощью LocationManager. Я провел много исследований и не могу найти никого с той же проблемой. Обратный вызов OnLocationChanged никогда не вызван. Ниже приведен мой код и логарифм.

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.[email protected]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 [email protected]}
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

И части локации Android SDK логарифма продолжают повторяться. Я пробовал все, о чем я мог думать и видел в google и stackoverflow. Als, как побочная заметка, я смог заставить ее работать на устройстве 2.3, используя requestSingleUpdate, который доступен в API 9, и следуя руководству Deep Dive into Location, но мне нужно, чтобы он работал на 2.1 или 2.2 и выше, используя старый SDK. Если у вас есть какие-либо намеки или вы хотите узнать больше, сообщите мне. Спасибо заранее.

4b9b3361

Ответ 1

Похоже, что вы должны работать, потому что это не так, я бы сделал ваш пример максимально простым для устранения неполадок. Я бы сделал ваш запрос похожим на

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, и каждый раз, когда вы нажимаете send, вы получите одно обновление GPS.

Ответ 2

Замена

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);

Ответ 3

Поставщик GPS отключит, когда устройство находится в режиме пониженного энергопотребления или использует режим энергосбережения, тогда в этом случае мы не сможем получить onLocationChanged

Поставщик GPS вряд ли когда-либо вернет местоположение, если вы остаетесь в доме или здании (только хорошо работают на улице)

Поэтому в своем приложении я буду использовать GPS_PROVIDER и NETWORK_PROVIDER, чтобы лучше получать onLocationChanged()

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

Чтобы запросить обновления местоположения у поставщика GPS, используйте GPS_PROVIDER вместо NETWORK_PROVIDER. Вы также можете запросить обновления местоположения как от GPS, так и от провайдера сетевых расположений, позвонив requestLocationUpdates() дважды - один раз для NETWORK_PROVIDER и один раз для GPS_PROVIDER.

Ответ 4

Как писал Стив Блэквелл, ваша установка хороша. Что вы можете попробовать, так это понять, если у вас 100% фиксированный сигнал GPS! Я установил хорошее приложение GPS Tester (из магазина воспроизведения), и оно покажет вам, есть ли у вас исправление или нет, и к каким спутникам вы и что является прочностью соединения. Именно по этой причине мой OnLocationChanged() никогда не звонил.. Я попытался запустить его изнутри здания:\

Удачи!

Ответ 5

У меня возникла аналогичная проблема. У меня были разрешения, исправленные запросы, но обновления не было. Оказалось, что все, что я должен был сделать, это просто подождать. Пока я искал проблему в Интернете, у меня было приложение, и через несколько минут оно только начинало получать обновления. Тогда даже когда я убил приложение и запустил его снова, обновления пришли мгновенно - я думаю, это системная вещь, некоторые оптимизации, возможно, из-за того, что устройство вообще не двигалось (кстати, это не какое-то дерьмовое устройство, это Pixel).

Ответ 6

У меня была такая же ситуация, я думал, что допустил ошибку в своем коде, поэтому метод 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. 

Ответ 7

Извините, что натолкнулся на такую старую ветку, но это может пригодиться некоторым другим, так как этот вопрос занимает относительно высокое место в поиске 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 является службой, и она фактически привязана к действию, которое в данный момент выполняется).

Однако, если я вызываю этот метод из действия, которое создало/привязало к сервису, как показано ниже, он работает нормально:

@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;

}
};

Надеюсь, что это поможет некоторым другим, кто сталкивается с этой проблемой.

Ответ 8

Я столкнулся с такой же проблемой. Я получил getLastKnownLocation как null. Проблема разрешается, когда я перезапускал как устройство, так и службу местоположения на устройстве.

Ответ 9

Если вы пытаетесь использовать NETWORK_PROVIDER, это действительно сложно проверить:

  • на эмуляторе: никогда не работайте
  • на реальном устройстве: только getLastKnownLocation() работает, чтобы получать onLocationChanged(), вы должны использовать мобильные данные и выйти на улицу с риском потери телефона от грабителя: P

Я предполагаю, что причина в том, что это просто местоположение сетевого провайдера, а не только ваше устройство, а сетевой провайдер никогда не перемещается, поэтому onLocationChanged() никогда не звонит. Это может произойти только при переключении между мобильными данными и Wi-Fi и наоборот. Пожалуйста, поправьте меня, если я ошибаюсь.

Поэтому я предлагаю использовать GPS_PROVIDER для экспериментов перед рассмотрением производительности и использования батареи. Он отлично работает как на эмуляторах, так и на реальных устройствах. Для лучшей практики: https://developer.android.com/guide/topics/location/strategies.html

Мне потребовалось несколько часов для тестирования с NETWORK_PROVIDER без каких-либо результатов, поэтому, надеюсь, мое предложение будет полезно.

Ответ 10

У меня была та же проблема (onLocationChanged() никогда не вызывался с NETWORK_PROVIDER) на моем реальном устройстве (M, app targetSDK 23), пока я не перезапустил его.

Ответ 11

Как ответил Phan Van Linh, это возможно потому, что вы внутри здания. Есть объяснение здесь о том, как издеваются GPS для эмулятора. Кроме того, есть это приложение, которое высмеивает данные GPS.

Ответ 12

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);
        }
}

Ответ 13

У меня 2 устройства: Samsung Galaxy S4 (Android 5.0.1) и Vertex Win (Android 8.1).

На Samsung все работает правильно и быстро, GPS-координаты найдены, и вызывается onLocationChanged.

На Vertex in prioity PRIORITY_BALANCED_POWER_ACCURACY он, вероятно, сначала взаимодействует с провайдером сети, поэтому он находит координаты через Wi-Fi. Но он не может правильно определить, включена ли служба определения местоположения (через некоторое время устройство думает, что оно включено, когда оно выключено, и вызывает метод addOnSuccessListener LocationServices.getSettingsClient. Поэтому я переключился на PRIORITY_HIGH_ACCURACY и Еще один сюрприз. Сетевой провайдер отключен, но onLocationChanged не вызывался, поэтому я не мог получить координаты. Я скачал GPS tester (как советовал @Li3ro) с Play Market и увидел, что спутники видны, но без исправления сигнал. Я не смог получить сигнал внутри здания.

Даже автономные карты не могли получить координаты, но на улице могли. Поэтому, после того как я ушел, я смог найти свои координаты в приложении.

См. также fooobar.com/questions/409619/..., где говорится о приоритетах и распознавании ошибок (отключение GPS через некоторое время, если координаты не найдены).

Ответ 14

Это должно произойти из-за настроек вашего телефона. В настройках местоположения телефонов, если в качестве режима службы определения местоположения задано только GPS, OnLocationChanged обратный вызов вызывает, когда есть GPS Fix. Выбрав опции "Использовать GPS, WI-FI и мобильные сети", местоположение будет определяться с помощью этих трех провайдеров. Это займет меньше времени, чтобы определить местоположение вашего устройства. *** Путь к доступу к службам определения местоположения может быть изменен с устройства на устройство. Спасибо