【问题标题】:Android Try Getting location for X seconds without freezing the appAndroid 尝试在不冻结应用的情况下获取位置 X 秒
【发布时间】:2013-05-15 00:46:38
【问题描述】:

我想做的是从 2 个提供商那里获取 GPS 位置,第一个是最准确的 GPS,第二个是 GPS 和网络结合的 aGPS。我这样做是因为当普通 GPS 需要更多时间才能获取时,即使在高层建筑中,aGPS 也可以获取位置。 我想要的是尝试从第一个提供者(GPS)获取位置 10 秒,如果在这 10 秒内我得到一个位置!= null,我打破定时循环并将结果带到主线程,这是主线程活动。否则,如果有的话,我会从第二个提供商 (aGPS) 那里获取位置。如果没有提供者能够获取位置,我将在 10 秒后返回 null。 我面临的问题是,当我执行定时循环时,应用程序会冻结 10 秒,因此我无法获取主要活动的位置。

这里我试图获取扩展 Activity 的 HomeActivity 类的位置:

Button btnRedCross = (Button) this.findViewById(R.id.btnRedCross);
        btnRedCross.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                OutRequestsDatabaseHandler db =new OutRequestsDatabaseHandler();
                OutRequest outreq = new OutRequest();
                outreq.setName("Red Cross");
                //TODO get the message from LocalUser db
                Calendar cal = Calendar.getInstance();
                outreq.setDate(cal.getTimeInMillis());
                outreq.setMessage("My Message");
                outreq.setType("RedCross");
                //outreq.setLongitude(12.123456);
                //outreq.setLatitude(12.123456);
                db.addOutRequest(HomeActivity.this, outreq);
                //HERE I AM TRYING TO GET THE LOCATION
                GPSTracker locationtracker=new GPSTracker(HomeActivity.this);
                location=locationtracker.getLocation();
                Log.i("LocationGetter","Result: Longitude:"+location[0]+" Latitude:"+location[1]);
            }
        });
    }

这是 2 个提供者尝试获取位置的 GPSTracker 类:

public class GPSTracker{
    Context con;
    LocationManager locMgr;
    private double longgps;
    private double latgps;
    private double longnetwork;
    private double latnetwork;
    private LocationListener gpsLocationListener;
    private LocationListener networkLocationListener;
    public GPSTracker(final Context context){
        con = context;
        locMgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        LocationProvider high = locMgr.getProvider(locMgr.getBestProvider(
                createFineCriteria(), true));
        LocationProvider low = locMgr.getProvider(locMgr.getBestProvider(
                createCoarseCriteria(), true));
        //GET LOCATION FROM GPS
         gpsLocationListener = new LocationListener() {

            @Override
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }

            @Override
            public void onProviderDisabled(String provider) {
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                        context);
                alertDialogBuilder
                        .setMessage(
                                "Please Enable GPS and Network For Accurate Result")
                        .setCancelable(false)
                        .setPositiveButton("Enable GPS",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,
                                            int id) {
                                        Intent callGPSSettingIntent = new Intent(
                                                android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                        context.startActivity(callGPSSettingIntent);
                                    }
                                });
                alertDialogBuilder.setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });
                AlertDialog alert = alertDialogBuilder.create();
                alert.show();
            }

            @Override
            public void onLocationChanged(Location location) {
                longgps = location.getLongitude();
                latgps = location.getLatitude();
                //Log.i("LocationGetter", "GPS: Longitude:" + longgps+ " Latitude:" + latgps);

            }
        };
        locMgr.requestLocationUpdates(high.getName(), 0, 0f,gpsLocationListener);
        //GET LOCATION FROM GPS + NETWORK
        networkLocationListener=new LocationListener() {

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderEnabled(String provider) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderDisabled(String provider) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onLocationChanged(Location location) {
                longnetwork = location.getLongitude();
                latnetwork = location.getLatitude();
                //Log.i("LocationGetter", "Network: Longitude:"+ longnetwork + " Latitude:" + latnetwork);

            }
        };
        locMgr.requestLocationUpdates(low.getName(), 0, 0f,networkLocationListener);
    }

    public static Criteria createFineCriteria() {

        Criteria c = new Criteria();
        c.setAccuracy(Criteria.ACCURACY_FINE);
        c.setAltitudeRequired(false);
        c.setBearingRequired(false);
        c.setSpeedRequired(false);
        c.setCostAllowed(true);
        c.setPowerRequirement(Criteria.POWER_HIGH);
        return c;

    }

    public static Criteria createCoarseCriteria() {

        Criteria c = new Criteria();
        c.setAccuracy(Criteria.ACCURACY_COARSE);
        c.setAltitudeRequired(false);
        c.setBearingRequired(false);
        c.setSpeedRequired(false);
        c.setCostAllowed(true);
        c.setPowerRequirement(Criteria.POWER_HIGH);
        return c;
    }

    public double[] getLocation() {
    double location[] = new double[2];
    Calendar cal = Calendar.getInstance();
    Long endtime = cal.getTimeInMillis() + 10000;
    while (Calendar.getInstance().getTimeInMillis() < endtime) {
        if (longgps != 0 && latgps != 0) {
            location[0] = longgps;
            location[1] = latgps;
            Log.i("LocationGetter", "GPS: Longitude:" + location[0]
                    + " Latitude:" + location[1]);
            break;
        } else if (longnetwork != 0 && latnetwork != 0) {
            location[0] = longnetwork;
            location[1] = latnetwork;
            Log.i("LocationGetter", "Network: Longitude:" + location[0]
                    + " Latitude:" + location[1]);
        }
    }
    locMgr.removeUpdates(networkLocationListener);
    locMgr.removeUpdates(gpsLocationListener);
    networkLocationListener = null;
    gpsLocationListener = null;
    return location;
}
}

【问题讨论】:

  • 您不能等待 10 秒,并且您的代码很可能会修复网络位置。
  • 如果 GPS 在 10 秒内到达但晚于网络,您是否要等待 GPS 修复?
  • Hoan 我会在 10 秒后获取网络位置。但是在 10 秒内如果我能得到 gps 位置,10 秒循环中断,我会得到 gps 位置。
  • 事情不在逻辑中。问题是,当我循环一段时间(10 秒)时,应用程序会冻结 10 秒

标签: android timer gps location


【解决方案1】:

这不只是一个多线程问题。可以创建第二个线程,而不是在主线程上执行工作,这样该线程是否空闲 10 秒都无关紧要。

顺便说一句,我认为最好使用所有提供者并根据其准确性使用卡尔曼滤波器信任它们,而不是依赖任何单个提供者。请参阅my answer here 了解似乎在 Android 位置提供程序的上下文中工作的简单卡尔曼滤波器。

【讨论】:

    【解决方案2】:

    通过声明没有正文的方法 updatedLocation(Location loc) 使您的 GPSTracker 类抽象。在代码中

    public abstract class GPSTracker{
        .......
        private Location mLocation;
    
        public void updateLocation(Location loc);  
    
        private CountDownTimer mNetworkCountDown = new CountDownTimer(10000, 10000)
        {
    
            @Override
            public void onTick(long millisUntilFinished)
            {
    
            }
    
            @Override
            public void onFinish()
            {
                            // this onFinish() will be called if not cancel by Gps
                locMgr.removeUpdates(networkLocationListener);
                            updateLocation(mLocation);
            }
        }; 
    
            private CountDownTimer mGpsCountDown = new CountDownTimer(10000, 10000)
        {
    
            @Override
            public void onTick(long millisUntilFinished)
            {
    
            }
    
            @Override
            public void onFinish()
            {
                locMgr.removeUpdates(gpsLocationListener);
            }
        };   
            .........
            gpsLocationListener = new LocationListener() {
            ..........
            @Override
            public void onLocationChanged(Location location) {
                // Get a gps fix cancel both countdowns and listeners
                mGpsCountDown.cancel();
                mNetworkCountDown.cancel();
                locMgr.removeUpdates(gpsLocationListener);
                locMgr.removeUpdates(networkLocationListener);
                // The calling class will get the fix
                updateLocation(location);
    
                longgps = location.getLongitude();
                latgps = location.getLatitude();
                //Log.i("LocationGetter", "GPS: Longitude:" + longgps+ " Latitude:" + latgps);
    
            }
        };
        locMgr.requestLocationUpdates(high.getName(), 0, 0f,gpsLocationListener);
        mGpsCountDown.start();
        .......
        networkLocationListener=new LocationListener() {
        ..........
        @Override
            public void onLocationChanged(Location location) {
                // No cancelation here, Gps will cancel if it gets a fix
                mLocation = location;
                longnetwork = location.getLongitude();
                latnetwork = location.getLatitude();
                //Log.i("LocationGetter", "Network: Longitude:"+ longnetwork + " Latitude:" + latnetwork);
    
            }
        };
        locMgr.requestLocationUpdates(low.getName(), 0, 0f,networkLocationListener);
        mNetworkCountDown.start();
        .........
        // remove the getLocation()
    } 
    

    在 HomeActivity 类中创建一个扩展 GPSTracker 的类

    public class HomeActivity extends Activity {
    .........
        public class MyGPSTracker extends GPSTracker
        {
             public void updateLocation(Location location)
             {
                  // location would be null if both Gps and Network did not
                  // get a fix in 10 seconds
                  if (location != null)
                  {
                      // do whatever you want with this location fix
                      // If you want to know if this fix is from GPS or Network
                      // just use String provider = location.getProvider()
                      Log.i("LocationGetter","Result: Longitude:"+location.getLongitude()+" Latitude:"+location.getLatitude);
                  }
             }
         }
    
         Button btnRedCross = (Button) this.findViewById(R.id.btnRedCross);
        btnRedCross.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View arg0) {
                OutRequestsDatabaseHandler db =new OutRequestsDatabaseHandler();
                OutRequest outreq = new OutRequest();
                outreq.setName("Red Cross");
                //TODO get the message from LocalUser db
                Calendar cal = Calendar.getInstance();
                outreq.setDate(cal.getTimeInMillis());
                outreq.setMessage("My Message");
                outreq.setType("RedCross");
                //outreq.setLongitude(12.123456);
                //outreq.setLatitude(12.123456);
                db.addOutRequest(HomeActivity.this, outreq);
                //HERE I AM TRYING TO GET THE LOCATION
                GPSTracker locationtracker=new MyGPSTracker(HomeActivity.this);
                // You will get the location when updateLocation is called by the
                // MyGPSTracker class
                Log.i("LocationGetter","Result: Longitude:"+location[0]+" Latitude:"+location[1]);
            }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-28
      相关资源
      最近更新 更多