Reputation: 540
I have activity which needs to be active all the time. I have thread which sleep 10 sec, and monitors values taken from database, compare them and start method. I'm wondering if user go back to other applications and activities, does my activity and thread still work, or they are handled by activity manager and go to pause-stop-destroy?? How to stay them a live?? Thank you. here is code for that thread:
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(10000);
myHendler.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
final Calendar cal = Calendar.getInstance();
int godina2 = cal.get(Calendar.YEAR);
int mesec2 = cal.get(Calendar.MONTH);
int dan2 = cal.get(Calendar.DAY_OF_MONTH);
int sati2 = cal.get(Calendar.HOUR_OF_DAY);
int minuti2 = cal.get(Calendar.MINUTE);
trenutniDatum = new StringBuilder().append(dan2).append("-").append(mesec2 +1).append("-").append(godina2);
trenutnoVreme = prepraviVreme(sati2) + ":" + prepraviVreme(minuti2);
for(int i = 0; i < primljenoIzBazeDatum.length; i++){
String bazaBroj = "";
String bazaText = "";
if(primljenoIzBazeDatum[i].toString().equals(trenutniDatum.toString()) && primljenoIzBazeVreme[i].toString().equals(trenutnoVreme)){
int bazaId = Integer.parseInt(primljenoIzBazeId[i]);
bazaBroj = primljenoIzBazeBroj[i].toString();
bazaText = primljenoIzBazeText[i].toString();
String datumPromena = "*" + primljenoIzBazeDatum[i].toString() + "* SENT *";
datumVreme.open();
datumVreme.updateData(bazaId, datumPromena);
datumVreme.close();
sendPoruka(bazaBroj, bazaText);
}
} // end for
} // end run
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
Upvotes: 1
Views: 1475
Reputation: 13402
Based on my understanding of what you want to do, here is what I would do :
First, create a BroadcastReceiver
public class Poller extends BroadcastReceiver {
private final String TAG = "Poller";
@Override
public void onReceive( Context context, Intent intent ) {
Log.i(TAG, "Poller broadcastintent received");
Intent myIntent = new Intent( context, PollerService.class );
context.startService( myIntent );
}
then , create the service that is called and then shuts itself down
public class PollerService extends Service {
final String TAG = "PollerService";
@Override
public void onStart(Intent intent, int startId) {
Log.i(TAG, "Service onStart()");
pollingTask.execute();
}
AsyncTask<Void, Void, Void> pollingTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... param) {
// Do what you want in the background
}
@Override
protected void onPostExecute(Void result) {
stopSelf();
}
};
}
then, set an AlarmManager to wake the service every minute
AlarmManager am = ( AlarmManager ) getSystemService( Context.ALARM_SERVICE );
Intent alarmIntent = new Intent( "CHECK_DATABASE" );
PendingIntent pi = PendingIntent.getBroadcast(context, 0 , alarmIntent, 0 );
int type = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long interval = POLLING_INTERVAL_IN_MILLISECONDS;
long triggerTime = SystemClock.elapsedRealtime() + interval;
// For short intervals setInexact repeating is same as exactRepeating, use at least fifteen minutes to make it more efficient
am.setInexactRepeating( type, triggerTime, interval, pi );
Log.i(TAG, "Set inexact alarm through AlarmManager");
}
setup the receiver in Android manifest
<receiver android:name="Poller">
<intent-filter>
<action android:name="CHECK_DATABASE"/>
</intent-filter>
</receiver>
finally, unset the AlarmManager to stop polling once your required SMS is received
AlarmManager am = ( AlarmManager ) getSystemService( Context.ALARM_SERVICE );
Intent intent = new Intent( "CHECK_DATABASE" );
PendingIntent pi = PendingIntent.getBroadcast( context, 0 , intent, 0 );
am.cancel(pi);
I do think that Peter is right though and this will kill you battery unless you'll only be checking until you get the required info and then don't poll and that's a short time.
Also, if you can get the exact time when you want to send the SMS with a single call from the database you can just set up the AlarmManger to wake up the service at that time, perform the action and be done with it. That would be the best approach (I can't quite make out if that is the case from you code but it does seems to be from you comments).
Upvotes: 6
Reputation: 6900
In Java language you can scheduling your programs by traditional way:
java.util.Timer
java.util.TimerTask
for more information you can see:
but better practice is using a scheduling framework such as Quartz, you can see http://www.quartz-scheduler.org/. Spring framework also integration with Quartz framework.
Upvotes: 0
Reputation: 80340
No, no application code on Android is not guaranteed to run all the time. Android OS can kill off aplications and services any time it feels it needs to.
Your best bet to periodically execute code would be to use AlarmManager, which makes your code execute periodically. Also a proper flag must be set to execute your code when device is asleep.
Note, since your period is very short (10s), it would keep CPU running all the time, draining the batterry very quickly.
Upvotes: 3
Reputation: 2996
If it has to be active all the time you have to use a Service: http://developer.android.com/guide/topics/fundamentals/services.html
I'm wondering if user go back to other applications and activities, does my activity and thread still work, or they are handled by activity manager and go to pause-stop-destroy?? How to stay them a live??
They won't be kept "alive". If the system needs the resources your activity is destroyed. If you want to keep things running in the background even after your app is finished you have to use a Service.
Upvotes: 0