In my app I am using a CountdownTimer. After each time the countdown timer has been executed I´m using a counter. When the counter meet a certain requirement I want the countdown timer to behave in another way onFinish and change the textview of my textTimer. Like it acts now my counter has already looped before starting the countdowntimer. How can I change that?
package org.example.anders.eazy;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.os.CountDownTimer;
import android.widget.TextView;
import android.os.Vibrator;
import java.util.concurrent.TimeUnit;
public class ExerciseActivity extends Activity {
String[] exerciseList;
TextView textTimer,workoutTextview,exerciseTextView;
int setsChosen;
int counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exerciseList = getResources().getStringArray(R.array.heavy_chest_arms);
Intent intent = getIntent();
setsChosen =intent.getExtras().getInt("setsChosen");
String selectedWorkout = intent.getExtras().getString("workoutName");
int timeChosen = intent.getExtras().getInt("timeChosen");
setContentView(R.layout.activity_exercise);
for(counter=0;counter<setsChosen;counter++) {
final CounterClass timer = new CounterClass(timeChosen * 60000, 1000);
timer.start();
textTimer = (TextView) findViewById(R.id.timeUntilFinished);
workoutTextview = (TextView) findViewById(R.id.workoutChosen);
//exerciseTextView= (TextView) findViewById(R.id.exerciseNow);
//textTimer.setText("00:01:00");
//exerciseTextView.setText(exerciseList[i]);
workoutTextview.setText(selectedWorkout);
}
}
public class CounterClass 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 CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
long millis= millisUntilFinished;
String hms=String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textTimer.setText(hms);
}
#Override
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
if(counter<setsChosen){
this.start();
}
else
textTimer.setText("Complete");
}
}
}
You can remove your loop and update counter at onFinish()
So, your code should be like this.
package org.example.anders.eazy;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.os.CountDownTimer;
import android.widget.TextView;
import android.os.Vibrator;
import java.util.concurrent.TimeUnit;
public class ExerciseActivity extends Activity {
String[] exerciseList;
TextView textTimer,workoutTextview,exerciseTextView;
int setsChosen;
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exerciseList = getResources().getStringArray(R.array.heavy_chest_arms);
Intent intent = getIntent();
setsChosen =intent.getExtras().getInt("setsChosen");
String selectedWorkout = intent.getExtras().getString("workoutName");
int timeChosen = intent.getExtras().getInt("timeChosen");
setContentView(R.layout.activity_exercise);
if (counter < setsChosen) {
final CounterClass timer = new CounterClass(timeChosen * 60000, 1000);
timer.start();
textTimer = (TextView) findViewById(R.id.timeUntilFinished);
workoutTextview = (TextView) findViewById(R.id.workoutChosen);
//exerciseTextView= (TextView) findViewById(R.id.exerciseNow);
//textTimer.setText("00:01:00");
//exerciseTextView.setText(exerciseList[i]);
workoutTextview.setText(selectedWorkout);
}
}
public class CounterClass 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 CounterClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
long millis= millisUntilFinished;
String hms=String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textTimer.setText(hms);
}
#Override
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
counter ++;
if(counter<setsChosen){
this.start();
}
else
textTimer.setText("Complete");
}
}
}
And for simply (doesn't need to create CountDownTimer's subclass). You can create a function runCountDownTimer() for looping like this.
package org.example.anders.eazy;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.os.CountDownTimer;
import android.widget.TextView;
import android.os.Vibrator;
import java.util.concurrent.TimeUnit;
public class ExerciseActivity extends Activity {
String[] exerciseList;
TextView textTimer,workoutTextview,exerciseTextView;
int setsChosen;
int counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exerciseList = getResources().getStringArray(R.array.heavy_chest_arms);
Intent intent = getIntent();
setsChosen =intent.getExtras().getInt("setsChosen");
String selectedWorkout = intent.getExtras().getString("workoutName");
int timeChosen = intent.getExtras().getInt("timeChosen");
setContentView(R.layout.activity_exercise);
textTimer = (TextView) findViewById(R.id.timeUntilFinished);
workoutTextview = (TextView) findViewById(R.id.workoutChosen);
//exerciseTextView= (TextView) findViewById(R.id.exerciseNow);
//textTimer.setText("00:01:00");
//exerciseTextView.setText(exerciseList[i]);
workoutTextview.setText(selectedWorkout);
counter = 0;
runCountDownTimer();
}
public void runCountDownTimer() {
if (counter < setsChosen) {
new CountDownTimer(timeChosen * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hms = String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textTimer.setText(hms);
}
#Override
public void onFinish() {
counter++;
runCountDownTimer();
}
}.start();
}
}
}
Related
My app is a timed math game. Answer as many questions as you can before the timer runs out. When the time runs out, The GameOverActivity is now the current activity. I've realized that if I give no answer, the app will crash. If I give at least 1 answer, the app doesn't crash and everything is normal. I'm not sure where the flaw in my code exista.
This is the Main Activity
package stormy.incremental.randomtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class FastMathActivity extends AppCompatActivity {
int rand1, rand2, randDecider, correctAnswer, falseAnswer, problemsSolved;
String response,sumStr;
MyCountDownTimer myCountDownTimer;
int score;
Random r;
TextView randTV1, randTV2, scoreTV, sumTV, problemsSolvedTV, timerTV;
Button choice1, choice2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_test);
problemsSolved =0;
falseAnswer = 1;
//Initializing TextViews
timerTV = ((TextView) findViewById(R.id.timer));
randTV1 = ((TextView) findViewById(R.id.rand1));
randTV2 = ((TextView) findViewById(R.id.rand2));
sumTV = ((TextView) findViewById(R.id.sum));
scoreTV = ((TextView) findViewById(R.id.score));
problemsSolvedTV = ((TextView) findViewById(R.id.problemsSolved));
choice1 = ((Button) findViewById(R.id.choice1));
choice2 = ((Button) findViewById(R.id.choice2));
//Initializing a Random
r = new Random();
//Set the first question
setRandomProblem();
//Starting the timer
myCountDownTimer = new MyCountDownTimer(timerTV, 5000, 1000);
myCountDownTimer.start();
// Button Listeners
choice1.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
checkResponse((Button)v);
setRandomProblem();
}
});
choice2.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
checkResponse((Button)v);
setRandomProblem();
}
});
}
public void checkResponse(Button v) {
//Convert the response and correctAnswer to String in order to compare values
response = v.getText().toString();
sumStr = Integer.toString(correctAnswer);
//If the user clicks the correct answer, increment score
if ((response.equals(sumStr))) {
score++;
scoreTV.setText(score+"");
}
//Increment the total amount of problems solved
problemsSolved++;
problemsSolvedTV.setText(problemsSolved+"");
//Keep track of the score within the timer
myCountDownTimer.recordScore(score,problemsSolved);
}
private void setRandomProblem() {
//Assigning random values to ints
rand1 = r.nextInt(5 - 1) + 1;
rand2 = r.nextInt(5 - 1) + 1;
randDecider = r.nextInt(2) + 1;
//The correctAnswer of the randoms
correctAnswer = rand1 + rand2;
//Setting the texts of the random values
randTV1.setText(rand1 + "");
randTV2.setText(rand2 + "");
//If the random deciding number is 1, set answer on choice1
if (randDecider == 1) {
choice1.setText(correctAnswer + "");
choice2.setText(correctAnswer + falseAnswer + "");
}
//If the random deciding number is 2, set answer on choice2
else {
choice1.setText(correctAnswer + falseAnswer + "");
choice2.setText(correctAnswer + "");
}
}
#Override
public void onStop(){
super.onStop();
//Stop the timer
myCountDownTimer.cancel();
}
}
This is the GameOverActivity
package stormy.incremental.randomtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
/**
* Created by kamalu on 12/25/2017.
*/
public class GameOverActivity extends AppCompatActivity {
TextView scoreTV, problemsSolvedTV, percentageTV;
int score, problemsSolved, percentage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover);
//Initializing TextViews
scoreTV = ((TextView)findViewById(R.id.score));
problemsSolvedTV = ((TextView)findViewById(R.id.problemsSolved));
percentageTV = ((TextView)findViewById(R.id.percentage));
//Opening Bundle and assigning values
Bundle extras = getIntent().getExtras();
score = extras.getInt("score");
problemsSolved = extras.getInt("problemsSolved");
//calculating the accuracy
percentage = (score/problemsSolved)*100;
//Displaying the score
percentageTV.setText(percentage+"");
scoreTV.setText(score+"");
problemsSolvedTV.setText(problemsSolved+"");
}
//Start the game over
public void retry(View v){
Intent retryIntent = new Intent(GameOverActivity.this, FastMathActivity.class);
startActivity(retryIntent);
}
public void onBackPressed()
{
}
}
This is the Timer. I believe it to be important to note that the onFinish() method in this class starts the GameOverActivity.
package stormy.incremental.randomtest;
import android.content.Intent;
import android.os.CountDownTimer;
import android.widget.TextView;
public class MyCountDownTimer extends CountDownTimer {
TextView textCounter;
int score,problemsSolved;
public MyCountDownTimer(TextView textCounter, long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
this.textCounter = textCounter;
}
#Override
public void onTick (long millisUntilFinished){
textCounter.setText(String.valueOf(millisUntilFinished / 1000));
}
#Override
public void onFinish () {
Intent gameOverIntent = new Intent(textCounter.getContext(), GameOverActivity.class);
gameOverIntent.putExtra("score", score);
gameOverIntent.putExtra("problemsSolved", problemsSolved);
textCounter.getContext().startActivity(gameOverIntent);
}
//Keep track of the scores
public void recordScore(int score,int problemsSolved){
this.problemsSolved = problemsSolved;
this.score = score;
}
}
You should check:
//calculating the accuracy
percentage = (score/problemsSolved)*100;
if problemsSolved = 0, your app will crash with exeptions: java.lang.ArithmeticException
You can refer:
if (problemSolved != 0){
//calculating the accuracy
percentage = (score/problemsSolved)*100;
} else {
// handle with problemSolved = 0;
}
I hope it can help your problem!
I want to make an android application that have punch in and punch out functionality. Scenario is when the user entered in an application it enters its task and press punch in button, When punch in button is press current date and time is saved in a local database and timer is running on background even i close an application but issue is it cannot run in background when i close an application and starts again timer starts from beginning.
How to figure out that my service is running and get that data?
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button pauseButton;
private TextView timerValue;
Intent intent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
updateUI(intent);
}
};
private void updateUI(Intent intent) {
int time = intent.getIntExtra("time", 0);
Log.d("Hello", "Time " + time);
int mins = time / 60;
int secs = time % 60;
timerValue.setText("" + mins + ":" + String.format("%02d", secs));
}
#Override
protected void onStop() {
super.onStop();
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
}
MyService.java
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service
{
private Intent intent;
public static final String BROADCAST_ACTION = "com.example.wajid.service";
private Handler handler = new Handler();
private long initial_time;
long timeInMilliseconds = 0L;
#Override
public void onCreate() {
super.onCreate();
initial_time = SystemClock.uptimeMillis();
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 1000); // 1 seconds
}
};
private void DisplayLoggingInfo() {
timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;
int timer = (int) timeInMilliseconds / 1000;
intent.putExtra("time", timer);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Why do you want to run a timer? Instead, simply save the check-in time in shared preferences. On check-out, the two can be compared and the relevant time calculated.
If you are worried that the user might try to manipulate the local device clock, then instead of getting the local time, you can use network time.
I have a problem with a button to be invisible when I want. In my if statement I have declared the exerciseButtonDone to first to be invisible but then after the final countdown I want it to become visible.
As my code is right now the button is visible all the time.
package org.example.anders.eazy;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.os.Vibrator;
import java.util.concurrent.TimeUnit;
public class ExerciseActivity extends Activity {
String[] exerciseList;
TextView textTimer,workoutTextview,exerciseTextView;
int setsChosen;
int counter = 0;
int timeChosen;
boolean togglebuttonpress;
Button exerciseButtonDone;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exerciseList = getResources().getStringArray(R.array.heavy_chest_arms);
setContentView(R.layout.activity_exercise);
exerciseButtonDone=(Button)findViewById(R.id.buttonActiveExcercise);
Intent intent = getIntent();
String selectedWorkout = intent.getExtras().getString("workoutName");
togglebuttonpress=intent.getExtras().getBoolean("togglebuttonPress");
textTimer = (TextView) findViewById(R.id.timeUntilFinished);
//workoutTextview = (TextView) findViewById(R.id.workoutChosen);
//workoutTextview.setText(selectedWorkout);
if(togglebuttonpress){
exerciseButtonDone.setVisibility(View.INVISIBLE);
setsChosen =intent.getExtras().getInt("setsChosen");
int timePass = intent.getExtras().getInt("timeChosen");
timeChosen=timePass;
counter = 0;
runCountDownTimer();
exerciseButtonDone.setVisibility(View.VISIBLE);
}
else {
textTimer.setText("");
exerciseButtonDone.setVisibility(View.VISIBLE);
}
//exerciseTextView= (TextView) findViewById(R.id.exerciseNow);
//exerciseTextView.setText(exerciseList[i]);
}
public void runCountDownTimer() {
if (counter < setsChosen) {
new CountDownTimer(timeChosen * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hms = String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textTimer.setText(hms);
}
#Override
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
counter++;
v.vibrate(500);
runCountDownTimer();
}
}.start();
}
textTimer.setText("Complete");
}
}
You are setting the button invisible and then immediately visible.
if(togglebuttonpress){
exerciseButtonDone.setVisibility(View.INVISIBLE);
...
exerciseButtonDone.setVisibility(View.VISIBLE);
}
move exerciseButtonDone.setVisibility(View.VISIBLE); from its current location to where the countdown timer actually finishes, which I now see is runCountDownTimer()
if (counter < setsChosen) {
new CountDownTimer(timeChosen * 60000, 1000) {
...
}
} else {
exerciseButtonDone.setVisibility(View.VISIBLE);
}
you'll still need to make execerciseButtonDone final... and move it to the right scope, thank you alex. It needs to be a class variable, over by say boolean togglebuttonpress;
you COULD do findViewById again, but that's redundant and unnecessary.
I added an if statement that checked if loop was done. It worked.
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
counter++;
v.vibrate(500);
runCountDownTimer();
if (counter == setsChosen)
{
exerciseButtonDone.setVisibility(View.VISIBLE);
}
}
I am writing a code in Android code to create dynamic service or run-time service in Android app. I want to create one service and it will run two dynamic service internally , with the unique id. But i am not able to figure out how to do it? Please go though my sample code :
MyCode:
MainActivity.java
package com.example.multipleservice;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.TextView;
public class MainActivity extends Activity
{
TextView timer1;
TextView timer2;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer1 = (TextView) findViewById(R.id.timer1);
timer2 = (TextView) findViewById(R.id.timer2);
Calendar calendar1 = Calendar.getInstance();
Intent myIntent1 = new Intent(MainActivity.this, MyService.class);
myIntent1.putExtra("Id", "1");
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent1,0);
AlarmManager alarmManager1 = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager1.set(AlarmManager.RTC, calendar1.getTimeInMillis(), pendingIntent1);
long tm1 = 0;
String ticket1 = "1";
SharedPreferences timer_saved1 = getApplicationContext().getSharedPreferences("TimerSave"+ticket1, 0);
long timerData1 = timer_saved1.getLong("timer"+ticket1, 0);
long timerValue1 = 0;
long diff_value1 = 36680;
if(timerData1!=0)
{
timerValue1 = timerData1*1000;
}
else
{
timerValue1 = diff_value1*1000;
}
tm1 = timerValue1;
RemainTime1 timera = new RemainTime1(tm1,1000);
timera.start();
Calendar calendar2 = Calendar.getInstance();
Intent myIntent2 = new Intent(MainActivity.this, MyService.class);
myIntent2.putExtra("Id", "2");
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent2,0);
AlarmManager alarmManager2 = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager2.set(AlarmManager.RTC, calendar2.getTimeInMillis(), pendingIntent2);
long tm2 = 0;
String ticket2 = "2";
SharedPreferences timer_saved2 = getApplicationContext().getSharedPreferences("TimerSave"+ticket2, 0);
long timerData2 = timer_saved2.getLong("timer"+ticket2, 0);
long timerValue2 = 0;
long diff_value2 = 36880;
if(timerData2!=0)
{
timerValue2 = timerData2*1000;
}
else
{
timerValue2 = diff_value2*1000;
}
tm2 = timerValue2;
RemainTime2 timerb = new RemainTime2(tm2,1000);
timerb.start();
}
public class RemainTime1 extends CountDownTimer
{
public RemainTime1(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish()
{
}
#Override
public void onTick(long arg0)
{
long millis = arg0;
long hour = TimeUnit.MILLISECONDS.toHours(millis);
long min = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
long sec = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
long hr = 0;
if(hour>=24)
{
hr = hour - 24*7;
}
else
{
hr = hour;
}
timer1.setText(hr+" hr : "+min+" mins : "+sec+" sec ");
}
}
public class RemainTime2 extends CountDownTimer
{
public RemainTime2(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish()
{
}
#Override
public void onTick(long arg0)
{
long millis = arg0;
long hour = TimeUnit.MILLISECONDS.toHours(millis);
long min = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
long sec = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
long hr = 0;
if(hour>=24)
{
hr = hour - 24*7;
}
else
{
hr = hour;
}
timer2.setText(hr+" hr : "+min+" mins : "+sec+" sec ");
}
}}
MySerivce.java
package com.example.multipleservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyService extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);
} }
MyAlarmService.java
package com.example.multipleservice;
import java.util.concurrent.TimeUnit;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Chronometer;
import android.widget.Toast;
public class MyAlarmService extends Service
{
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onStart(Intent intent, int startId)
{
String ticket = intent.getStringExtra("Id");
SharedPreferences timer_saved = getApplicationContext().getSharedPreferences("TimerSave"+ticket, 0);
long timerData = timer_saved.getLong("timer"+ticket, 0);
long timerValue = 0;
long diff_value = 0;
if(timerData!=0)
{
timerValue = timerData*1000;
}
else
{
timerValue = diff_value*1000;
}
RemainTime timer = new RemainTime(timerValue,1000);
timer.start();
super.onStart(intent, startId);
}
public class RemainTime extends CountDownTimer
{
public RemainTime(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish()
{
}
#Override
public void onTick(long arg0)
{
long millis = arg0;
long hour = TimeUnit.MILLISECONDS.toHours(millis);
long min = TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
long sec = TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));
long hr = 0;
if(hour>=24)
{
hr = hour - 24*7;
}
else
{
hr = hour;
}
}
} }
This is my above code , i am getting NullPointerException in getStringExtra section. I want to create two different timer and when i will close the application , but still the two timer should run in the service and when i will open the app again then i should see the updated timer value from the two clock.
Please help me out !!! Please suggest me some possible solution.
I'm developing an Android Application to a college work. In this work I want to create a background service with a timer and when I close the application, timer still running. When I open the app, I can see the time since I've started service.
Well, my problem is that when I close the app, the background timer stops and not increments more.
Can you help me please?
Thanks a lot
My launcher class
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button pauseButton;
private TextView timerValue;
Intent intent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MainActivity.this, CounterService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
private void updateUI(Intent intent) {
int time = intent.getIntExtra("time", 0);
Log.d("Hello", "Time " + time);
int mins = time / 60;
int secs = time % 60;
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs));
}
}
and here, the service class
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
public class CounterService extends Service {
private Intent intent;
public static final String BROADCAST_ACTION = "com.javacodegeeks.android.androidtimerexample.MainActivity";
private Handler handler = new Handler();
private long initial_time;
long timeInMilliseconds = 0L;
#Override
public void onCreate() {
super.onCreate();
initial_time = SystemClock.uptimeMillis();
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 1000); // 1 seconds
}
};
private void DisplayLoggingInfo() {
timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;
int timer = (int) timeInMilliseconds / 1000;
intent.putExtra("time", timer);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
you need to start your service in the onStop() method in your activity like this:
#Override
protected void onStop() {
super.onStop();
//write your code here to start your service
}
Kindly go through the link hope it will be helpful if you want to run timer in background Timer in background
activity_main.xml
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/et_hours"
android:hint="Hours"
android:inputType="time"
android:layout_marginRight="5dp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_timer"
android:layout_above="#+id/btn_cancel"
android:text="Start Timer"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/btn_cancel"
android:text="cancel timer"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_timer"
android:layout_centerInParent="true"
android:textSize="25dp"
android:textColor="#000000"
android:text="00:00:00"/>
</RelativeLayout>
MainActivity.java
package playstore.com.a02backgroundtimer;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_start, btn_cancel;
private TextView tv_timer;
String date_time;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
EditText et_hours;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
listener();
}
private void init() {
btn_start = (Button) findViewById(R.id.btn_timer);
tv_timer = (TextView) findViewById(R.id.tv_timer);
et_hours = (EditText) findViewById(R.id.et_hours);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
try {
String str_value = mpref.getString("data", "");
if (str_value.matches("")) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
if (mpref.getBoolean("finish", false)) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
tv_timer.setText(str_value);
}
}
} catch (Exception e) {
}
}
private void listener() {
btn_start.setOnClickListener(this);
btn_cancel.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_timer:
if (et_hours.getText().toString().length() > 0) {
int int_hours = Integer.valueOf(et_hours.getText().toString());
if (int_hours<=24) {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
date_time = simpleDateFormat.format(calendar.getTime());
mEditor.putString("data", date_time).commit();
mEditor.putString("hours", et_hours.getText().toString()).commit();
Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class);
startService(intent_service);
}else {
Toast.makeText(getApplicationContext(),"Please select the value below 24 hours",Toast.LENGTH_SHORT).show();
}
/*
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/
} else {
Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_cancel:
Intent intent = new Intent(getApplicationContext(),Timer_Service.class);
stopService(intent);
mEditor.clear().commit();
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
break;
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String str_time = intent.getStringExtra("time");
tv_timer.setText(str_time);
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,new IntentFilter(Timer_Service.str_receiver));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
Timer_Service.java
package playstore.com.a02backgroundtimer;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class Timer_Service extends Service {
public static String str_receiver = "com.countdowntimerservice.receiver";
private Handler mHandler = new Handler();
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
private Timer mTimer = null;
public static final long NOTIFY_INTERVAL = 1000;
Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
intent = new Intent(str_receiver);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
strDate = simpleDateFormat.format(calendar.getTime());
Log.e("strDate", strDate);
twoDatesBetweenTime();
}
});
}
}
public String twoDatesBetweenTime() {
try {
date_current = simpleDateFormat.parse(strDate);
} catch (Exception e) {
}
try {
date_diff = simpleDateFormat.parse(mpref.getString("data",""));
} catch (Exception e) {
}
try {
long diff = date_current.getTime() - date_diff.getTime();
int int_hours = Integer.valueOf(mpref.getString("hours", ""));
long int_timer = TimeUnit.HOURS.toMillis(int_hours);
long long_hours = int_timer - diff;
long diffSeconds2 = long_hours / 1000 % 60;
long diffMinutes2 = long_hours / (60 * 1000) % 60;
long diffHours2 = long_hours / (60 * 60 * 1000) % 24;
if (long_hours > 0) {
String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2;
Log.e("TIME", str_testing);
fn_update(str_testing);
} else {
mEditor.putBoolean("finish", true).commit();
mTimer.cancel();
}
} catch (Exception e) {
mTimer.cancel();
mTimer.purge();
}
return "";
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service finish", "Finish");
}
private void fn_update(String str_time) {
intent.putExtra("time", str_time);
sendBroadcast(intent);
}
}
Once the app starts you need to mention the hours you want timer for ... Then also after killing the app when you restarts the app it will show the start time of the timer ... Now you customize you application a per your requirement .