0

私のフラグメントでは、クリックするとセンサーをポーリングするサービスが開始され、エグゼキュータサービスを使用してセンサデータがデータベースに保存されます。フラグメントのonClickは次のようになります。サービスからのAndroidクローズプログレスダイアログ

public void onClick(View v) { 
     if (!recordingStarted){ 
      try{ 
       recordingStarted = true; 
       mainActivity.startService(new Intent(mainActivity, SensorService.class)); 
       startButton.setText(getResources().getString(R.string.start_button_label_stop)); 
       Snackbar.make(coordinatorLayout, "Recording...", Snackbar.LENGTH_SHORT).show(); 
      } catch (SQLException e){ 
       mainActivity.logger.e(getActivity(),TAG, "SQL error insertSubject()", e); 
      } 
     } else { 
      dialog = new ProgressDialog(mainActivity); 
      dialog.setTitle("Stop recording"); 
      dialog.setMessage("Please wait..."); 
      dialog.show(); 

      mainActivity.stopService(new Intent(mainActivity, SensorService.class)); 
      startButton.setEnabled(false); 
      Snackbar.make(coordinatorLayout, "Recording stopped.", Snackbar.LENGTH_SHORT).show(); 
     } 
    } 

SensorServiceクラスはExecutorServiceを使用してデータベースに10ms毎にセンサデータを保存するように設定されています。

そのクラスの関連する部分は、以下のとおりです。

public class SensorService extends Service implements SensorEventListener { 

    public void onSensorChanged(SensorEvent event) { 
      //get sensor values here 

      //insert into database 
      try{ 
       executor.execute(insertHandler); 
      } catch (SQLException e) { 
       Log.e(TAG, "insertData: " + e.getMessage(), e); 
      } 
     } 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     dbHelper = new DBHelper(getApplicationContext()); 

     PowerManager manager = 
       (PowerManager) getSystemService(Context.POWER_SERVICE); 
     wakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 

     registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); 

     //Executor service and runnable for DB inserts 
     executor = Executors.newSingleThreadExecutor(); 
     insertHandler = new InsertHandler(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     super.onStartCommand(intent, flags, startId); 

     startForeground(Process.myPid(), new Notification()); 
     registerListener(); 
     wakeLock.acquire(); 

     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     //Prevent new tasks from being added to thread 
     executor.shutdown(); 

     try { 
      //Wait for all tasks to finish before we proceed 
      while (!executor.awaitTermination(10, TimeUnit.SECONDS)) { 
       Log.i(TAG, "Waiting for current tasks to finish"); 
      } 
     } catch (InterruptedException e) { 
      executor.shutdownNow(); 
     } 

     //Stop everything else once the task queue is clear 
     unregisterReceiver(receiver); 
     unregisterListener(); 
     wakeLock.release(); 
     dbHelper.close(); 
     stopForeground(true); 
    } 

    class InsertHandler implements Runnable { 
     public void run() { 
      dbHelper.insertData(Short.parseShort(MainActivity.subInfo.get("subNum")), System.currentTimeMillis(), 
        accelerometerMatrix[0], accelerometerMatrix[1], accelerometerMatrix[2], 
        accelerometerWorldMatrix[0], accelerometerWorldMatrix[1], accelerometerWorldMatrix[2], 
        gyroscopeMatrix[0], gyroscopeMatrix[1], gyroscopeMatrix[2]); 
     } 
    } 
} 

ので、ユーザはそのonCreateonStartCommand方法を通過SensorServiceボタンを押したとき。センサーデータが変更されると、Executorサービスがデータベースに挿入します。

ユーザーがボタンをもう一度押して停止すると、エグゼキュータにシャットダウンを指示しますが、現在のすべてのタスクの処理が完了します。エグゼキュータキューがクリアされると、データベースが閉じられ、リスナーの登録が解除されます。

エグゼキュータがシャットダウンを待ってキューをクリアするこの段階では、進行状況ダイアログを表示して、物事を閉鎖するプロセス。

停止ボタンを押すと、フラグメント自体にprogressdialogが表示されます。しかし、エグゼキュータ・サービスがキューの処理を終了し、正しくシャットダウンされた後でのみ、ダイアログを閉じることはできますか?

は、私は簡単に非同期タスクでこれを行うことができますが、それは

進捗ダイアログがフラグメントに属しオプションではありませんので、私はこの代わりのためのエグゼキュータのサービスを使用することを選択したので、私はからMainActivity.dialog.dismiss()ような何かを傾けますサービス内。とにかくそれを扱う非常にきれいな方法であるとは思わない

私はハンドラが残っていると思いますが、このケースではエグゼキュータサービスが別のサービス(SensorService)。これを解決するためにハンドラを使用すると、コードはどのように見えますか?

答えて

0

サービスがアクティビティコンポーネントに信号を送信するためのメカニズムが必要です。最も簡単で最も一般的な方法は、イベントバスを使用することです。これの適切な実装は完全にあなた次第ですが、既存のイベントバスライブラリを使用してあなたを支援することができます。あなたは簡単なGoogle検索でこれらを見つけることができます。

関連する問題