Android locationManager requestLocationUpdates不起作用

我正在开发一个应用程序列出最接近用户的餐馆。 点击刷新button时,会列出用户当前位置的餐馆。 我正在使用位置pipe理器,只有在活动到达前台(onResume)时才请求更新,以避免电池的持续使用。 当应用程序进入onPause()时,位置更新被停止。 当我通过terminal传递更新时,它在模拟器上正常工作。

问题:当我改变自己的位置(比如开车5英里远),我打开我的应用程序和活动以显示最近的餐馆时,位置刷新需要很长时间(4-5分钟),直到应用程序继续显示前一个位置的餐馆。 但是,如果我实际改变自己的位置并访问Google地图,然后打开我的餐馆应用程序,那么它即刻起作用。 我已经确保GPS打开。 我可以做些什么来让位置pipe理员在我打开我的活动后马上启动并刷新位置? 先谢谢你!

package com.mortley.android.restaurantsaver; public class NearbyRestaurantActivity extends ListActivity implements OnClickListener, LocationListener{ private Button refreshButton, searchRestaurants; ImageButton goToSearch; private double[] lastKnownLocation; private EditText locationEditText; private LocationManager locManager; private LocationListener locListener; private boolean gps_enabled = false; private boolean network_enabled = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nearbyrestaurants); refreshButton = (Button)findViewById(R.id.reloadButton); refreshButton.setOnClickListener(this); searchRestaurants = (Button)findViewById(R.id.searchButton); searchRestaurants.setOnClickListener(this); goToSearch = (ImageButton)findViewById(R.id.goLocationButton); goToSearch.setOnClickListener(this); locationEditText = (EditText)findViewById(R.id.addressTextBox); locationEditText.setVisibility(View.GONE); goToSearch.setVisibility(View.GONE); locManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);//?? locManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 1000, 100, this); //checks network connectivity boolean checkConnection = isNetworkAvailable(); if(!checkConnection){ Toast.makeText(getApplicationContext(), "Check your Network Connectivity", Toast.LENGTH_LONG).show(); } if(checkConnection){ //sets current location parameters for the user lastKnownLocation = RestaurantHelper.getLastKnownLocation(this); //Log.v("NearbyRestaurantActivity", "This"+this); RestaurantApplication application = (RestaurantApplication) this.getApplication(); RestaurantAdapter restaurantAdapter = new RestaurantAdapter(this, R.layout.restaurantrow, R.id.label,new ArrayList<RestaurantReference>()); restaurantAdapter.setLastKnownLocation(lastKnownLocation); //set a global variable for the RestaurantAdapter in the RestaurantApplication class. application.setRestaurantAdapter(restaurantAdapter); //Set the adapter first and then update it when the RestaurantHttpAsyncTask makes a web service call. setListAdapter(restaurantAdapter); //Make a webservice call in a different thread passing Keyword for URL as a string array. RestaurantHttpAsyncTask m_progressTask; String[] keywords = {"", "american", "asian", "italian","mexican"}; //String[] keywords = {"indian"}; m_progressTask = new RestaurantHttpAsyncTask(NearbyRestaurantActivity.this, keywords); m_progressTask.setRestaurantAdapter(restaurantAdapter); m_progressTask.execute(); } } @Override public void onClick(View v) { //Refresh button helps to refresh the restaurant list on location change. Again it makes a call to the webservice using Async Task if(v.getId() == refreshButton.getId() ){ try { gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch (Exception ex) { ex.printStackTrace(); } try { network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch (Exception ex) { ex.printStackTrace(); } // don't start listeners if no provider is enabled if (!gps_enabled && !network_enabled) { Toast.makeText(getApplicationContext(), "Sorry, Location is not determined. Please enable your Network Providers.", Toast.LENGTH_LONG).show(); } //check network connectivity before refresh boolean checkConnection = isNetworkAvailable(); if(!checkConnection){ Toast.makeText(getApplicationContext(), "Check your Network Connectivity", Toast.LENGTH_LONG).show(); } if(checkConnection){ RestaurantApplication application = (RestaurantApplication) this.getApplication(); RestaurantAdapter restaurantAdapter = new RestaurantAdapter(this, R.layout.restaurantrow, R.id.label, new ArrayList<RestaurantReference>()); restaurantAdapter.setLastKnownLocation(lastKnownLocation); //set a global variable for the RestaurantAdapter in the RestaurantApplication class. application.setRestaurantAdapter(restaurantAdapter); //Set the adapter first and then update it when the RestaurantHttpAsyncTask makes a web service call. setListAdapter(restaurantAdapter); //Make a webservice call in a different thread passing Keyword for URL as a string array. RestaurantHttpAsyncTask m_progressTask, m_progressTask1; String[] keywords = {"", "american", "asian", "italian","mexican", "chinese", "indian"}; //String[] keywords = {"Chinese"}; m_progressTask = new RestaurantHttpAsyncTask(NearbyRestaurantActivity.this, keywords); m_progressTask.setRestaurantAdapter(restaurantAdapter); m_progressTask.execute(); } } if(v.getId() == goToSearch.getId() ){ Activity child = this; while(child.getParent() != null){ child = child.getParent(); } TabGroup1Activity parent = (TabGroup1Activity)getParent(); InputMethodManager imm = (InputMethodManager)getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(locationEditText.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); //changes ** restaurantAdapter to RestaurantAdapter1 to test & application to application1 RestaurantApplication application1 = (RestaurantApplication) this.getApplication(); RestaurantAdapter restaurantAdapter1 = new RestaurantAdapter(this, R.layout.restaurantrow, R.id.label, new ArrayList<RestaurantReference>()); restaurantAdapter1.setLastKnownLocation(lastKnownLocation); //set a global variable for the RestaurantAdapter in the RestaurantApplication class. application1.setRestaurantAdapter(restaurantAdapter1); //Set the adapter first and then update it when the RestaurantHttpAsyncTask makes a web service call. setListAdapter(restaurantAdapter1); //Make a webservice call in a different thread passing Keyword for URL as a string array. RestaurantHttpAsyncTaskTextSearch m_progressTask, m_progressTask1; String keywords = locationEditText.getText().toString(); if(keywords.equals("")){ keywords = "Pizza in Palo Alto"; } keywords = keywords.replaceAll(" ", "%20"); keywords = keywords.replaceAll(",", "%20"); m_progressTask = new RestaurantHttpAsyncTaskTextSearch (NearbyRestaurantActivity.this, keywords); m_progressTask.setRestaurantAdapter(restaurantAdapter1); m_progressTask.execute(); locationEditText.setVisibility(View.GONE); goToSearch.setVisibility(View.GONE); } if(v.getId() == searchRestaurants.getId() ){ if(goToSearch.isShown() == true){ goToSearch.setVisibility(View.GONE); locationEditText.setVisibility(View.GONE); } else if(goToSearch.isShown() == false){ //check network connectivity before refresh boolean checkConnection = isNetworkAvailable(); if(!checkConnection){ Toast.makeText(getApplicationContext(), "Check your Network Connectivity", Toast.LENGTH_LONG).show(); } if(checkConnection){ goToSearch.setVisibility(View.VISIBLE); locationEditText.setVisibility(View.VISIBLE); } } } } //Method to check network connectivity public boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting()) { //Log.d("network", "Network available:true"); return true; } else { //Log.d("network", "Network available:false"); return false; } } @Override protected void onResume() { super.onResume(); locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 50, 100, this); //Log.v("NearbyRestaurantActivity", "In OnResume()"); } @Override protected void onPause() { super.onPause(); locManager.removeUpdates(this); //Log.v("NearbyRestaurantActivity", "In onPause()"); } @Override public void onLocationChanged(Location location) { // TODO Auto-generated method stub } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } } public class RestaurantHelper { public static double[] getLastKnownLocation(Activity activity){ double lat = 0.0; double lon = 0.0; LocationManager lm = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); Location location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if(location == null){ lat = 0.0; lon = 0.0; } else{ //Log.v("Latitude", Double.toString(location.getLatitude())); //Log.v("Longitude", Double.toString(location.getLongitude())); lat = location.getLatitude(); lon = location.getLongitude(); } return new double[]{lat,lon}; } } 

Solutions Collecting From Web of "Android locationManager requestLocationUpdates不起作用"

快速获取更新位置信息的主要原因是您依赖于RestaurantHelper.getLastKnownLocation()方法中的NETWORK_PROVIDER ,但在onCreate()GPS_PROVIDER注册了一个LocationListener。

所以,这个代码在RestaurantHelper.getLastKnownLocation()

 Location location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

…应改为:

 Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 

从理论上讲,这应该给你最新的GPS位置,当你注册听众时应该刷新。 相反,您也可以更改为侦听onCreate()NETWORK_PROVIDER ,并按原样离开RestaurantHelper.getLastKnownLocation() 。 这取决于您的准确度要求 – 如果您想要高精确度的位置将最近的位置返回到最近的build筑物水平(例如, GPS_PROVIDER ),您应该使用GPS_PROVIDER 。 但是,如果您能够以较粗的精度生活,那么NETWORK_PROVIDER通常会比GPS更快地返回一个新的位置,特别是在室内的情况下,有时这可以相当准确地从WiFi中导出。

另一种方法是通过在onCreate()通过两个requestLocationUpdates()行注册来侦听GPS_PROVIDERNETWORK_PROVIDER ,然后检查以查看lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);上Location的最新时间戳lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); ,并使用最近更新的那个。

我还build议进行以下更改,以使您的代码在大量Android设备上可靠:

  1. 在侦听GPS或NETWORK位置更新时,将requestLocationUpdates() minDistance参数指定为0 – 直到Android 4.1,minDistance参数的历史不可靠且不可预测。
  2. 切换到新的Fused位置提供程序 – 调用getLastKnownLocation()方法时, getLastKnownLocation()比Android框架位置API更可靠,并且在不同设备之间更一致。 请注意,这依赖于Google Play服务SDK,该SDK仅适用于Android 2.2及更高版本。

我有2个build议给你

  1. LocationClient video ,是做位置的新方法。 它对LocationManager的改进可能是一个很难pipe理和发展的问题。

  2. 如果你需要使用LocationManager,你必须知道requestLocationUpdates是错误的(非常错误)。 由于在定制硬件上的所有实现都不相同。 有一个黑客/解决方法的作品。 在调用requestLocationUpdates之前,先踢下面的内容

代码:

  HomeScreen.getLocationManager().requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } @Override public void onLocationChanged(final Location location) { } }); 

requestLocationUpdates是越野车。 使用networking供应商总是触发onLocationChanged(…)

 locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 100, this) 

只有在使用networking供应商使用GPS背靠背后:

 locManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 1000, 100, this) 

在请求gps位置更新之前,不要忘记检查gps是否启用。