-->

create service with CountDownTimer in android

2019-01-15 18:22发布

问题:

I am starter in android. I want to create a Service.java from this Activity.class.

In my MainActivity I have 2 buttons(aBTN and bBTN). with clicking on each of them Adult1Activity with timer starts. this timer controls with PlayBTN and StopBTN. Also, I want to show timer in notification. I want to use 2 other buttons "RestoreBTN" and "CloseBTN" for connecting between activity and notification. I use CountDownTimer class for timer. but I don't know how I write

  1. Textview
  2. RestoreBTN

Note: "aBTN" and "bBTN" have different times. "aBTN" is 10 minutes and "bBTN" is 5 min.

This code is the first one.

public class Adult1Activity extends AppCompatActivity implements View.OnClickListener{
private Button playBTN,stopBTN ;    // contoroll buttons
private Button OnStop;
private TextView tv ;
private Toolbar toolbar;
private CountDownTimer countDownTimer;
private int total;
private long timeBlinkInMilliseconds ; // start time of start blinking
private boolean blink; // controls the blinking .. on and off

public CustomDialogClass cdd; // back dialog

private boolean isRunning = false;
public String timeString;
public NotificationManager notificationManager;
public NotificationCompat.Builder notificationBuilder;
public final int notification_id=01;
private static final String EXTRA_NOTE = "NOTE";
private static final String NOTE_RESTORE = "restore";
private static final String NOTE_CLOSE = "close";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_adult1);

    //define toolbar
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);



    playBTN = (Button) findViewById(R.id.play);
    stopBTN = (Button) findViewById(R.id.stop);
    tv = (TextView) findViewById(R.id.TimeCount);

    playBTN.setOnClickListener(this);
    stopBTN.setOnClickListener(this);

    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    handleIntent(getIntent());
}

@Override
public void onClick(View v) {
    switch(v.getId())
    {    case  R.id.play:
        tv.setTextAppearance(getApplicationContext(),
                R.style.normalText);
        setTimer();
        stopBTN.setVisibility(View.VISIBLE);
        playBTN.setVisibility(View.GONE);
        startTimer(total);
        break;

        case R.id.stop :
            countDownTimer.cancel();
            Intent reloadIntent = new Intent(Adult1Activity.this, Adult1Activity.class);
            startActivity(reloadIntent); // refresh activity
            finish();
            isRunning = false;
            notificationManager.cancel(notification_id);
            break;
    }
}
//------------------------------------------------
private void setTimer() {
    int time=30;
    total = time*60 * 1000;  // 30*60 aeconds
    timeBlinkInMilliseconds = 10 * 1000;
}


private void startTimer(long enter) {
    countDownTimer = new CountDownTimer(enter, 500) {
        // 500 means, onTick function will be called at every 500
        // milliseconds

        @Override
        public void onTick(long leftTimeInMilliseconds) {
            final long seconds = leftTimeInMilliseconds / 1000;
            long save = leftTimeInMilliseconds / 1000;

            if (leftTimeInMilliseconds < timeBlinkInMilliseconds) {
                tv.setTextAppearance(getApplicationContext(),
                        R.style.blinkText);
                // change the style of the textview .. giving a red
                // alert style

                if (blink) {
                    tv.setVisibility(View.VISIBLE);
                    // if blink is true, textview will be visible
                } else {
                    tv.setVisibility(View.INVISIBLE);
                }

                blink = !blink; // toggle the value of blink
            }

            // format the textview to show the easily readable format
            timeString = String.format("%02d", seconds / 60)
                    + ":" + String.format("%02d", seconds % 60);
            tv.setText(timeString);
            ExtendedNotification(timeString);
        }

        @Override
        public void onFinish() {
            Adult1Activity.this.finish();
            vibrate(1000);
            notificationManager.cancel(notification_id);

            // turn on screen
            PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
            wakeLock.acquire();

            // *********** notification
            PendingIntent i = PendingIntent.getActivity(getBaseContext(), 0,
                    new Intent(getBaseContext(), Sport2Activity.class),0);

            finish();
        }
    }.start();
}
//----------------------------------------------------------
public void onFinish() {
    moveTaskToBack(true);
}
//-------------vibrate---------------------------------------------
public void vibrate(int duration) {
    Vibrator vibs = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vibs.vibrate(duration);
}

//****************************************************
//alert dialog for back btn
public void onBackPressed () {
     cdd = new CustomDialogClass(Adult1Activity.this);
    cdd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    cdd.show();
}


public class CustomDialogClass extends Dialog {
    public Activity c;
    public Button minimizeBTN, exitBTN;

    public CustomDialogClass(Activity a) {
        super(a);
        this.c = a;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.back_btn);
        minimizeBTN = (Button) findViewById(R.id.minimizing_app);
        exitBTN = (Button) findViewById(R.id.exit_completely);

        minimizeBTN.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MinimizeApp();
                isRunning = true;
                ExtendedNotification(timeString);
                cdd.dismiss();
              //  notificationManager.notify(notification_id,notificationBuilder.build());

            }
        });


        exitBTN.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                CloseApp();
            }
        });

    }


}

//*****************Notification class******
    private void ExtendedNotification(String time) {
        final Intent resultIntentRestore = new Intent(this, Adult1Activity.class);
        resultIntentRestore.putExtra(EXTRA_NOTE,NOTE_RESTORE);
        resultIntentRestore.putExtra(time,NOTE_RESTORE);
        PendingIntent restoreIntent = PendingIntent.getActivity(Adult1Activity.this,
                0, resultIntentRestore, PendingIntent.FLAG_UPDATE_CURRENT);

        final Intent resultIntentClose = new Intent(this, Adult1Activity.class);
        resultIntentClose.putExtra(EXTRA_NOTE, NOTE_CLOSE);
        PendingIntent closeIntent = PendingIntent.getActivity(Adult1Activity.this,
                1, resultIntentClose, PendingIntent.FLAG_UPDATE_CURRENT);

          notificationBuilder = new NotificationCompat.Builder(Adult1Activity.this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Stand Up!")
                .setContentText(time)
                .setAutoCancel(true)
                .addAction(new NotificationCompat.Action(R.drawable.ic_note_restore, "Restore", restoreIntent))
                .addAction(new NotificationCompat.Action(R.drawable.ic_note_close, "Close", closeIntent))
                .setContentIntent(restoreIntent);


        //final Notification notification = notificationBuilder.build();
        //notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
        notificationManager.notify(notification_id,notificationBuilder.build());

    }
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent); // Make sure to call super
    handleIntent(intent);
}

private void handleIntent(Intent intent) {
    final String a = intent.getStringExtra(EXTRA_NOTE);
    if (a != null) {
        switch (a) {
            case NOTE_RESTORE:
                tv.setText(timeString);
               // tv.setText(intent.getStringExtra(timeString));
                notificationManager.cancel(notification_id);
                break;

            case NOTE_CLOSE:
                countDownTimer.cancel();
                isRunning = false;
                notificationManager.cancel(notification_id);
               // Adult1Activity.this.finish();
                break;
        }
    }
}
//**********************App statuse********************
public void MinimizeApp(){
    moveTaskToBack(true); //hide

}

private void CloseApp(){
    android.os.Process.killProcess(android.os.Process.myPid());// exit
    notificationManager.cancel(notification_id);
}

}

this is my ForgroundService that I has written till now.

public class TimerService extends Service {
public CountingDownTimer countingDownTimer;
public static String total_time_string;
public static int totalSeconds;


public NotificationManager notificationManager;
public NotificationCompat.Builder notificationBuilder;
public final int notification_id=01;
private static final String EXTRA_NOTE = "NOTE";
private static final String NOTE_RESTORE = "restore";
private static final String NOTE_CLOSE = "close";

@Override
public void onCreate() {

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    countingDownTimer = new CountingDownTimer(totalSeconds,500); //milliseconds , (500 means) onTick function will be called at every 500
    //countingDownTimer = new CountingDownTimer(intent.getExtras().getInt(total_time_string),500); //milliseconds , (500 means) onTick function will be called at every 500
    countingDownTimer.start();

    notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    setupNotification();

    return super.onStartCommand(intent, flags, startId);
}

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

@Override
public void onDestroy() {
    super.onDestroy();
    countingDownTimer.cancel();
    notificationManager.cancel(notification_id);
}

//******************************************************************
public class CountingDownTimer extends CountDownTimer{
    final String timeString;

    /**
     * @param millisInFuture    The number of millis in the future from the call
     *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
     *                          is called.
     * @param countDownInterval The interval along the way to receive
     *                          {@link #onTick(long)} callbacks.
     */
    public CountingDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        timeString = null;
    }

    @Override
    public void onTick(long leftTimeInMilliseconds) {
        // format the textview to show the easily readable format
        final long seconds = leftTimeInMilliseconds / 1000;
        timeString = String.format("%02d", seconds / 60)
                + ":" + String.format("%02d", seconds % 60);

        Adult1Activity.tv.setText(timeString);
     //   ExtendedNotification(timeString);

    }

    @Override
    public void onFinish() {
        startActivity(new Intent(this,Sport2Activity.class));

        vibrate(1000);

        // turn on screen
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
        wakeLock.acquire();
    }
}

public void vibrate(int duration) {
    Vibrator vibs = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vibs.vibrate(duration);
}

//****************Notification ********************
    private void setupNotification() {
        Intent notificationIntent_Restore = new Intent(this,Adult1Activity.class);
        notificationIntent_Restore.putExtra(EXTRA_NOTE,NOTE_RESTORE);
        notificationIntent_Restore.putExtra(countingDownTimer.timeString,NOTE_RESTORE);
        PendingIntent restoreIntent = PendingIntent.getActivity(this,
                0, notificationIntent_Restore, PendingIntent.FLAG_UPDATE_CURRENT);

        final Intent notificationIntent_Close = new Intent(this, Adult1Activity.class);
        notificationIntent_Close.putExtra(EXTRA_NOTE, NOTE_CLOSE);
        PendingIntent closeIntent = PendingIntent.getActivity(this,
                1, notificationIntent_Close, PendingIntent.FLAG_UPDATE_CURRENT);

        notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Stand Up!")
                .setContentText(countingDownTimer.timeString)
                .setAutoCancel(true)
                .addAction(new NotificationCompat.Action(R.drawable.ic_note_restore, "Restore", restoreIntent))
                .addAction(new NotificationCompat.Action(R.drawable.ic_note_close, "Close", closeIntent))
                .setContentIntent(restoreIntent);

         startForeground(notification_id,notificationBuilder);
        //final Notification notification = notificationBuilder.build();
        //notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
       // notificationManager.notify(notification_id,notificationBuilder.build());

    }

回答1:

    private class OTPCountdown extends CountDownTimer {

            /**
             * @param millisInFuture    The number of millis in the future from the call
             *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
             *                          is called.
             * @param countDownInterval The interval along the way to receive
             *                          {@link #onTick(long)} callbacks.
             */
            public OTPCountdown(long millisInFuture, long countDownInterval) {
                super(millisInFuture, countDownInterval);
            }

            @Override
            public void onTick(long millisUntilFinished) {
                tvOTPCountdown.setText(getString(R.string.otp_expiration_msg, millisUntilFinished / 1000));
            }

            @Override
            public void onFinish() {
                showManualWrap();
            }
        }



// use like this 
 otpCountdown = new OTPCountdown(60000, 1000);
        otpCountdown.start();


回答2:

Just because you are starter in Android and someone didnt get time to answer your question doesn't mean you would downvote their accepted answer and boss over them. If you are not able to figure out whats going on with your code. Give time to other developers to see it again. Moderator please look at this thread: How to set Service/StartForeground to work CountDownTimer properly