Android locationManager requestLocationUpdates不起作用

我正在开发一个列出最接近用户的餐厅的应用程序.当点击刷新按钮时,它会列出用户当前位置的餐馆.我正在使用位置管理器,只有当活动进入前台(onResume)才能请求更新,以避免电池的不断使用.当应用程序进入onPause()时,位置更新被停止.当我通过终端传递更新时,它在模拟器上工作正常.

问题:
当我改变我的位置(比如开车5英里远)时,我打开我的应用程序和活动来显示最近的餐厅,需要很长时间(4-5分钟)的位置刷新,直到应用程序继续显示以前的位置的餐厅.但是,如果我实际更改我的位置并访问Google地图,然后打开我的餐厅应用程序,那么它可以立即工作.我确保GPS被打开.一旦我打开我的活动,我可以做什么来让位置管理员踢和更新位置?
先谢谢你!

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(),Toast.LENGTH_LONG).show();
            }
            if(checkConnection){

                RestaurantApplication application = (RestaurantApplication) this.getApplication();
                RestaurantAdapter restaurantAdapter = new RestaurantAdapter(this,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 = {"","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,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(),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,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};
}
}

解决方法

您没有快速获取更新的位置信息的主要原因是您依赖于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()保持原样.这取决于您的准确性要求 – 如果您希望高精度位置将最近的位置返回到最近的建筑物级别(例如5-30米),则应使用GPS_PROVIDER.但是,如果您可以以更准确的方式生活,NETWORK_PROVIDER通常会返回一个比GPS更快的新位置,特别是如果您在室内,有时如果从WiFi导出,这可能相当准确.

另一种方法是通过在onCreate()中通过两个requestLocationUpdates()行注册来监听GPS_PROVIDER和NETWORK_PROVIDER,然后检查从lm.getLastKNownLocation(LocationManager.GPS_PROVIDER)的位置上查看最近的时间戳.和lm.getLastKNownLocation(LocationManager.NETWORK_PROVIDER);并使用最近更新的那个.

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

>在侦听GPS或NETWORK位置更新时,将requestLocationUpdates()mindistance参数指定为0 – mindistance参数具有由原始设备制造商解释的方式不可靠和不可预测的历史,直到Android 4.1.
>切换到新的Fused Location Provider – 当调用getLastKNownLocation()方法比Android框架的位置API更为可靠,并且在不同的设备之间更一致.请注意,这依赖于Google Play服务SDK(仅适用于Android 2.2及更高版本).

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...