2013-04-01 2 views
41

Я разрабатываю приложение, которое получает позицию сотового телефона весь день в течение 6 и 6 минут в службе, оно работает нормально, но иногда метод OnLocationChanged поставщика сети слушатель перестает быть вызванным, и я не знаю почему.LocationListener NETWORK_PROVIDER разрешен, но onLocationChanged никогда не называется

Это почему-то перестает быть вызванным, но провайдер включен, а Листер работает, когда я включаю или выключаю Поставщика вручную, вызывается onProviderEnabled и onProviderDisabled.

Это просто происходит с NETWORK_PROVIDER, GPS_PROVIDER хорошо работает.

СЛУШАТЕЛЬ:

LocationListener locationListenerGPS = new LocationListener() { 
     // @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      // TODO locationListenerGPS onStatusChanged 
      Log.d(TAG, "Provedor trocado"); 
     } 

     // @Override 
     public void onProviderEnabled(String provider) { 
      Log.w(TAG, "PROVEDOR " + provider + " HABILITADO!"); 
     } 

     // @Override 
     public void onProviderDisabled(String provider) { 
      Log.w(TAG, "PROVEDOR " + provider + " DESABILITADO!"); 
     } 

     // @Override 
     public void onLocationChanged(Location location) { 

      longitudeGPS = location.getLongitude(); 
      latitudeGPS = location.getLatitude(); 
      Log.d(TAG,"LocationChangedGPS LAT: "+latitudeGPS+" longi: "+longitudeGPS); 
      gpsComSinal = true; 
     } 
    }; 

    LocationListener locationListenerNET = new LocationListener() { 

     // @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      // TODO locationListenerNET onStatusChanged 
      Log.d("Contele", "Provedor foi mudado"); 
     } 

     // @Override 
     public void onProviderEnabled(String provider) { 
      Log.i(TAG, "PROVEDOR " + provider + " HABILITADO!"); 
     } 

     // @Override 
     public void onProviderDisabled(String provider) { 
      Log.i(TAG, "PROVEDOR " + provider + " DESABILITADO!"); 
     } 

     @Override 
     public void onLocationChanged(Location location) { 
      longitudeNET = location.getLongitude(); 
      latitudeNET = location.getLatitude(); 
      Log.d(TAG,"LocationChangedNET LAT: "+latitudeNET+" longi: "+longitudeNET); 
      netComSinal = true; 
     } 
    }; 

Код:

public void initProviders() { 

     localizacao = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE); 


     localizacao.removeUpdates(locationListenerNET); 
     localizacao.removeUpdates(locationListenerGPS); 

     localizacao.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 
       locationListenerGPS); 

     localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 
       0, locationListenerNET); 

     Log.d(TAG,"EsperaGPS"); 
     Handler esperaGPS = new Handler() { 
      public void handleMessage(Message msg) { 

       requestGPS(); 
      } 
     }; 

     Message msgEsperaGPS = Message.obtain(); 
     msgEsperaGPS.what = 0; 
     esperaGPS.sendMessageDelayed(msgEsperaGPS, 35000); 
    } 



    public void requestGPS() { 
      if (gpsComSinal) { 
       Log.d(TAG,"PEGO SINAL DE GPS"); 
       rastreio = "GPS"; 
       longitude = longitudeGPS; 
       latitude = latitudeGPS; 
       Log.d(TAG, "Utilizando provedor GPS."); 
       localizacao.removeUpdates(locationListenerGPS); 
       localizacao.removeUpdates(locationListenerNET); 

      } else { 
       Log.d(TAG,"Sem GPS... pegar NEt"); 
       // Setando os valores para usar network 
       localizacao.removeUpdates(locationListenerGPS); 
       localizacao.removeUpdates(locationListenerNET); 
       localizacao 
         .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
           0, 0, locationListenerNET); 
       Log.d(TAG,"EsperaNET"); 

         requestNET(); 
      } 
     } 

    public void requestNET() { 
      if (netComSinal) { 
       Log.d(TAG,"PEGO SINAL DE NET"); 
       rastreio = "NET"; 
       longitude = longitudeNET; 
       latitude = latitudeNET; 
       Log.d(TAG, "Utilizando provedor NET."); 
       localizacao.removeUpdates(locationListenerNET); 

      } else { 
       localizacao.removeUpdates(locationListenerGPS); 
       localizacao.removeUpdates(locationListenerNET); 
       Log.d(TAG,"Sem sinal"); 
      } 
     } 

Сообщить в Samsung Galaxy S3: enter image description here

все еще получаю "Сем SINAL" в течение 4 дней подряд.

Этот вопрос уже произошло с Galaxy Y и LG Optimus L5

Я сделал еще один тест, чтобы увидеть, если другие мки получили позиции NET, и я обнаружил, что они проходят по той же проблеме, они могут» t получить позицию NET только через GetLastknowLocation; чтобы проверить, что я использовал Galaxy S3 с этой проблемой, и я отключил поставщик GPS. (Протестировано в Цербере).

Я не мог найти объяснений, почему слушатель NETWORKSLOCATIONS останавливает предоставление позиций, но может быть, потому что он не должен работать в течение 2 или 3 дней без остановки.

Я сделал несколько тестов с другими мки, чтобы увидеть, если этот вопрос просто происходит с моим Aplication, и я обнаружил, что они проходят по той же проблемой, как и в Cerberus, например:

Я отключить GPS Provider в мобильный телефон (Galaxy S3) с "SINAL СЭМ" проблемы, посмотрите:

Мой отчет: enter image description here

И Cerberus (печать взяты в 14/05/2013) сообщают: enter image description here

Но когда я открыл Карты Google, он, похоже, работает нормально, я попытался переместиться на дистанционное место, чтобы посмотреть, будет ли он показывать GetLastknowLocation, но нет, карты google помещают меня в нужное место в данный момент, поэтому Я понял, что Google Maps использовал motionevent для перемещения меня на карту;

А также напечатать Логарифм Google Maps, чтобы получить NetworkProvider:

Нормальный случай:

enter image description here

Сем Sinal случай:

enter image description here

+0

Это потому, что поставщик сети не предоставляет вам не местоположение, а место ячейки башни/bts. Возможно, я ошибаюсь, но думаю, что если вы будете двигаться достаточно, вы, вероятно, поймаете другую ячейку tower/bts, и вы получите новое место в этом сетевом прослушивателе. –

+0

У меня уже было это, и я попытался переместить его на 2000 метров +, но без успеха, если я перезагружу сотовый телефон, приложение обычно работает в течение 4 или 3 дней, в каком-то устройстве эта проблема так и не произошла. Я получил Galaxy S3 с этой проблемой в течение 2 дней подряд, и он не получил ни одной позиции в сети, просто GPS. –

+0

Похоже, что устройство NetworkLocation Provider сломано. Я также сталкивался с подобной проблемой на некоторых устройствах HTC, а затем искал сеть для проблемы с HTC GPS и обнаружил, что многие пользователи жалуются на то, что GPS не работает должным образом. – Akhil

ответ

1

Я думаю, это потому, что ваш app get 'убит' в фоновом режиме. Я столкнулся с этой проблемой раньше, и я решил ее, переместив создание службы LocationListener в службу. Обязательно сохраните ссылку на слушателя. Это может решить проблему.

+0

У меня есть сервис который работает через 6 и 6 минут в этой службе, я создал LocationListener для GPS и NET, и ошибок нет, приложение не убивается, потому что оно по-прежнему получает позицию GPS, если я выхожу из OnlocationChanged of the GPS-провайдер возвращает мне LAT и LONGITUDE, но NET неподвижно «мертв», даже если у меня есть WIFI-соединение или 3G. –

4

У меня точно такая же проблема, и единственным решением для меня является перезагрузка устройства. Что интересно, что ни одно из приложений не содержит информацию о местоположении, кроме карт Google.
Приложение Google Maps как-то находит свое местоположение! ..

P.S. используя службу LocationListener в сервисе, поэтому это определенно не проблема плохой ссылки, мертвого объекта и т. д.

+0

Да, это своего рода тайна, но я думаю, что на картах Google используется акселерометр для решения этой проблемы. –

+0

Перезагрузка устройства работала для меня. – thomaus

+1

В моем случае мое приложение не получит никаких обратных вызовов onLocationChanged на одном конкретном телефоне, когда другие получили их. Я заметил то же самое, что и m190: каким-то образом Google Maps получал текущее местоположение, и мое приложение застряло, имея возможность получить последние известные местоположения, которые были довольно старыми.Перезагрузка устройства в конечном итоге устранила проблему. Хотелось бы узнать, что Google Maps делает по-другому ... – strangeluck

4

У меня все еще есть эта проблема. Но я до сих пор ищу ответ, я пытался реализовать это в слушателе NETWORK_PROVIDER:

public void onStatusChanged(final String provider, final int status, final Bundle extras) { 
    switch(status) { 
    case LocationProvider.AVAILABLE: 
       // ... 
     break; 
    case LocationProvider.OUT_OF_SERVICE: 
       // ... 
     break; 
    case LocationProvider.TEMPORARILY_UNAVAILABLE: 
       // ... 
     break; 
    } 
} 

Потому что: OUT_OF_SERVICE, если провайдер не работает, и это не изменится в ближайшее будущее; TEMPORARILY_UNAVAILABLE, если поставщик временно недоступен, но ожидается, что он будет доступен в ближайшее время; и AVAILABLE, если поставщик в настоящее время доступен.onStatusChanged

И я подумал, что OUT_OF_SERVICE была моя проблема, и нет никакого решения в до сих пор, просто перезагрузить устройство, а затем я попытался сделать некоторые отчеты, когда это произойдет, и когда это ocurre я попросить пользователя reebot устройства, но несколько устройств получают этот статус.

28

У меня возникли аналогичные проблемы с Сетевой провайдер и только решением было принудительное перезапуск устройства. Несмотря на то, что карта google всегда показывала правильное местоположение, поскольку она также использует информацию других датчиков, помимо поставщика сетевого местоположения.

Но вот хорошие новости, не Долгое время назад Google представил Плавленый Расположение Provider API, с помощью его Google Play Service Framework которая очень проста в использовании, чем GPS/сети поставщиков Местоположение.

Совместимый до API уровня 8, теперь, когда я получаю эту странную проблему с сетевым провайдером, то же время Fused Location дает мне точное местоположение (без перезагрузки устройства).

Я совершил один работающий FusedLocation Test Project here, можно клонировать и испытать себя ..

Ниже фрагмент кода: -

package com.example.fusedLoctionTest.service; 

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.support.v4.content.LocalBroadcastManager; 
import android.util.Log; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesClient; 
import com.google.android.gms.location.LocationClient; 
import com.google.android.gms.location.LocationRequest; 

public class FusedLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, 
     GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener{ 
    private static final LocationRequest REQUEST = LocationRequest.create() 
      .setInterval(0) 
      .setFastestInterval(0) 
      .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
    public static final String LOCATION_RECEIVED = "fused.location.received"; 
    private Long now; 

    private LocationClient mLocationClient; 
    private final Object locking = new Object(); 
    private Runnable onFusedLocationProviderTimeout; 
    private Handler handler = new Handler(); 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 
     now = Long.valueOf(System.currentTimeMillis()); 
     mLocationClient = new LocationClient(this, this, this); 
     mLocationClient.connect(); 
     return START_STICKY; 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.d("FusedLocationService", "Fused Location Provider got connected successfully"); 
     mLocationClient.requestLocationUpdates(REQUEST,this); 
     onFusedLocationProviderTimeout = new Runnable() { 
      public void run() { 
       Log.d("FusedLocationService", "location Timeout"); 

       Location lastbestStaleLocation=getLastBestStaleLocation(); 
       sendLocationUsingBroadCast(lastbestStaleLocation); 

       if(lastbestStaleLocation!=null) 
        Log.d("FusedLocationService", "Last best location returned ["+lastbestStaleLocation.getLatitude()+","+lastbestStaleLocation.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis())-now)+" ms"); 

       if(mLocationClient.isConnected()) 
        mLocationClient.disconnect(); 
      } 
     }; 
     handler.postDelayed(onFusedLocationProviderTimeout, 20000);//20 sec 
    } 

    private void sendLocationUsingBroadCast(Location location) { 
     Intent locationBroadcast = new Intent(FusedLocationService.LOCATION_RECEIVED); 
     locationBroadcast.putExtra("LOCATION", location); 
     locationBroadcast.putExtra("TIME", Long.valueOf(System.currentTimeMillis()-now) +" ms"); 
     LocalBroadcastManager.getInstance(this).sendBroadcast(locationBroadcast); 
     stopSelf(); 
    } 

    @Override 
    public void onDisconnected() { 
     Log.d("FusedLocationService","Fused Location Provider got disconnected successfully"); 
     stopSelf(); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     synchronized (locking){ 
      Log.d("FusedLocationService", "Location received successfully ["+location.getLatitude()+","+location.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis()-now))+" ms"); 

      handler.removeCallbacks(onFusedLocationProviderTimeout); 
      if(mLocationClient.isConnected()) 
       mLocationClient.removeLocationUpdates(this); 

      sendLocationUsingBroadCast(location); 

      if(mLocationClient.isConnected()) 
       mLocationClient.disconnect(); 
     } 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.d("FusedLocationService", "Error connecting to Fused Location Provider"); 
    } 

    public Location getLastBestStaleLocation() { 
     Location bestResult = null; 
     LocationManager locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     Location lastFusedLocation=mLocationClient.getLastLocation(); 
     Location gpsLocation = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     Location networkLocation = locMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
     if (gpsLocation != null && networkLocation != null) { 
      if (gpsLocation.getTime() > networkLocation.getTime()) 
       bestResult = gpsLocation; 
     } else if (gpsLocation != null) { 
      bestResult = gpsLocation; 
     } else if (networkLocation != null) { 
      bestResult = networkLocation; 
     } 

     //take Fused Location in to consideration while checking for last stale location 
     if (bestResult != null && lastFusedLocation != null) { 
      if (bestResult.getTime() < lastFusedLocation.getTime()) 
       bestResult = lastFusedLocation; 
     } 

     return bestResult; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 
} 
+0

Я реализовал что-то подобное и могу получить обновления местоположения, когда мое приложение переходит в фоновый режим. Однако, когда я уничтожаю свое приложение (служба все еще работает), я больше не получаю обновления местоположения. То же самое происходит с вашим приложением. Любые идеи почему? – Bear

+2

R ... перезагрузка? Какой ужасный провал, Google. – nmr

+0

Работает ли в сети Интернет ??? –

2

Я понимаю некоторые вещи в нашем вопросе; вы вызываете метод requestGPS, а затем dicover его location.If gps включен, получил через gps. Othervise gott через NET. Когда вы вызываете requestGPS и управляете провайдером, чем получаете lat-lang, но удаляете обновления. (Не вызывайте, потому что вы удалили триггер обновлений);

if (gpsComSinal) { 
    Log.d(TAG,"PEGO SINAL DE GPS"); 
    rastreio = "GPS"; 
    longitude = longitudeGPS; 
    latitude = latitudeGPS; 

    Log.d(TAG, "Utilizando provedor GPS."); 
    // if you remove update don't call onLocationChanged 
    localizacao.removeUpdates(locationListenerGPS); 
    localizacao.removeUpdates(locationListenerNET); 
} else { 
    Log.d(TAG,"Sem GPS... pegar NEt"); 
    // Setando os valores para usar network 
    localizacao.removeUpdates(locationListenerGPS); 
    localizacao.removeUpdates(locationListenerNET); 
    localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
             0, 0, locationListenerNET); 
    Log.d(TAG,"EsperaNET"); 
    requestNET(); 
} 
+0

Я согласен с вами в том, что есть некоторые бесполезные removeUpdates, но на данный момент, если (gpsComSinal), я уже ждал 35 секунд, чтобы слушать NetProvicer и GPSProvider и сохранить их позиции, потому что я хочу, чтобы позиции занимали 6 и 6 минут, и я хочу для экономии заряда аккумулятора. Так что removeUpdates не проблема, потому что через 6 минут я снова запрашиваю их позиции. –

2

NETWORK_PROVIDER не обновляется, когда GPS-устройство телефона работает и получает сигнал. Если вы отключите GPS и заставите телефон получать свое местоположение из сети, вы снова начнете получать обновления.

3

Кажется, проблема с сетью, о которой сообщается в Android Open Source Project, Issue Tracker: https://code.google.com/p/android/issues/detail?id=57707. Вкратце: проблема опубликована 17 июля 2013 г. - последний блог 7 января 2015 г., выпущенная на Android 4.1.x, появляется на самых разных устройствах: «Не разрешена в последней библиотеке сервисов Play», никаких обходных решений, предложенных в блоге.

+0

Почему они отметили это как устаревшее ... проблема никогда не была исправлена. – Questioner

Смежные вопросы