Android GPS超时

Android GPS超时,android,gps,Android,Gps,编辑:我重写这个问题是因为我显然不清楚 有时Android手机上的GPS服务需要很长时间才能得到修复。有时很快,有时需要几个小时。我知道并接受这一点 我有一个可以做很多事情的应用程序。它必须做的一件事是允许用户单击按钮将其当前坐标发送到服务器。我需要的是手机的坐标,当用户点击按钮或在一个合理的短时间之后 因为我知道获得GPS定位不是即时的,而且我知道可能需要几分钟或几小时(在这段时间内,用户移动了很长的距离),所以我需要为此功能编写一个超时代码。对于此功能,在用户单击按钮三分钟(例如)后上载其G

编辑:我重写这个问题是因为我显然不清楚

有时Android手机上的GPS服务需要很长时间才能得到修复。有时很快,有时需要几个小时。我知道并接受这一点

我有一个可以做很多事情的应用程序。它必须做的一件事是允许用户单击按钮将其当前坐标发送到服务器。我需要的是手机的坐标,当用户点击按钮或在一个合理的短时间之后

因为我知道获得GPS定位不是即时的,而且我知道可能需要几分钟或几小时(在这段时间内,用户移动了很长的距离),所以我需要为此功能编写一个超时代码。对于此功能,在用户单击按钮三分钟(例如)后上载其GPS位置是不可接受的。45秒就可以了,75秒就不行了。如果功能无法足够快地获取位置,则可以向用户发出错误通知

我需要一个功能“获取GPS位置并将其发送到服务器,除非需要一分钟以上”

我的原始代码如下。我已经改变了一些事情,因为张贴它。我在onStartCommand()方法中添加了一个计时器。我启动一个TimerTask,60秒后将调用我的stop()方法。在onLocationChanged()方法的开头,我取消了TimerTask

我的问题是:计时器方案是实现此超时的好方法吗?有更好的办法吗

原始问题:

我正在编写一个Android应用程序,当用户告诉它时,它需要将当前的GPS坐标发送到服务器。从上下文菜单中,我运行下面的服务。该服务是LocationListener,并从LocationManager请求更新。当它获得一个位置(onLocationChanged())时,它会将自己作为侦听器删除,并将坐标发送给服务器。所有这些都在起作用

然而,如果GPS坐标不能很快获得,我的服务就会一直运行,直到得到一些。它会在UI上显示一个进度对话框,这很烦人。更糟糕的是,如果用户在启动服务后已移动,则第一个GPS坐标可能错误,应用程序将向服务器发送错误数据

我需要暂停服务。有什么好办法吗?我对线程不是很有经验。我想我可以在onStartCommand()方法中运行Runnable,它将以某种方式倒计时30秒,然后,如果还没有GPS结果,调用我的服务的stop()方法。这听起来是最好的方法吗

或者,是否可以告知GPS是否无法获得定位?我该怎么做呢

编辑:为了进一步澄清,我正在寻找最好的方式,在一段时间后“放弃”获得一个位置

public class AddCurrentLocation extends Service implements LocationListener {

    Application app;
    LocationManager mLocManager;
    ProgressDialog mDialog;

    @Override
    public int onStartCommand(Intent intent, int arg0, int arg1) {
        app = getApplication();

        // show progress dialog
        if (app.getScreen() != null) {
            mDialog = ProgressDialog.show(app.getScreen(), "", "Adding Location. Please wait...", true);
        }

        // find GPS service and start listening
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        String bestProvider = mLocManager.getBestProvider(criteria, true);
        mLocManager.requestLocationUpdates(bestProvider, 2000, 0, this);

        return START_NOT_STICKY;
    }

    private void stop() {
        mLocManager.removeUpdates(this);
        if (mDialog != null) {
            mDialog.dismiss();
        }
        stopSelf();
    }

    @Override
    public void onLocationChanged(Location location) {
        // done with GPS stop listening
        mLocManager.removeUpdates(this);

        sendLocation(location); // method to send info to server
        stop();
    }

    // other required methods and sendLocation() ...

}

事实并非如此。在大多数情况下,获得GPS定位总是需要很长时间。但是从那时起,每次更新(代码中每2秒)都将是此人的当前位置。你得到的第一个修正是此人的当前位置,因此数据不会“过时”

还有一件事。如果您在服务中运行此代码,则不应使用进度对话框阻塞UI,而且绝对不应从服务中阻塞UI。这是一个等待发生的内存泄漏。仅当进度最多可能需要5秒,并且正在活动的线程中运行时,才应显示进度。另一个选项是在标题栏中显示“进度”对话框,并且仍然允许用户与应用程序交互(这就是为什么您仍然使用服务)。长时间显示进度真的不是那么友好。特别是如果他们不知何故改变了方向(可能是意外),然后你的应用程序因为对话框的服务句柄而崩溃,他们必须重新开始


请查看,以查看一个关于活动应如何与服务一起工作的很好的示例。它使用服务收回数据,并在服务执行某些工作时显示标题中的进度。还可以让你在应用程序中做其他事情。

斯科特,有许多因素会影响第一次修复所需的时间,甚至影响修复能否完成,最常见的是设备和卫星之间的物理障碍(如建筑物、峡谷墙等)

您无法控制GPS引擎提供修复所需的时间,但您可以告诉它是如何进行的,包括第一次修复的时间:

locationManager.addGpsStatusListener(gpsListener);

    // this reports on the status of the GPS engine, but does not enable additional controls 
    private static final GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            GpsStatus gpsStatus = locationManager.getGpsStatus(null);
            switch (event) {
                case GpsStatus.GPS_EVENT_STARTED: 
                    Log.i(TAG, "onGpsStatusChanged(): GPS started");
                    break;
                case GpsStatus.GPS_EVENT_FIRST_FIX: 
                    Log.i(TAG, "onGpsStatusChanged(): time to first fix in ms = " + gpsStatus.getTimeToFirstFix());
                    break;
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS: 
                    // int maxSatellites = gpsStatus.getMaxSatellites();    // appears fixed at 255
                    // if (H.DEBUG) Log.d(TAG, "onGpsStatusChanged(): max sats = " + maxSatellites);
                    if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): ##,used,s/n,az,el");
                    Iterable<GpsSatellite>satellites = gpsStatus.getSatellites();
                    Iterator<GpsSatellite>satI = satellites.iterator();
                    while (satI.hasNext()) {
                        GpsSatellite satellite = satI.next();
                        if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): " + satellite.getPrn() + "," + satellite.usedInFix() + "," + satellite.getSnr() + "," + satellite.getAzimuth() + "," + satellite.getElevation()); 
                        // http://en.wikipedia.org/wiki/Global_Positioning_System: the almanac consists of coarse orbit and status information for each satellite
                        // http://en.wikipedia.org/wiki/Ephemeris: the positions of astronomical objects in the sky at a given time
                        // + "," + satellite.hasAlmanac() + "," + satellite.hasEphemeris());
                    }
                    break;
                case GpsStatus.GPS_EVENT_STOPPED: 
                    Log.i(TAG, "onGpsStatusChanged(): GPS stopped");
                    break;
            }       
        }
    };
locationManager.addGpsStatusListener(gpsListener);
//这会报告GPS引擎的状态,但不会启用其他控制
私有静态最终GpsStatus.Listener gpsListener=new gpssstatus.Listener(){
公共无效onGpsStatusChanged(内部事件){
GpsStatus GpsStatus=locationManager.getGpsStatus(null);
开关(事件){
案例GpsStatus.GPS\u事件\u开始:
i(标记“onGpsStatusChanged():GPS启动”);
打破
案例GpsStatus.GPS\u事件\u第一个\u修复:
Log.i(标记“onGpsStatusChanged():在ms=“+gpsStatus.getTimeToFirstFix())中首次修复的时间);
打破
案例GpsStatus.GPS\事件\卫星\状态:
//int maxSatellites=gpsStatus.getMaxSatellites();//看起来固定在255
//if(H.DEBUG)Log.d(标记“onGpsStatusChanged():max sats=“+maxSatellites”);
if(H.VERBOSE)Log.d(标记“onGpsStatusChanged():##,used,s/n,az,el”);
IterableSatelites=gpsStatus.getSatellites();
迭代器ATI=satellites.iterator();
while(satI.hasNext()){
GpsSatellite卫星=satI.next();
如果(H.VERBOSE)Log.d(标记“onGpsStatusChanged():“+satellite.getPrn()+”,“+satellite.usedInFix()+”,“+satellite.getS