2016-08-12 64 views
4

我正在開發一個科爾多瓦Android/iOS應用程序與一些位置跟蹤。 要不斷更新位置,我使用背景地理位置插件(https://github.com/mauron85/cordova-plugin-background-geolocation)。科爾多瓦Android背景插件5分鐘後死亡

這個插件創建一個服務,該服務監聽系統LocationManager。 當系統獲得位置更新時,插件會觸發一個事件鏈/一些計算,直到它達到我在我的cordova應用程序中使用的最終JavaScript回調。

它可以在iOS上正常工作,並且永遠不會被殺死,但是當您將手機置於睡眠狀態(鎖定屏幕)而未在前臺顯示應用時,我遇到了Android的問題(假設您切換到另一個鎖定前的應用程序)。 如果您移動(從而獲取位置更新),則此過程將繼續運行。但是如果你靜置超過5分鐘,後臺位置服務停止,並且沒有更多位置傳遞給我的JS回調。 在此之後,如果您再次移動服務停止,直到您解鎖屏幕並將應用程序放到前臺。

這很煩人,因爲我的應用程序完全基於此停止和去模式,需要在鎖定屏幕(口袋裏的電話)下運行,並且我的服務器檢查位置的時間戳以過濾誰被視爲在線和活躍在一個新的地點,誰不是。 所以我基本上需要2件事:當用戶再次移動時能夠重新啓動位置跟蹤,並且如果用戶空閒,則繼續向我的服務器發送一些位置。

從我的研究中,我最終創建了一個睡眠時間爲60s並回退的線程,每分鐘調用我的後臺服務(將位置發送給前端JS)的句柄位置函數。 不幸的是,我是Cordova Plugin的新手,並沒有設法讓它工作。我有一個空指針異常,同時試圖訪問該應用上下文的systemService:

E/AndroidRuntime(4627): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference 
E/AndroidRuntime(4627):  at android.content.ContextWrapper.getSystemService(ContextWrapper.java:583) 
E/AndroidRuntime(4627):  at com.tenforwardconsulting.cordova.bgloc.ForcedUpdateLocation.handleLocationFromOutside(ForcedUpdateLocation.java:12) 
E/AndroidRuntime(4627):  at com.tenforwardconsulting.cordova.bgloc.BackgroundGeolocationPlugin$3.run(BackgroundGeolocationPlugin.java:266) 
E/AndroidRuntime(4627):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
E/AndroidRuntime(4627):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
E/AndroidRuntime(4627):  at java.lang.Thread.run(Thread.java:818) 

插件的啓動功能:

public ComponentName startBackgroundService() { 
    if (isEnabled) { return null; } 
    Class serviceProviderClass = null; 

    try { 
     serviceProviderClass = ServiceProvider.getClass(config.getServiceProvider()); 
    } catch (ClassNotFoundException e) { 
     callbackContext.error("Configuration error: provider not found"); 
     return null; 
    } 

    Activity activity = this.cordova.getActivity(); 
    Log.d(TAG, "Starting bg service"); 

    registerActionReceiver(); 
    locationServiceIntent = new Intent(activity, serviceProviderClass); 
    locationServiceIntent.addFlags(Intent.FLAG_FROM_BACKGROUND); 
    // locationServiceIntent.putExtra("config", config.toParcel().marshall()); 
    locationServiceIntent.putExtra("config", config); 
    isEnabled = true; 


    //Start a thread to send a position every 60s 
    final ForcedUpdateLocation ful = new ForcedUpdateLocation(); 

    cordova.getThreadPool().execute(new Runnable(){ 
     public void run(){ 
      try { 
       while(isEnabled){ 
        Thread.sleep(3000); 
        Log.d(TAG, "Force location sent"); 

        ful.handleLocationFromOutside(); 

       } 
      } catch (InterruptedException e){ 
       Log.d(TAG, "EXCEPTION ! Force location sent", e); 
      } 
     } 
    }); 


    return activity.startService(locationServiceIntent); 
} 

我的存根「ForcedUpdateLocation」服務,擴展了該插件的LocationService(呼籲handleLocation):

package com.tenforwardconsulting.cordova.bgloc; 

import android.location.Location; 
import android.content.Context; 
import android.location.LocationManager; 


public class ForcedUpdateLocation extends com.tenforwardconsulting.cordova.bgloc.AbstractLocationService { 

    public void handleLocationFromOutside(){ 

     LocationManager locationMangerWakeThread = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 

     Location location = locationMangerWakeThread.getLastKnownLocation(locationMangerWakeThread.GPS_PROVIDER); 

     handleLocation(location); 
    } 

    @Override 
    protected void cleanUp(){ 
     //Stub 
    }; 

    @Override 
    protected void startRecording(){ 
     //Duh 
    }; 

    @Override 
    protected void stopRecording(){ 
     //Wouf ? 
    }; 
} 

除了事實我堅持這一點,我覺得這個解決方案真的很醜...

那麼保持此服務運行的最佳方式是什麼?有沒有最佳做法,以保持長時間在後臺運行閒置進程?

非常感謝

回答

1

嘗試使用 'stopOnTerminate' 和 'startOnBoot' 這個插件的選項。 這將幫助你不斷得到更新的背景,即使應用程序被操作系統殺死。

也請記住,您的callbk函數並不總是執行,因爲如果您的應用程序被系統殺死,這將會終止您的活動和您的callbk。 因此,請嘗試使用url該插件的選項即使在後臺也不會將您的位置發佈到服務器。