2010-06-07 37 views
12

編輯:我正在改寫這個問題,因爲我顯然不清楚。Android GPS超時

有時,Android手機上的GPS服務需要很長時間才能得到修復。有時候速度很快,有時需要幾個小時。我知道並接受這一點。

我有一個應用程序可以做很多事情。其中必須做的一件事就是允許用戶點擊一個按鈕將其當前座標發送到服務器。我需要的是當用戶點擊按鈕或之後在相當短的時間內電話的座標。

因爲我知道獲取GPS定位並不是即時的,我知道它可能需要幾分鐘或幾小時(在此期間用戶移動了很長距離),所以我需要爲此功能編碼超時。對於此功能,在用戶點擊按鈕後三分鐘(例如)上傳GPS位置是不可接受的。如果需要45秒,這很好,如果需要75秒,則不會。如果功能無法足夠快地獲取位置,則可以向用戶發出錯誤通知。

我需要一個功能'獲取GPS位置並將其發送到服務器,除非它需要超過一分鐘'。

我的原代碼如下。自發布以來,我改變了一些東西。我在onStartCommand()方法中添加了一個Timer。我啓動一個TimerTask,60秒後會調用我的stop()方法。在onLocationChanged()方法的開始處,我取消了TimerTask。

我的問題是:Timer方案是實現這個超時的好方法嗎?有沒有更好的辦法?

原題:

我正在寫一個Android應用程序,除其他事項外,需要發送當前的GPS座標到服務器,當用戶告訴它。從上下文菜單中,我運行下面的服務。該服務是一個LocationListener,並從LocationManager請求更新。當它獲取一個位置(onLocationChanged())時,它將自己作爲一個偵聽器並將座標發送到服務器。所有這些都在起作用。

但是,如果GPS座標不能快速提供,我的服務會持續運行,直到它獲得一些。它用一個進度對話框來阻止用戶界面,這很煩人。更糟糕的是,如果用戶在啓動該服務後已經移動,則第一個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() ... 

} 
+0

那麼你究竟做了什麼才能解決這個問題?我也有同樣的問題。 – sexitrainer 2011-02-22 20:39:08

回答

6

這並不是真的如何工作。在大多數情況下,它會持續很長時間才能獲得GPS定位。但從這一點來看,每次更新(代碼中每2秒)都將是該人員的當前位置。你得到的第一個修復將是該人的當前位置,因此數據不會「過時」。

另一件事。如果您在服務中運行此代碼,則不應該通過進度對話框阻止UI,並且絕對不能從服務中阻止。這是一個等待發生的內存泄漏。如果最多可能需要5秒,並且正在「活動」中的線程中運行,則只應顯示進度。另一個選項是在標題欄中顯示進度對話框,並讓用戶與應用程序進行交互(這就是爲什麼您使用服務的原因)。顯示很長一段時間的進展真的不是用戶友好的。特別是如果他們以某種方式改變方向(可能是偶然),然後你的應用程序因爲對話框的服務句柄而崩潰,並且他們必須重新開始。

查看Google I/O 2010 app查看活動應如何與服務配合使用的一個很好的例子。它使用服務來回拉數據,並在服務正在做一些工作時顯示標題中的進度。而且還可以讓你在應用中做其他事情。

+1

感謝您的幫助。我需要做的是當用戶選擇一個上下文菜單選項時獲取一個位置。因此,如果需要15分鐘才能獲得GPS定位(有時我的手機上有此功能),那麼該位置將會過時。基本上,我想知道用戶點擊按鈕時的位置,如果時間太長(無論如何),那麼我需要告訴用戶該功能失敗。在大多數情況下,用戶將坐在那裏看着手機,看看它是否工作。我不能讓他們坐在那裏幾個小時,沒有GPS信號:) – 2010-06-07 20:25:11

+0

如果是這樣的話,爲什麼你不啓動GPS時,當應用程序啓動,然後當他們按下按鈕,它很可能已經有一個修復。就像我之前說過的。隨着GPS的位置不會過時。它得到了解決,位置更新將成爲手機的當前位置。 – 2010-06-08 15:09:39

+0

我編輯了我的問題,以便更清楚。 – 2010-06-09 14:25:42

4

斯科特,有很多因素會影響第一次修補可能需要多長時間 - 甚至是否可以實現修復,最常見的是設備和衛星之間的物理障礙(如建築物,峽谷牆壁等) 。

你無法控制它需要多長時間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; 
      }  
     } 
    }; 

事件將作爲引擎生成嘗試聆聽可用衛星。在最近一次對光線障礙的測試中,我發現獲得初始修復需要22.4秒,在此期間,有24個SATELLITE_STATUS事件報告在接收到足夠乾淨的信號之前逐漸接入8顆衛星,以實現修復。這裏是最後一個事件:

06-08 23:23:25.147,D,GPS,22427,「onGpsStatusChanged():##,used,s/n,az,el」 06-08 23:23 :25.147,D,GPS,22427,「onGpsStatusChanged():2,真,26.0,57.0,73.0」 06-08 23:23:25.147,D,GPS,22427,「onGpsStatusChanged():4,真,30.0 ,GPS,22427,「onGpsStatusChanged():5,true,19.0,144.0,25.0」 06-08 23:23:25.155,D,GPS, 22427「onGpsStatusChanged():9,true,22.0,202.0,22.0」 06-08 23:23:25.155,D,GPS,22427,「onGpsStatusChanged():10,true,17.0,109.0,32.0」 06 -08 23:23:25.155,D,GPS,22427,「onGpsStatusChanged():12,true,32.0,320.0,80.0」 06-08 23:23:25.155,D,GPS,22427,「onGpsStatusChanged 29,真,21.0,278.0,21.0「 06-08 23:23:25.155,D,GPS,22427,「onGpsStatusChanged():30,true,31.0,312.0,43.0」 06-08 23:23:25.163,D,GpsLocationProvider,1039,TTFF:22457 06-08 23:23:25.194,I,GPS,22427,onGpsStatusChanged():首次修復的時間ms = 22457

請注意,在修復時間,您將獲取當前位置,而不是您曾經可能已經。我想現在你已經可以到達那裏了。或者,看看專業人士如何做到這一點here

+0

感謝您的幫助。我編輯我的問題更清楚。 – 2010-06-09 14:26:13

+0

@DJC,請更正斷開的鏈接到MyTracks.java。 – Gili 2012-04-17 04:56:32

+0

什麼是代碼中的H? – Siddhesh 2012-09-27 07:46:19

-7

基於回答肖恩,包裝參數爲JSON和發送JSON對象到服務器

1

我一直在掙扎了類似的問題,最近從計時器切換到AlarmManager ,這似乎更加健壯。這可能是你的情況矯枉過正(我正在使用這個重複位置採樣),但你可能想至少使用Handler而不是定時器。 (使用Handler.postDelayed。)