0

我有一个具有 CountdownTimer 的后台服务。随着 CountdownTimer 倒计时,我向 Activity 发送广播。当 CountdownTimer 倒计时时,Activity 会收到警报,我可以停止服务并取消注册接收器。

我已将正常的接收器注销方法从 onStop 和 onPause 移到我自己的方法中,一旦收到带有“timer_finished”的广播,我就会调用该方法。这样我就可以在不注销的情况下离开 Activity。

如果用户当前正在查看 Activity,则一切正常。如果用户离开 Activity,则 CoundownTimer 仍在运行,但 Activity 没有接收到广播。

我该如何做到这一点,以便 Activity 接收最终广播“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 上取消注册以减少系统开销。如果您想在活动不在前台时接收事件,请使用接收器元素在清单中注册接收器。

于 2016-02-16T15:02:46.947 回答