I am trying to create a service with background task. 24 hrs once the thread would start and do the process.
I have tried like this. but its not worked.
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 10 * 1000; // / 1000 = 1 second
private Timer timer = new Timer();
Home home;
private boolean isRunning = true;
#Override
public IBinder onBind(Intent intent) {
// Not implemented...this sample is only for starting and stopping
// services.
// Service binding will be covered in another tutorial
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Announcement about starting
Toast.makeText(this, "Starting the Demo Service", Toast.LENGTH_SHORT)
.show();
// Start a Background thread
isRunning = true;
// Thread backgroundThread = new Thread(new BackgroundThread());
BackgroundThread();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Background thread
isRunning = false;
// Announcement about stopping
Toast.makeText(this, "Stopping the Demo Service", Toast.LENGTH_SHORT)
.show();
}
private void BackgroundThread() {
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
Calendar c = Calendar.getInstance();
String month = String.valueOf(c.get(Calendar.MONTH) + 1);
String year = String.valueOf(c.get(Calendar.YEAR));
String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH));
String months = null;
if (month.startsWith("0") || month.startsWith("1")) {
months = year + "-" + month + "-" + day;
home.loadCalender(months);
} else {
months = year + "-" + "0" + month + "-" + day;
home.loadCalender(months);
}
}
}, 0, UPDATE_INTERVAL);
/*
* counter = 0; while(isRunning) { System.out.println(""+counter++);
* //Thread.currentThread().sleep(5000);
*
* }
*/
System.out.println("Background Thread is finished.........");
}
}
In my main activity, i have started the Service...
plz help me to do this task.
Use AlarmManager to schedule your alarm to occur once per day, using setRepeating() (or perhaps setInexactRepeating(). Please do not waste the user's RAM trying to have a service running all of the time watching the clock tick.
Related
These methods are implemented in a class extending Service. A new service is started every time a button is pressed.
If the button is pressed once, LogCat outputs what I expect, which includes a final output of "Service onDestroy." However, when the button is pressed twice, the second time before the first service ended, "Service onDestroy." displays only once when the first service is done, and the second service prints out the rest of "Service Running" logs but not "Service onDestroy."
Can anyone tell me why? Thank you!
public int onStartCommand(Intent intent,int flags, int startId) {
Log.i(TAG,"Service onStartCommand " + startId);
final int currentId = startId;
Runnable r = new Runnable() {
public void run() {
for (int i = 0; i < 3; i++) {
long endTime = System.currentTimeMillis() + 10*1000;
while (System.currentTimeMillis() < endTime) {
synchronized(this) {
try {
wait(endTime - System.currentTimeMillis());
}catch (Exception e) {
}
}
}
Log.i(TAG,"Service running");
}
stopSelf();
}
};
Thread t = new Thread(r);
t.start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG,"Service onBind");
return null;
}
#Override
public void onDestroy() {
Log.i(TAG,"Service onDestroy");
}
In the guide for Services they use don't use stopSelf() but stopSelf(startId) when extending Service. The first stopSelf() propably stops both executions of your Service.
See here: http://developer.android.com/guide/components/services.html
Edit: Also a service is only created and destroyed once even when there are several executions of it running it is still a single service. In your case (a Bound Service) it will only be destroyed when the last excecution finishes. For logging every excecution ending you could try to override the stopSelf(int startId) method.
I have an Intent service running that performs a do while loop.
The service is started from an activity when a button is pressed.
Problem is when I press the button again a new service is started along side the previous service from the first press.
I want the previous service to be stopped and the new service to replace it.
Essentially i want to know how to either kill services or pass data to the running thread in order to change the do while conditions. Im not sure how to handle this.
Thanks for your help.
startAlarm.setOnClickListener(new View.OnClickListener() {
int x=0;
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
getActivity().startService(alarmService);
System.out.println("Service has started.");
}
});
public class AlarmService extends IntentService{
public AlarmService() {
super("Alarm run service");
// TODO Auto-generated constructor stu
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
int hour = intent.getExtras().getInt("hourval");
int minute = intent.getExtras().getInt("minval");
System.out.println("Hour is : " + hour + " minute is : " + minute);
int currentHour;
int currentMinute;
do{
System.out.println("in the loop");
Calendar cal = Calendar.getInstance();
currentHour = cal.get(Calendar.HOUR_OF_DAY);
currentMinute = cal.get(Calendar.MINUTE);
System.out.println(currentHour + ":" + currentMinute + "and " + hour +":" +minute);
}while(currentHour != hour || currentMinute != minute);
System.out.println("Left loop");
Intent alarmRingStart = new Intent(getApplicationContext(),AlarmRing.class);
alarmRingStart.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(alarmRingStart);
System.out.println("Alarm has gone off");
}
#Override
public void onDestroy(){
super.onDestroy();
}
}
you can first stopService, and in service.onDestroy set a flag indicating the while loop should exit. you should always check the value of that flag.
Below given code is written to track battery level of device and store it in db. In order to get battery level, function "batterylevel" is called every 3 minutes, and battery level is inserted to db table. And also code saves the time, when device gets full charged, in another db table. Everything works fine for some time. But problem occurs after about 30 minutes, the running service automatically enters to its oncreate method, after that service won't show any logs, eventually service stops causing force close while trying to stop the service manually.
public class BatteryLevelService extends Service {
BroadcastReceiver batteryLevelReceiver;
Timer t ;
Calendar cal;
Date lastBatteryFullTime;
Context context;
int sec;
int lastFullChargeYear,lastFullChargeMonth,lastFullChargeDay;
int lastFullChargeHour,lastFullChargeMinute,lastFullChargeSecond;
private File dir;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate(){
Log.d("Service", "oncreate Service Started");
}
private void batteryLevel() {
cal=Calendar.getInstance();
long currentHour=cal.get(Calendar.HOUR_OF_DAY);
long currentMinute=cal.get(Calendar.MINUTE);
long currentSecond=cal.get(Calendar.SECOND);
final String currentTime=currentHour+" : "+currentMinute+" : "+currentSecond;
Intent batteryIntent = registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int rawlevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (rawlevel >= 0 && scale > 0) {
level = (rawlevel * 100) / scale;
}
MainActivity.sqladp.insertBatteryLevel(level, currentTime);
if(level==100){
cal=cal.getInstance();
lastFullChargeYear=cal.get(Calendar.YEAR);
lastFullChargeMonth=cal.get(Calendar.MONTH);
lastFullChargeDay=cal.get(Calendar.DAY_OF_MONTH);
lastFullChargeHour=cal.get(Calendar.HOUR_OF_DAY);
lastFullChargeMinute=cal.get(Calendar.MINUTE);
lastFullChargeSecond=cal.get(Calendar.SECOND);
lastBatteryFullTime=new Date(lastFullChargeYear, lastFullChargeMonth, lastFullChargeDay, lastFullChargeHour, lastFullChargeMinute);
String[] lastFullChargeTime=lastBatteryFullTime.toString().split("GMT");
MainActivity.sqladp.deleteLastFullBattery();
MainActivity.sqladp.insertLastUsage("Battery", "", lastFullChargeTime[0], "");
}
Log.d("Battery level", ""+level + "%");
}
#Override
public void onStart(Intent intent, int startId) {
Log.d("Service", "Service Started");
t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
batteryLevel();
Log.d("", "batlevel ");
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
3*60*1000);
}
#Override
public void onDestroy() {
Log.d("service", "onDestroy");
t.cancel();
}
The method onStart() is only used for old Android versions (<2.0). For later versions you should use onStartCommand() as bellow:
#Override
public int onStartCommand(Intent intent, int flags, int startId)
this will solve your problem
I have a Foregound Service with a broadcaster.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Service
Log.d("Service","Service started");
startTime = intent.getLongExtra("STARTTIME", 0);
endTime = intent.getLongExtra("ENDTIME", 0);
isRunning = true;
postNotification();
// Broadcaster
handler.removeCallbacks(updateRunnable);
handler.postDelayed(updateRunnable, DELAY);
return START_STICKY;
}
When I try to stop the service the onDestroy() runs and all is fine, but the updateRunnable keeps on going so the broadcasting still occurs.
private Runnable updateRunnable = new Runnable() {
public void run() {
Log.d("Service", "run");
currentTime = System.currentTimeMillis();
if(endTime > 0 && (currentTime-startTime) >= endTime) {
isRunning = false;
// Alarm
AlarmNotification alarmNotification = new AlarmNotification(context);
alarmNotification.startAlarm();
// Notification
AppNotification notify = new AppNotification(context);
notify.stopNotification();
update();
// Tried them all:
stopService(intentBroadcaster);
stopForeground(true);
stopSelf();
} else {
update();
}
handler.postDelayed(this, 1000); // 1 seconds
}
};
As you can see I have tried every stop command I can think of. What am I doing wrong here? How do I stop the broadcasting / runnable?
Your broadcaster keeps running because your application process is still running, so your thread will keep on executing unless you told it not to.
It's easy to stop your thread, in your run method:
private boolean shouldContinue = true;
private Runnable updateRunnable = new Runnable() {
public void run(){
// ... whaterver your doing
if(shouldContinue){
handler.postDelayed(this, 1000);
}
}
};
public void onDestroy(){
shouldContinue = false;
}
I write an app that schedule to start accelerometer every 15 seconds and run it 10 seconds to retrieve sensor data. I start accelerometer using alarmManager and keep it running with wakelock when screen go off. But I found sometimes:
The accelerometer can't retrieve data after some periods. I mean it have been started according to logcat,but there is not any sensor data,then it is closed and it starts again without data.
I don't know why the accelerometer didn't start any more after some periods and it is fine before. I found logcat says "listener with binder android.os.BinderProxy doesn't exist accelerometer". I don't know why.
following is kernel code:
Activity.java
Intent intent = new Intent(getApplicationContext(),SensorService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long curTime = Calendar.getInstance().getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, curTime, _intervalTime, pendingIntent);
SensorService.java
public void onStart(Intent intent, int startId) {
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
wl.acquire();
Log.d(TAG,"I'm bright!");
try {
Thread.sleep(_delayClose);// kill self after _delayClose ms
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stopSelf();// SensorService.this.stopSelf()
}
}).start();
this.mSensorManager.registerListener( _sensorHandle,
accSensor,
sensorDelay)
}
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
this.mSensorManager.unregisterListener(_sensorHandle);
Log.d(TAG,"TIEM UP");
if(wl.isHeld())
{
wl.release();
}
}
I'm guessing that there must be some considerable overhead in registering and unregistering sensor listener that often, plus the alarmManager overhead.
Given that you want sensor data that often, how about just keep your listener registered and have it internally manage when it should and shouldnt do something useful with the samples it's receiving?
public class SensorSamplrActivity extends Activity {
private final static String TAG = "samplr";
private final static int SAMPLE_INTERVAL_SECS = 15;
private final static int SAMPLE_DURATION_SECS = 10;
private SensorManager mSensorManager;
private long whenToStartSample = System.currentTimeMillis();
private long whenToEndSample = System.currentTimeMillis() + SAMPLE_DURATION_SECS;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);
}
private SensorEventListener mSensorListener = new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
long now = System.currentTimeMillis();
if (now < whenToStartSample){
// ignore the event & wait for next time to sample
Log.d(TAG,"ignoring events for " + (whenToStartSample - now) + "ms");
return;
}
if (whenToStartSample <= now && whenToEndSample > now){
Log.d(TAG,"Do something with this event # " + now);
}
else {
// we've gone past whenToEndSample so reset timers
whenToStartSample = now + (SAMPLE_INTERVAL_SECS * 1000);
whenToEndSample = whenToStartSample + (SAMPLE_DURATION_SECS * 1000) ;
}
}
};
#Override
public void onDestroy(){
super.onDestroy();
mSensorManager.unregisterListener(mSensorListener);
}
}