So I found this background service code that keeps on popping up a toasts every 10 seconds. What I want to ask is translate this code on popping up in minutes interval instead of 10 seconds of interval and instead of a toast popping up I want to it to popup an activity when the interval finishes.
public class TimeService extends Service {
// constant
public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
Toast.makeText(getApplicationContext(), getDateTime(),
Toast.LENGTH_SHORT).show();
}
});
}
private String getDateTime() {
// get date time in custom format
SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
return sdf.format(new Date());
}
}
...
}
public static final long NOTIFY_INTERVAL = 10 * 1000 * 60;
10*1000 is 10 seconds.Time is always counted as milliseconds. so
change 10 * 1000 to 10 * 1000 * 60
public static final long NOTIFY_INTERVAL = 10 * 1000 * 60;
Related
/**
* intervals of loop
*/
private final long HEART_BEAT_DELAY = 1000L;
private long lastTime = 0;
/**
* whether user is chatting with other(true:isChatting; false: not chatting)
*/
private boolean mIsChatting = false;
/**
* mainThread
*/
private Thread mThread = new Thread() {
#Override
public void run() {
mThread.setPriority(Thread.MAX_PRIORITY);
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
//if user is chatting and activity is not finishing, keep cycling
while (mIsChatting && !VideoChatViewActivity.this.isFinishing()) {
try {
sleep(HEART_BEAT_DELAY);
//get current time
long thisTime = System.currentTimeMillis();
//get interval between current time and last request time
long duration = thisTime - lastTime;
//every 60 seconds do network request
if (mIsChatting && duration >= 60 * 1000) {
//set last heartbeat time to current time
lastTime = thisTime;
//network request
mModel.sendHeartBeat(mUserId, mCallId);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
/**
* start heartbeat thread
*/
public void startHearBeat() {
if (!mIsChatting) {
mIsChatting = true;
lastTime = System.currentTimeMillis();
mThread.start();
} else {
LogUtil.e("ralph", "start second time, ignore it");
}
}
/**
* stop heartbeat thread
*/
public void endHeartBeat() {
mIsChatting = false;
}
I've got this code and heartbeat should request network for every 60s, but sometimes it will wait to 90s to the next requet.
To fix that i've set processPriority and threadPriority,but they didn't work anyway.
How can i fix that make request on time?
If you are setting threadPriority to the highest, it means that you want this thread to run before anything else.
Try using mThread.join() in startHearBeat() method.
I would like to implement this function:
When the user click on button start the task and after 5 minute send one file to dropbox, but if the user click another time on the button, the precedent task abort and new task (5 min) start.
I wrote code to upload files to Dropbox, but never written code using task with such a long time (5 minute).
How can do that?
-- EDIT --
thanks #xdevs23, I have implemented the final code
public void onSendOrder() {
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
...
...
...
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
};
private Runnable myRunnable = new Runnable() {
#Override
public void run() {
// your code
int cloud = GetPreferenceCloud();
if(cloud > 0){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
final File bckDatabase = BackupDatabase();
if (networkInfo != null && networkInfo.isConnected() && bckDatabase != null) {
runOnUiThread(new Runnable() {
public void run() {
// call your asynctask here
new UploadOnCloud(MainActivity.this,
PreferenceConstants.DB_DATABASE_STORE_CLOUD,
PreferenceConstants.FILE_DIR_CLOUD,
bckDatabase,
mUListener,
cloud).execute();
}
});
} else {
Toast.makeText(getContext(),getContext().getResources().getString(R.string.send_msg13), Toast.LENGTH_SHORT).show();
}
}
}
};
* EDIT. V2 *
For implement the Countdown on statusbar I've implemented this:
Modify the onSend function:
public void onSendOrder() {
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
minute = 3600;
//mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);
....
....
in the file menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/break_timer"
android:title="00:00"
app:showAsAction="always"
app:actionViewClass="android.widget.TextView" />
<item
android:id="#+id/action_refresh"
android:title="#string/action_refresh"
app:showAsAction="ifRoom"
android:icon="#drawable/ic_action_autorenew"/>
</menu>
modify the onCreateOptionsMenu
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem timerItem = menu.findItem(R.id.break_timer);
timerText = (TextView) MenuItemCompat.getActionView(timerItem);
timerText.setPadding(10, 0, 10, 0); //Or something like that...
return super.onCreateOptionsMenu(menu);
}
private int minute;
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
if(minute >= 0){
minute--;
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);
timerText.setText(secondsToString(minute));
}else {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
};
Instead of using an AsyncTask, you could use Threads and Runnables.
Create a Runnable where your code, which you want to run in the background, is located:
Runnable myRunnable = new Runnable() {
#Override
public void run() {
// your code
}
}
Create your Thread:
private Thread myThread;
Make sure that you have a handler created on the main thread.
For best results, add it to your onCreate() method:
private Handler mHandler;
#Override
public void onCreate() {
// ...
mHandler = new Handler();
// ...
}
You need to import android.os.Handler.
Declare the runnable where your upload code is:
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
Now do following when the user clicks on the button:
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 60 * 1000 /* 5 minutes in milliseconds */);
And that's it.
Explanation:
When the user clicks on the button, it will wait (without blocking the UI) for 5 seconds, and then it will run the code inside postRunnable, which starts a new thread in the background, which will run the code inside your myRunnable.
Edit for updating notification
private Handler mHandler;
private int minutes = 5;
private Runnable updateRunnable = new Runnable() {
#Override
public void run() {
if(minutes > 0) {
String notifContent = "" + minutes + " remaining.";
// Create your notification (there are several guides which show you how to do this), use notifContent as title or text or whatsoever
minutes--;
mHandler.postDelayed(updateRunnable, 60 * 1000);
} else {
// Remove your notification
}
}
};
To start the countdown:
mHandler.post(updateRunnable);
In my app, I have a service implementing timer task through which i am getting user's location after every 10 seconds.
The thing I am stuck with is I would like to stop this service as well as timer after say 1 or 2 minutes.
I am not able to put behind the logic for it.
Please help me out.
public class TimeService extends Service {
// constant
public static final long NOTIFY_INTERVAL = 20 * 1000; // 10 seconds
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
int i=0;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
Toast.makeText(getApplicationContext(), getDateTime(),
Toast.LENGTH_SHORT).show();
new LongOperation().execute("");
}
});
}
private String getDateTime() {
// get date time in custom format
SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
return sdf.format(new Date());
}
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
System.out.println("bgnotification Long operation doinbackground called----> ");
return "";
}
#Override
protected void onPostExecute(String result) {
System.out.println("bgnotification Long operation post execute called----> ");
if(i<3){
GPSTracker mGPS = new GPSTracker(getApplicationContext());
onLocationChanged(mGPS);i++;
Toast.makeText(getApplicationContext(), "HEllo Post execute called",
}
#Override
protected void onPreExecute() {
System.out.println("bgnotification Long operation pre execute called----> ");
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
public void onLocationChanged(GPSTracker track) {
// Getting latitude
double latitude = track.getLatitude();
// Getting longitude
double longitude = track.getLongitude();
System.out.println( latitude);
System.out.println( longitude);
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
try
{
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
Log.e("Addresses","-->"+addresses);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
#Wishy to stop service and timer task at certain time you need to make an other timer task which going to execute one time and execution time duration will be whatever you specify. In run method u need to write mTimer.purge(); mTimer.cancel() and stopService(newIntent(class.this,yourservice.class));
An easier solution is making timer public static.
public class TimeService extends Service {
//...
private Timer mTimer = null;
//...
}
another Activity:
//...
if(TimeService.mTimer!=null) TimeService.mTimer.cancel();
//...
Override onDestroy() method in service class like thus:
#Override
public void onDestroy() {
super.onDestroy();
if (mTimer != null) {
mTimer.cancel();
}
}
Call stopService() there where you want to stop your service, like thus:
stopService(serviceIntent);
That's all.
My intention is to create an timer which starts from 00:00:00 and hangs together with a recording function. This recording is done in a service so, the timer is also in the same service. If the app moves to the background, the recording and thus the timer keep on going and the app picks the time up at the onResume with a myService.getTime().
But I experience two strange things. The first is that my timer sometimes goed faster than a second, sometimes slower, sometimes jumps from for example 00:00:04 to 00:00:06 etc. There is no consitency in it. I use the code below, but there might be a better option to solve this? The second is that it is causing a lag on my button, although I am starting it in a service?
SERVICE
//////////TIMER FUNCTION START//////////
private void startTimerClick() {
if (stopped) {
startTime = System.currentTimeMillis() - elapsedTime;
} else {
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer);
mHandler.postDelayed(startTimer, 0);
}
private void pauseTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = true;
}
private void stopTimerClick() {
mHandler.removeCallbacks(startTimer);
stopped = false;
}
private void startTimer() {
startTimer = new Runnable() {
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
mHandler.postDelayed(this, REFRESH_RATE);
}
};
}
private void updateTimer(float time) {
secs = (long) (time / 1000);
mins = (long) ((time / 1000) / 60);
hrs = (long) (((time / 1000) / 60) / 60);
/*
* Convert the seconds to String and format to ensure it has a leading
* zero when required
*/
secs = secs % 60;
seconds = String.valueOf(secs);
if (secs == 0) {
seconds = "00";
}
if (secs < 10 && secs > 0) {
seconds = "0" + seconds;
}
/* Convert the minutes to String and format the String */
mins = mins % 60;
minutes = String.valueOf(mins);
if (mins == 0) {
minutes = "00";
}
if (mins < 10 && mins > 0) {
minutes = "0" + minutes;
}
/* Convert the hours to String and format the String */
hours = String.valueOf(hrs);
if (hrs == 0) {
hours = "00";
}
if (hrs < 10 && hrs > 0) {
hours = "0" + hours;
}
}
//////////TIMER FUNCTION END////////////
public String getHours(){
return hours;
}
public String getMinutes(){
return minutes;
}
public String getSeconds(){
return seconds;
}
}
ACTIVITY(/FRAGMENT)
private void timerStart() {
handler = new Handler();
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
handler.post(new Runnable() {
#Override
public void run() {
timer.setText(myService.getHours()+":"+myService.getMinutes()+":"+myService.getSeconds());
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
}
You are using Threads both in your Service and in your Activity/Fragment code.
Using threads for time sensitive tasks in Android is a problem because Android is able to significantly delay threads.
I have been using a ScheduledThreadPoolExecutor for a similar task and it worked great.
You are then using it like this:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); // where 1 is the number of needed concurrent threads. 1 should last for your needs.
executor.scheduleWithFixedDelay(new TimerTask() {
// your recurringly executed code here
}, 0, 1, TimeUnit.SECONDS);
A bit confusing this one but should make sense.
Thanks to all your help I have my app now showing a custom digital clock and a countdowntimer (02:30:00 countdown) running under it.
How do I add 02:30:00 to the current time so a new clock field shows the current time + the countdown?
Thanks
Dj
This is my digitalclock code where would i put the offset to ad 2 hours 30 mins to time...
#Override
protected void onStart() {
super.onStart();
timer = new Timer("DigitalClock");
Calendar calendar = Calendar.getInstance();
final Runnable updateTask = new Runnable() {
public void run() {
countdown.setText(getCurrentTimeString());
}
};
int msec = 999 - calendar.get(Calendar.MILLISECOND);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(updateTask);
}
}, msec, 1000);
}
#Override
protected void onStop() {
super.onStop();
timer.cancel();
timer.purge();
timer = null;
}
private String getCurrentTimeString() {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
// int second = calendar.get(Calendar.SECOND);
return String.format("%02d:%02d", hour, minute);
}
Now that I understand your question :p, I think the only way to do that is to reimplement a DigitalClock. Take its source code and play with it by adding an offset to the hours and minutes.
UPDATE:
What I would do is take that code and change this part:
mTicker = new Runnable() {
public void run() {
if (mTickerStopped) return;
mCalendar.setTimeInMillis(System.currentTimeMillis());
setText(DateFormat.format(mFormat, mCalendar));
invalidate();
long now = SystemClock.uptimeMillis();
long next = now + (1000 - now % 1000);
mHandler.postAtTime(mTicker, next);
}
};
mTicker.run();
Convert 2:30:00 to milliseconds and add it to now :
long now = SystemClock.uptimeMillis() + offset;