0

CountdownTimer を持つバックグラウンド サービスがあります。CountdownTimer がカウントダウンすると、アクティビティにブロードキャストを送信します。CountdownTimer がカウントダウンすると、Activity にアラートが送信され、サービスを停止して受信者の登録を解除できます。

通常のレシーバーの登録解除メソッドを onStop と onPause から、"timer_finished" でブロードキャストを受信したときに呼び出す独自のメソッドに移動しました。これは、登録を解除せずにアクティビティから移動できるようにするためです。

ユーザーが現在アクティビティを表示している場合、すべて正常に機能します。ユーザーがアクティビティから離れた場合、CountdownTimer は引き続き実行されますが、アクティビティはブロードキャストを受信して​​いません。

アクティビティが最終ブロードキャスト「timer_finished」を受信するようにするにはどうすればよいですか?

public class CountDownBroadcastService extends Service {

    private static final String TAG = CountDownBroadcastService.class.getSimpleName();

    public static final String COUNTDOWN_BR = "com.carefreegroup.rr3.countdown_br";
    Intent bi = new Intent(COUNTDOWN_BR);

    CountDownTimer cdt = null;
    Context mContext;

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

            mContext = this;

            Log.i(TAG, "Starting timer...");


            cdt = new CountDownTimer(10000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {

                    Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
                    bi.putExtra("countdown", millisUntilFinished);
                    bi.putExtra("timer_status", "timer_not_finished");
                    sendBroadcast(bi);
                }

                @Override
                public void onFinish() {
                    Log.i(TAG, "Timer finished");

                    bi.putExtra("timer_status", "timer_finished");


                    sendBroadcast(bi);

                }
            };

            cdt.start();
        }

        @Override
        public void onDestroy() {

            cdt.cancel();
            Log.i(TAG, "Timer cancelled");
            super.onDestroy();
        }

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

        @Override
        public IBinder onBind(Intent arg0) {       
            return null;
        }
}

.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "start of oncreate");

        setContentView(R.layout.loneworker);

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setIcon(R.drawable.ic_launcher);
        setTitle("Lone Worker");
        nfcscannerapplication = (NfcScannerApplication) getApplication();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        tvCountDown = (TextView)findViewById(R.id.tvloneworkercountdown);
        callFinished = (Button)findViewById(R.id.buttonlwcallfinished);


        callFinished.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Log.e(TAG, "inside callFinished");
                //maybe alert carer is safe***************************************

                setCountDownFinished();

            }
        });




        startService(new Intent(this, CountDownBroadcastService.class));
        Log.i(TAG, "Started service");






    }//end of onCreate



    private BroadcastReceiver br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {            
            updateGUI(intent); // or whatever method used to update your GUI fields
        }
    };


    public void onResume() {
        super.onResume();        
        registerReceiver(br, new IntentFilter(CountDownBroadcastService.COUNTDOWN_BR));
        Log.i(TAG, "Registered broacast receiver");
        }



    private void updateGUI(Intent intent) {
        if (intent.getExtras() != null) {
            long millisUntilFinished = intent.getLongExtra("countdown", 0);
            //Log.i(TAG, "Countdown seconds remaining: " +  millisUntilFinished / 1000);    

            String status = intent.getStringExtra("timer_status");

            if(status.equalsIgnoreCase("timer_not_finished")){

                    tvCountDown.setText("Countdown seconds remaining: " +  millisUntilFinished / 1000);

            }else if(status.equalsIgnoreCase("timer_finished")){

                setCountDownFinished();
            }
        }
    }//end of updateGUI


    public void setCountDownFinished(){

        tvCountDown.setText("0");
        unregisterReceiver(br);
        Log.i(TAG, "Unregistered broacast receiver");

        stopService(new Intent(this, CountDownBroadcastService.class));
        Log.e(TAG, "Stopped CountDownBroadcastService");

    }// end of setCountDownFinished()




}
4

1 に答える 1

1

プログラムでブロードキャスト レシーバーをアクティビティに登録すると、アクティビティが一時停止するとブロードキャストが受信されません。BroadcastReceiver のドキュメントは、この点に関して明確ではありません。システムのオーバーヘッドを削減するためだけに、onPause での登録解除を推奨しています。アクティビティがフォアグラウンドにない場合でもイベントを受け取りたい場合は、receiver 要素を使用してマニフェストにレシーバーを登録します。

于 2016-02-16T15:02:46.947 に答える