I want to run some task (fetching data from database) in background after 5 minutes interval. What should I use?
Please mind that Google ask you to run long operations on Service. Please read the articles below, to detech what service do you need (service, interservice)!
Intent Service going to shut down itself after the job is done.
To fire a service in every 5mins to do the job , you can combine with a timer, as suggested above.
Mind before continue: Service belongs to the same thread, where you create it. So when you are about to developer your service please use a new Thread to start it. If you forget to do it, your service going to belong to the UI thread, mean you are in a trouble....
read first:
http://developer.android.com/guide/components/services.html
developer guide:
http://developer.android.com/reference/android/app/Service.html
You can use TimerTask inside a service
Timer timer = new Timer();
timer.schedule( new YourTask(), 50000 );
Try this.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Do something
}
}, 0, 5000);
Use Async task:
pre Execute, do inBackground, Post Execute
With alarm Manager
Intent myIntent1 = new Intent(sign_in.this,MyNotificationService.class);
pendingintent2 = PendingIntent.getService(sign_in.this, 1,myIntent1, 1);
AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar1Notify = Calendar.getInstance();
calendar1Notify.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 20);
alarmManager1.set(AlarmManager.RTC_WAKEUP,calendar1Notify.getTimeInMillis(), pendingintent2);
long time = 300*1000;// 5 minutes repeat
alarmManager1.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1Notify.getTimeInMillis(),time,pendingintent2);
Add Permission in manifest
<service android:name="com.example.MyNotificationService" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</service>
you can use a timer task:
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
public void doTask(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
//your task(fetch data)
}
});
}};
t.schedule(scanTask, 300000, 300000);
}
You can use timer, it is not a problem but method within android do have some advantages
private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
...
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
updateStatus(); //this function can change value of mInterval.
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
Related
I want to clear my shared preferance field phonenumber exactly at 12 am in broadcast receiver. How will I do that ?
Here is my code ...
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences prefs = context .getSharedPreferences("connect", Context.MODE_PRIVATE);
String username = prefs.getString("phonenumber", null ) ;
}
}```
Alarm Manager
The Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing.
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
synchronized public void run() {
preferences.edit().putString(key, "").apply()
}
}, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
ScheduledThreadPoolExecutor.
You can use java.util.Timer or ScheduledThreadPoolExecutor (preferred) to schedule an action to occur at regular intervals on a background thread.
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
// call the preferences clear logic
}
}, 0, 10, TimeUnit.MINUTES);
EDit:
You can actually save the install time and then do a calculation to see if a week has elapsed. If it has clear the shared preference
//First time
long installed = context
.getPackageManager()
.getPackageInfo(context.getPackageName(), 0)
.firstInstallTime;
Ref:More on periodic event handling
Get install time and clear shared preference
I have been trying to write a metronome in Android however I am finding really hard to sync the beats accurately using the Handler postdelayed method. I manage to achieve an accurate timing using a ScheduledThreadPoolExecutor, but the issue is that with the ScheduledThreadPoolExecutor I can't control the timing from within the run method and therefore I am forced to stop and start the scheduled job, which is not ideal. Is there a way to make the Handler postdelayed more accurate? or a way to reschedule the ScheduledThreadPoolExecutor without having to stop and start the thread?
My current code is as below:
public class Metronome extends Service implements Runnable
{
private Handler handler = new Handler();
private SoundPool soundPool;
private long interval;
private void initSoundPool()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
soundPool = new SoundPool.Builder()
.setMaxStreams(1)
.setAudioAttributes(new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build())
.build();
} else
{
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
}
soundId = soundPool.load(context, R.raw.secondary_clave, 1);
}
#Override
public void run()
{
handler.postDelayed(this, interval);
soundPool.play(soundId, 1, 1, 0, 0, 1);
}
public void start()
{
handler.post(this);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
With the ScheduledThreadPoolExecutor it's super accurate, however, I don't have control via the "interval" flag inside the run loop, so if I change the interval I have to terminate the executor and start a new one everytime I need to rechedule which is horrible.
public class Metronome extends Service implements Runnable
{
private SoundPool soundPool;
private long interval;
private ScheduledThreadPoolExecutor beatsPerBarExec;
private ScheduledFuture<?> futureThread;
private void initSoundPool()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
soundPool = new SoundPool.Builder()
.setMaxStreams(1)
.setAudioAttributes(new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build())
.build();
} else
{
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
}
soundId = soundPool.load(context, R.raw.secondary_clave, 1);
}
#Override
public void run()
{
soundPool.play(soundId, 1, 1, 0, 0, 1);
}
public void start()
{
beatsPerBarExec = new ScheduledThreadPoolExecutor(1);
futureThread = beatsPerBarExec.scheduleAtFixedRate(this, 0, interval, TimeUnit.MILLISECONDS);
}
public void pause()
{
futureThread.cancel(false);
beatsPerBarExec.purge();
beatsPerBarExec = null;
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
You may be seeing the effects of drift.
Example: you want your Runnable to run every 200msec. You reschedule your Runnable in the run() method using postDelayed() and pass it 200msec as the delay. When the run() method is called the next time, it may not be exactly 200msec since the previous time. Perhaps it is 210msec. Now you reschedule your Runnable to run in another 200msec. This time the run() method may be called again after 210 msec, which means your sound plays 420msec since the first one, etc.
To eliminate drift, you need to determine the exact clock time you want the Runnable to run at, subtract the current time and use that in the call to postDelayed(). This will take into account any potential variance in the thread timing.
Be aware that when you call postDelayed() you are posting a Runnable to run on the main (UI) thread. This is the thread that handles all the UI updates and when your Runnable is ready to run it will just be queued to the main (UI) thread handler, and may not run immediately.
You can mitigate this problem by scheduling your Runnable to run on a background thread instead of the main (UI) thread. However this means your Runnable will be called on the background thread and I don't know if your other code (that plays the sound) needs to run on the main (UI) thread or not.
I have an Android project which is sending a Broadcast every second and am trying to figure out how to stop it after a click.
My broadcast code is:
Intent broadcastIntent = new Intent ("send broadcast");
sendBroadcast(broadcastIntent);
stoptimertask(); //it is stopping broadcast for a second.
You can define two methods: one that start a Timer to send a broadcast every second and a second one that stop the Timer.
Timer timer;
private void startBroadcastLoop() {
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
// Send broadcast
Intent broadcastIntent = new Intent ("send broadcast");
sendBroadcast(broadcastIntent);
}
},0,1000); // Send broadcast every second
}
private void stopBroadcastLoop() {
if(timer!=null){
timer.cancel();
timer = null;
}
}
And then on your button, call the right function according to the state of a boolean:
sendBroadcastBool = false;
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// If broadcast not sent yet
if (!sendBroadcastBool) {
startBroadcastLoop();
sendBroadcastBool = true;
}
else {
stopBroadcastLoop();
sendBroadcastBool = false;
}
}
});
Best
I am making an android app that requires a runnable. I am starting a new activity from the runnable. The new activity comes up and works fine. The issue is that when the call is made to start the activity, it is incredibly slow. It takes a full 5 seconds to start the activity when I want it to be instantaneous.
Boolean handlerrun=true;
Intent intent= new Intent(this,newactivity.class);
int somevalue=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameactivity);
handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
if(handlerrun){somevalue++;}
if(somevalue>500){
handlerrun=false;
startActivity(intent);
finish();
}
handler.postDelayed(this, 1);}
}
};
handler.postDelayed(r, 1);
}
The activity starts when somevalue is greater than 500. To stop the handler from increasing the value of somevalue, I use a boolean handlerrun, which only runs the handler when it is true. When somevalue is greater than 500, handlerrun= false so the handler doesn't increase the value. I tried using the handler.removeCallbacksandMessages() method but it didn't work. Logcat doesn't give me any errors.Any help would be appreciated.
You could try something like this:
#Override
protected void onResume() {
super.onResume();
if(done){
return;
}
done = true;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(getApplicationContext(), YourActivity.class));
finish();
overridePendingTransition(0, 0);
}
}, 5000);
}
That will start YourActivity after 5 seconds approximately.
Hope it helps.
hi
When my app get the ACTION_BOOT_COMPLETED it starts a service.
I would like to delay that for lets say 60sec.
Can i do that in the:
public class StartAtBootServiceReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
// Delay...60sec
}
}
use Timer() and TimerTask():
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
//run your service
}
}, 60000);
When you receive the BOOT_COMPLETED intent you should use the AlarmManager to setup an pending intent that will fire after 60 seconds.