I want to run the service when the countdown time has finished, but when I exit the application the command does not work, what's the solution?
time.java
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
startService(new Intent(getBaseContext(), alert1.class));
}
}.start();
mTimerRunning = true;
updateWatchInterface();
}
this is the service class
alert1.java
public class alert1 extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("RELAY1_STATUS");
myRef.setValue("OFF");
Toast.makeText(getBaseContext(),"off",Toast.LENGTH_LONG).show();
}
}, 0);
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
You can try like this. First, send your counter time as a parameter. When time finished just start your service.
private void setTimerForStartService(int timeInMillis){
countDownTimer = new CountDownTimer(timeInMillis, 1000){
#Override
public void onTick(long millisUntilFinished) {
String text = String.format(Locale.getDefault(), "%02d",
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
updateCountDownText(text);
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
startService(new Intent(getBaseContext(), alert1.class));
}
}.start();
}
Related
Hi I am making sport countdown timer and I have pause button. To pause timer I am using :(code bellow)
but I don't know hot to resume it. And I don't want to put my countdown timer function in public void method.
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
mButtonStartPause.setText("Start");
mButtonStartPause.setVisibility(View.INVISIBLE);
mButtonReset.setVisibility(View.VISIBLE);
}
}.start();
updateCountDownText();
}
private void startTimer() {
mTimerRunning = true;
mButtonStartPause.setText("pause");
mButtonReset.setVisibility(View.INVISIBLE);
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
mButtonStartPause.setText("Start");
mButtonReset.setVisibility(View.VISIBLE);
}
private void resetTimer() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setVisibility(View.VISIBLE);
}
}
I checked your restart function. And I think solution to restart is to cancel it and start it again. Try this out:
private void resetTimer() {
mCountDownTimer.cancel();
mCountDownTimer.start();
}
I am trying to use a countdown timer which will run when the activity onPause is triggered. However, the service stops after 1 minute. But if I start the service with the activity working it works.
public class TimerService extends Service {
private static CountDownTimer countDownTimer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer(2*60 * 1000);
return START_STICKY;
}
#Override
public void onDestroy() {
countDownTimer.cancel();
super.onDestroy();
}
private void startTimer(int noOfMinutes) {
countDownTimer=new CountDownTimer(noOfMinutes, 1000) {
public void onTick(long millisUntilFinished) {
long millis=millisUntilFinished;
String hms=String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
Log.d("Long Seconds", hms);
}
public void onFinish() {
//timerOn=false;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(getApplicationContext(), Splash_Loader.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}, 1000);
}
}.start();
}
}
Starting it onPause from an activity
#Override
protected void onPause() {
super.onPause();
startService(new Intent(this,TimerService.class));
}
Manifest file decleration
<service android:name = ".TimerService"/>
This piece of code runs perfectly if i write it in a activity but it dosent run in a fragment.And I want it to run it in background after app is killed.
This is my countdowntimer
public void bonus(){
mEndTime = System.currentTimeMillis() + timeleftinmillis;
Log.i("timeadd", String.valueOf(mEndTime));
countDownTimer=new CountDownTimer(timeleftinmillis,1000){
#Override
public void onTick(long l) {
timeleftinmillis=l;
updateTimer();
}
#Override
public void onFinish() {
mrunning=false;
updateButtons();
}
}.start();
mrunning=true;
bonusmoney.setText( String.valueOf(clickcount));
updateButtons();
}
Here is where i am converting time in minutes and seconds
public void updateTimer (){
long min = (timeleftinmillis/1000) / 60;
long sec = (timeleftinmillis/1000) % 60;
String timeformat = String.format(Locale.getDefault(),"%02d:%02d",min,sec);
timerbonusview.setText(timeformat);
}
This is my OnStart() method
#Override
public void onStart() {
super.onStart();
SharedPreferences prefs = getContext().getSharedPreferences("prefs", MODE_PRIVATE);
timeleftinmillis = prefs.getLong("millisLeft", timeinmillis);
mrunning = prefs.getBoolean("timerRunning", false);
updateTimer();
updateButtons();
if (mrunning) {
mEndTime = prefs.getLong("endTime", 0);
Log.i("endtime", String.valueOf(mEndTime));
timeleftinmillis = mEndTime - System.currentTimeMillis();
Log.i("timeleft", String.valueOf(timeleftinmillis));
if (timeleftinmillis < 0) {
timeleftinmillis = 0;
mrunning = false;
Log.i("timebonus", "less than zero");
updateTimer();
updateButtons();
} else {
bonus();
}
}
}
This is my onStop() method
#Override
public void onStop() {
super.onStop();
SharedPreferences prefs = getContext().getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("millisLeft", timeleftinmillis);
editor.putBoolean("timerRunning", mrunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
updating buttons here
private void updateButtons() {
if (mrunning) {
dailyearningsbtn.setVisibility(View.INVISIBLE);
}else {
dailyearningsbtn.setVisibility(View.VISIBLE);
}
}
For running tasks after app is killed consider using background services in android
I am Trying to Implement a service where when I a select a time, the timer starts and runs in the background. the thing is working fine. but when I select another time, the timer overlaps on one another. I want my app to work in such a way that different services should run for different time. also, when I kill the app and reopen it, I get the remaining time in all the services.
however my data is coming from a web service and this web service contains a field with time. when I click the time, the above concept should start.
I have implemented my code as,
BroadCastService.java
public class BroadCastService extends Service {
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
public static final String COUNTDOWN_BR = "project.uop.assignment8";
Intent bi = new Intent(COUNTDOWN_BR);
public BroadCastService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
getTime = intent.getStringExtra("time");
setTimer();
startTimer();
Log.i("madhura","madhura");
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
private void setTimer() {
int time = 0;
//if (getTime.equals("")) {
time = Integer.parseInt(getTime);
// } else
/* Toast.makeText(BroadCastService.this, "Please Enter Minutes...",
Toast.LENGTH_LONG).show();*/
totalTimeCountInMilliseconds = 60 * time * 1000;
timeBlinkInMilliseconds = 30 * 1000;
}
private void startTimer() {
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
if (leftTimeInMilliseconds < timeBlinkInMilliseconds) {
if (blink) {
// mTextField.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
// mTextField.setVisibility(View.INVISIBLE);
}
blink = !blink;
}
String a = String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60);
bi.putExtra("countdown", a);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Toast.makeText(BroadCastService.this, "Finished", Toast.LENGTH_SHORT).show();
}
}.start();
}
}
and my TimerActivity.class
public class TimerActivity extends AppCompatActivity {
TextView mTextField;
TextView hotel;
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
SessionManager sessionManager;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
InitializeToolbar();
Intent in = getIntent();
getTime = in.getStringExtra("time");
Intent intent = new Intent(this,BroadCastService.class);
intent.putExtra("time",getTime);
this.startService(intent);
sessionManager = new SessionManager(this);
hotel = findViewById(R.id.textView);
hotel.setText(sessionManager.getUserName());
Log.i("started", "Started service");
mTextField = findViewById(R.id.timer);
}
public void InitializeToolbar(){
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle("Order Notification");
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(BroadCastService.COUNTDOWN_BR));
Log.i("efgh", "Registered broacast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(br);
Log.i("abcd", "Unregistered broadcast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(br);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
#Override
public void onDestroy() {
stopService(new Intent(this, BroadCastService.class));
Log.i("Stopped", "Stopped service");
super.onDestroy();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
String millisUntilFinished = intent.getStringExtra("countdown");
mTextField.setText(millisUntilFinished);
}
}
}
thanks in advance.
Use Handler and #Overide its method Handler#handleMessage(Message msg)
See this: https://gist.github.com/mjohnsullivan/403149218ecb480e7759
I have a simple Service
public class UpdateService extends Service {
private int seconds;
final static String MY_ACTION = "MY_ACTION";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
timer.start();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
final CountDownTimer timer = new CountDownTimer(86400000, 1000) {
public void onTick(long millisUntilFinished) {
Util.saveInfo(getApplicationContext(), Util.SECONDS, seconds++);
Intent intent = new Intent();
intent.setAction(MY_ACTION);
sendBroadcast(intent);
}
public void onFinish() { }
};
}
When I close an application service stops working. But showing that the service is running.
What am I doing wrong?
Update
I changed CountDownTimer to Thread, but the problem remained
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
Util.saveInfo(getApplicationContext(), Util.SECONDS, seconds++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
OnStart()
if(!t1.isAlive())
t1.start();
Because CountDown Timer is working only foreground means app is running and not minimized or closed. You have to place a Thread in Service that executing at particular time of you want.
try this :
public class LocalService extends Service
{
private static Timer timer = new Timer();
private Context ctx;
public IBinder onBind(Intent arg0)
{
return null;
}
public void onCreate()
{
super.onCreate();
ctx = this;
startService();
}
private void startService()
{
timer.scheduleAtFixedRate(new mainTask(), 0, 5000);
}
private class mainTask extends TimerTask
{
public void run()
{
toastHandler.sendEmptyMessage(0);
}
}
public void onDestroy()
{
super.onDestroy();
Toast.makeText(this, "Service Stopped ...", Toast.LENGTH_SHORT).show();
}
private final Handler toastHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
System.out.println("test");
}
};
}