2016-08-12 5 views
4

私はCordova Android/iOSアプリケーションをいくつかの位置追跡機能を使って開発しています。 位置を継続的に更新するには、背景ジオロケーションプラグイン(https://github.com/mauron85/cordova-plugin-background-geolocation)を使用します。5分後にCordovaアンドロイドのバックグラウンドプラグインが殺される

このプラグインは、システムLocationManagerをリッスンするサービスを作成します。 システムが位置更新を取得すると、コードラインアプリで使用する最終的なJavaScriptコールバックに達するまで、プラグインはイベントチェーン/いくつかの計算を実行します。

iOSでうまく動作し、決して死ぬことはありませんが、フォアグラウンドでアプリを持っていない間に電話をスリープ状態にすると(Androidを使用しているとき)、Androidに問題があります(別のロック前のアプリ)。 移動すると(場所の更新を取得すると)、プロセスは実行を継続します。しかし、あなたが5分以上静止していると、バックグラウンドロケーションサービスは停止し、JSコールバックにはロケーションが渡されなくなります。 その後、再度移動すると、サービスを停止したままにして、画面をロック解除してアプリをフォアグラウンドにするまで続きます。

私のアプリは完全にこのストップ&ゴーパターンに基づいており、ロックされた画面(ポケットの中の携帯電話)で実行する必要があり、私のサーバーは、オンラインとみなされる人をフィルタする場所のタイムスタンプをチェックし、新鮮な場所で活発で、誰がそうでないのか。 私は基本的に2つのことが必要です。つまり、ユーザーが再び移動したときに位置追跡を再開し、ユーザーがアイドル状態であればサーバーにいくつかの場所を送信し続けることができるようにします。

私の研究から、私はバックグラウンドサービス(フロントJSに位置を送信する)のハンドル位置機能を呼び出して、60秒間スリープしてループバックするスレッドを作成しました。 残念ながら、私はCordova Pluginを初めて使用していて、それを動作させることはできませんでした。

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」サービスが延びアプリコンテキストのエコプリンティングにアクセスしようとしているとき、私は、nullポインタ例外を抱えていますプラグイン(handleLocationのためにコールする)のLocationService:

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' オプションを使用してみてください。 これは、アプリがOSによって殺されたとしても、バックグラウンドでアップデートを続けるのに役立ちます。

あなたのアプリケーションがシステムによって殺された場合、これはあなたの活動とcallbkを殺すため、あなたのcallbk機能は必ず実行されるとは限りません。 プラグインのオプションurlを使用して、バックグラウンドでもサーバーに現在地を投稿してください。

関連する問題