I have this countdown timer which i modified to count up.The timer will keep on running at the same time give percentage on a textview (tvp). below are the code.
timer = new CountUpTimer(date3) {
public void onTick(int secondt) {
simpleDateFormat = new SimpleDateFormat ("HH:mm:ss");
tv_timer.setText(simpleDateFormat.format (secondt));
t1 = date3 - date;
percentage = Math.round (secondt/t1 *100);
tvp.setText ( percentage+"%" );
}
};timer.start();
The timer is running on background which i use services and broadcast receiver and it work just fine.
The problem is, the percentage textview is not updating and running and stuck on the last value after pressing back button. below are the runnable code used to update percentage textview.
getActivity ().runOnUiThread(new Runnable() {
#Override
public void run() {
tvp.setText ( percentage + "%" );
}
});
below are my timer service code
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
intent = new Intent(str_receiver);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
mHandler.post( () -> {
timerprogressupdate ();
} );
}
}
public String timerprogressupdate() {
fn_update ( IFTimer.secondt );
fn_updatep ( IFTimer.percentage );
return timerprogressupdate();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service finish","Finish");
}
private void fn_update(long str_time){
intent.putExtra("time",str_time);
sendBroadcast(intent);
}
}
broadcast receiver
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String strDate = intent.getStringExtra("time");
}
};
I need the percentage textview updating and running after i press back button. Anyone have a solution on this? Appreciated if anyone could help me.
Related
I try to run a method in my service every two seconds, but when i start the services just run one time
This is the relevant code:
the start service:
mViewHolder.mLinearLayoutContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent launchIntent = view.getContext().getPackageManager().getLaunchIntentForPackage(mListStorage.get(position).getAdrress());
mApkPackage = mListStorage.get(position).getAdrress();
Intent intent = new Intent(view.getContext(), KillerService.class);
if(mApkPackage != null){
intent.putExtra("NAMEAPK", mApkPackage);
view.getContext().startService(new Intent(view.getContext().getApplicationContext(), KillerService.class));
view.getContext().bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
}
if (launchIntent != null) {
view.getContext().startActivity(launchIntent);//null pointer check in case package name was not found
}
}
});
And this is from my Service class:
#Override
protected void onHandleIntent(#Nullable Intent intent) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//mAppsNames();
Log.d("SYSTEMRUNNIGKILLI", "matandoapps");
}
}, 2000);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
mApkName = intent.getStringExtra("NAMEAPK");
Log.d("HOLAXD", mApkName);
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
The part of Log.d("SYSTEMRUNNIGKILLI", "matandoapps"); just run one time and not every 2 seconds.
You are using wrong method to call code after every 2 seconds . Try to use this method
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {}
}, 0, 1000); //1000 miliseconds equal to 1 second
Another way just add handler.postDelayed(this,2000);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//mAppsNames();
Log.d("SYSTEMRUNNIGKILLI", "matandoapps");
handler.postDelayed(this,2000);
}
}, 2000);
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'm trying to make an alarm app for android the first thing that i should do is to continuously get the current time of system so i did this but it only gets the current second and no more ,, any help ?
here is the code :
public class MainActivity extends Activity {
public Button time;
public TextView secondview;
public static int hours, mins, secs;
Handler main;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = (Button) findViewById(R.id.button1);
secondview = (TextView) findViewById(R.id.textView2);
new Thread(new Runnable() {
#Override
public void run() {
secondview.setText(String.valueOf(secs));
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
main = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Calendar mycal = Calendar.getInstance();
hours = mycal.get(Calendar.HOUR);
mins = mycal.get(Calendar.MINUTE);
secs = mycal.get(Calendar.SECOND);
secondview.setText(String.valueOf(secs));
}
};
}
}
Handler and Thread are bad choice for this type of problem.
To make an alarm app, use AlarmManager.
You should carefully choose which type of timer to use. (ELAPSED_REALTIME, RTC, ....)
For alarm app, RTC_WAKEUP is good choice.
And Android developer site has training how to use AlarmManager.
quote:
// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
There's another example for some use case.
Android provide two ways of service,one is bind to activity,when activity destoyed,the service also,another can achieve the same function,but it have no connoction with activity. and here we need use the second one!
public class MainActivity extends Activity {
private Button startService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.startService);
startService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, CountService.class);
startService(intent);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
Intent intent = new Intent(MainActivity.this,CountService.class);
stopService(intent);
}}
public class CountService extends Service{
private int seconds=0;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
#Override
public void run() {
while(seconds!=-1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("TIME","Time "+seconds);
//handle seconds use Calendar and AlarmManager
seconds++;
}
}
}).start();
}
#Override
public void onDestroy() {
super.onDestroy();
}}
I found this from somewhere. It uses timertask.
public void updateTimeOnEachSecond() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
c = Calendar.getInstance();
Log.d("myapp", "time changed");
hrs = c.get(Calendar.HOUR_OF_DAY);
min = c.get(Calendar.MINUTE);
sec = c.get(Calendar.SECOND);
runOnUiThread(new Runnable() {
#Override
public void run() {
txt_hrs.setText(String.valueOf(hrs));
txt_mins.setText(String.valueOf(min));
txt_sec.setText(String.valueOf(sec));
}
});
}
}, 0, 1000);
}
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");
}
};
}
I am creating an app that vibrate and beep every 30 sec and when I log out the vibrate and beep must be cancelled and when I log in the vibrate and beep should resume.
NOTE: it must vibrate and beep for every 30 sec until I log out
In my app I am using TimerTask for this implementation
this is the code for vibrate and beep using TimerTask
static TimerTask Task;
final static Handler handler = new Handler();
static Timer t = new Timer();
public static void vib() {
Task = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Vibrator vibrator = (Vibrator) ApplicationUtils.getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(3000);
playSound();
Log.d("TIMER", "Timer set on");
}
});
}
};
t.schedule(Task, 0, 30000);
}
This is the code I'm using in logout section
public void stopvib() {
if (Task != null) {
// Log.d("TIMER", "timer canceled");
t.cancel();
Task.cancel();
}
}
Note: I also removed the Task.cancel(); but still I am getting same error
My vibrate working fine before logout and again login I am geting error
java.lang.IllegalStateException: Timer was cancelled
at java.util.Timer.scheduleImpl(Timer.java:562)
at java.util.Timer.schedule(Timer.java:481)
at com.vib(AlertListActivity.java:724)
can any one help me with this coding. Where did I go wrong?
i have recently run this code and is working fine. This can be achieved using broadcast Receiver.You have to implement separate CustomTimer task that extend TimerTask:
Activity mActivity=null;
public MyCustomTimer(Activity mActivity) {
this.mActivity=mActivity;
}
#Override
public void run() {
this.mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mActivity, "Write you code here",Toast.LENGTH_LONG).show();
Log.d("MyCustomTimer","Call");
}
});
}
After this you have to implement BroadCast Receive in that class where you want to implement " vib() " method.:
Let say, in my case (just for example ) is MainActivity:
public class MainActivity extends Activity {
private MyCustomTimer myCustomTimer = null;
BroadcastReceiver mBr_Start = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("START_VIBRATION")) {
System.out.println("onreceive :START_VIBRATION");
vib();
}
}
};
BroadcastReceiver mBr_Stop = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("STOP_VIBRATION")) {
stopVibration();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("START_VIBRATION");
registerReceiver(mBr_Start, mIntentFilter);
IntentFilter mIntentFilter2 = new IntentFilter();
mIntentFilter2.addAction("STOP_VIBRATION");
registerReceiver(mBr_Stop, mIntentFilter2);
Button b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, MySecondActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private void vib() {
myCustomTimer = new MyCustomTimer(MainActivity.this);
Timer timer = new Timer();
timer.scheduleAtFixedRate(myCustomTimer, 0, 30000);
}
private void stopVibration() {
Log.d("MainActivity", "Before Cancel");
if (null != myCustomTimer)
myCustomTimer.cancel();
Log.d("MainActivity", "After Cancel");
}
}
Now,you can start Or stop vibration by implementing these lines:
To start vibration:
Intent i=new Intent("START_VIBRATION");
mActivity.sendBroadcast(i);
To Stop:
Intent i=new Intent("STOP_VIBRATION");
mActivity.sendBroadcast(i);
Note:
onDestroy() of MainActivity (in your case,Where you implement Broadcast Receiver,unregister BroadcastReceiver.)
Set timer instance to null when you logout and then initialize it everytime user logged in the app. This will fix the "Timer was cancelled" related issues.
Why do you need a static TimerTask.You can give like this which works fine for me.
timer.schedule(new TimerTask() {
#Override
public void run() {
//your code
}
}, 0, 30000);
While logout use, timer.cancel().
Here you can simply cancel the timer.No need to cancel the TimerTask.