2012-11-28 109 views
1

詳情:位置跟蹤在後臺服務問題的Android

我有需要做以下服務: - 不斷地監聽GPS位置,以50米作爲參數(正常工作),併發送到服務器 - 每60秒,如果沒有讀取GPS位置,開始監聽網絡位置並將其發送到服務器

這聽起來很奇怪,但這是項目要求。因此,用戶一直在使用GPS進行跟蹤。當他停下來,或GPS沒有鎖定,或者在建築物內時,每隔60秒開始一次快速的網絡位置讀取,並將此位置發送到服務器。由於該服務使用與主應用程序相同的線程,因此每個服務器更新都在其自己的線程中完成。還有一件重要的事情:每個位置讀取應該一個接一個地發送,例如,如果用戶正在駕駛,並且多次讀取完成,則每個位置應該在前一個發送之後發送到服務器。這就是爲什麼我決定使用ScheduledExecutorService,因爲我可以提交線程,他們將一個接一個地執行。

下面是代碼:

private ScheduledExecutorService scheduleTaskExecutor; 
Handler locationHandler = new Handler(); 
private Location lastNetworkLocation; 

@Override 
    public void onStartCommand() { 
     scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor(); 

     //prepare to execute Network reading every 60 seconds 
     scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() { 
      @Override 
      public void run() { 
        initNetworkReadings(); 

        //usually a network location read is done almost instantly 
        //however after 5 seconds I check if a location has been read by the Network listener inside the locationRunnable 
        locationHandler.postDelayed(locationRunnable, 5000); 
       } 

      } 
     }, 60, 60, TimeUnit.SECONDS); 

     locationRunnable = new Runnable() { 
      @Override 
      public void run() { 
        if (lastNetworkLocation !=null){ 
         //send location to the server if valid 
        } 
      lastNetworkLocation = null; 
      } 
     } 
    } 

    private void initNetworkReadings() { 
     locationManager.removeUpdates(locationListenerNetwork); 
     try { 
      isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } catch (Exception ex) { 
     } 

     if (isGpsEnabled) { 
     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); 
     } 
    } 

    LocationListener locationListenerNetwork = new LocationListener() { 
    @Override 
    public void onLocationChanged(Location location) { 
     lastNetworkLocation = location; 
     // stop listening for Network locations 
     locationManager.removeUpdates(locationListenerNetwork); 
    } 
    ... 
    } 

每次我讀了GPS位置我將它添加到線程的隊列:

scheduleTaskExecutor.submit(new Runnable() { 
     @Override 
     public void run() { 
      updateLocationOnServer(readLocation); 
     } 
    }); 

我的問題是,網絡位置聽衆從來沒有得到onLocationChanged()調用,當我使用它在上面的代碼中,在Runnable中。但如果我加上服務啓動,initNetworkReadings(),我得到onLocationChanged()立即開除。所以我認爲這與在scheduleAtFixedRate中使用有關。 您認爲這可能是什麼問題?我想到工作流程的方式有什麼不好?

回答

1

如果嘗試使用Handler和Runnable而不是scheduleAtFixedRate()設置重新分配,該怎麼辦?

Handler h = new Handler(); 
Runnable run = new Runnable(){ 
    //Do your repeititive work here! 
    h.postDelayed(run, 60 * 1000); 
}; 
h.post(run); 
0

同樣的問題, 我有一個檢測位置的後臺服務。 如果網絡可用,它使用網絡,否則它使用gps。

它適用於許多智能手機 (nexus 4.1,galaxy nexus 4.2,galaxy note),但是Galaxy s3 jb(4.1)的網絡位置永遠不會上升到任何位置。

與gps位置相同的代碼,工作得很好。