2012-01-25 303 views
44

我想要使用LocationManager來獲取用戶當前位置。我做了大量的研究,似乎無法找到有同樣問題的人。回調似乎永遠不會被調用。以下是我的各種代碼和logcat。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); 
    } 
} 

我在AndroidMa權限nifest

<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 

而且logcat中的Android SDK的位置部分不斷重複他們的自我。我已經嘗試了所有我能想到的,並已經看到谷歌和stackoverflow。阿爾斯只是一個便箋,我已經能夠得到它在2.3設備上使用requestSingleUpdate在API 9中可用,並遵循指南A Deep Dive into Location工作,但我需要它使用舊版SDK在2.1或2.2及更高版本上工作。所以,如果你有任何提示或想了解更多,請讓我知道。提前致謝。

+0

雖然已經很晚了,但我希望這個評論可以幫助別人,看看這個鏈接:http://www.lengrand.fr/2013/10/onlocationchanged-is-never-called-on-android – SMHJamali

回答

46

它看起來像你安裝應該工作,因爲它沒有,我會盡可能簡單的例子,以解決問題。我會讓你的請求看起來像

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更新。

+1

幾乎工作,以及我認爲它工作,因爲它在MyTouch 4G上工作,我不斷更新後得到更新。然後我嘗試了另一臺設備(MyTouch 3G),它不再有效。我已經注意到,在像Bionic這樣的更好的設備上,GPS的工作速度非常快,但是在低端手機上,似乎我永遠無法使用它。低端手機在GPS方面真的很糟糕嗎?還是有什麼我失蹤? – smitt04

+1

簡化幫助,但它也證明,在MyTouch 3G,我不能得到一個位置,直到我先連接到WiFi網絡 – smitt04

+11

這沒有任何區別 – user724861

2

正如史蒂夫布萊克威爾寫道,你的設置很好。你可以可以嘗試瞭解你是否100%擁有GPS固定信號!我已經安裝了一個不錯的GPS Tester application (from the play store),它會告訴你,如果你有一個修復或不連接,並連接到哪些衛星和連接強度。 這就是我的OnLocationChanged()永遠不會調用的原因。我試着從建築物內運行它:\

祝你好運!

+1

註銷回調感謝分享那真棒應用程序,我安裝它,並知道在某些地方我的gps位置是沒有自動更新(在我的應用程序) –

+0

不適用於索尼4.3 –

+2

真棒工具,即GPS測試應用程序,所以我可以看到,在我的設備上它顯示GPS:NO Fix。我認爲這意味着沒有固定的GPS信號,對吧? – cubycode

0

我面臨同樣的問題。我得到getLastKnownLocation爲null。當我重新啓動設備中的設備和位置服務時問題得到解決。

+0

我面臨同樣的問題,但知道某些設備還需要時間/移動來獲取位置lat-lon ...我的聯繫在moto能夠獲取的時候沒有獲取經緯度 –

6

更換

的LocationManager。GPS_PROVIDER

LocationManager.NETWORK_PROVIDER

解決我的問題。

這裏是我的位置管理的代碼片段

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

//檢查地點的權限,棉花糖及以上

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

我遇到過類似的問題。我有權限,請求正確的服務,但沒有更新。事實證明,我所要做的只是等待。當我在網上搜索這個問題時,我運行了應用程序,幾分鐘後它纔開始接收更新。然後,即使我殺了應用程序,並再次運行,更新就瞬間 - 我想這是一個系統的東西,一些優化,可能由於該設備是不是在所有移動(順便說一句這是不是有些低劣的設備。 ,它是Pixel)。

1

我有同樣的情況,我想我已經在我的代碼一些錯誤,所以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. 
2

GPS提供商將禁用當設備在低功耗或使用省電模式,那麼在這種情況下,我們不能接收onLocationChanged

GPS提供商未落返回的位置,如果你留在裏面的房子或建築物(僅在室外正常工作)

因此,在我的應用我將同時使用GPS_PROVIDERNETWORK_PROVIDER接收onLocationChanged()更好

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

從GPS提供商請求位置更新,請使用GPS_PROVIDER 代替NETWORK_PROVIDER。您也可以從GPS,並通過調用 requestLocationUpdates(網絡位置提供商都要求位置更新 )兩次,一次NETWORK_PROVIDER和一次 GPS_PROVIDER。

0

如果您正在使用NETWORK_PROVIDER努力,實在是很難測試:

  • 在仿真器:從來沒有在真機上工作
  • :僅getLastKnownLocation()的作品,接受onLocationChanged()你必須使用移動數據和來自強盜手機丟失的風險,到外面去:P

我猜的原因是,它只是網絡提供商只不是你的設備本身,以及網絡及通訊系統的位置rk提供者永遠不會移動,所以onLocationChanged()永遠不會調用。只有在移動數據和WiFi之間切換時纔會發生,反之亦然。如果我錯了,請糾正我。

所以我建議在考慮性能和電池使用之前使用GPS_PROVIDER進行實驗。它在仿真器和真實設備上都能很好地工作。爲了獲得最佳的做法:https://developer.android.com/guide/topics/location/strategies.html

我花了好幾個小時,NETWORK_PROVIDER測試沒有任何結果,所以希望我的建議幫助。

0

我在我的真實設備(M,應用程序的targetSDK 23)上有同樣的問題(onLocationChanged()從來沒有用NETWORK_PROVIDER調用),直到我重新啓動它。

相關問題