Handler is not working at delay time in my background service - android

I have to perform some task continuously in MyService.java class. For this I use Handler but mHandler.postDelayed(this, 40000); is not getting fired after given time. It is getting fired after every second. Please help me out
public class SendMessageService extends Service {
private Handler mHandler = new Handler();
private Runnable task;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerReceiver(stopReceiver, new IntentFilter("com.android.STOP_HANDLER"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
task = new Runnable() {
#Override
public void run() {
dosomething();
mHandler.postDelayed(this, 40000);
}
};
try {
mHandler.postDelayed(task, 40000);
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(stopReceiver);
}
private void dosomething() {
//perform my task
}
private BroadcastReceiver stopReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("receive","STOP");
mHandler.removeCallbacks(task);
}
};
}

I change my code to this and it is working
public class SendMessageService extends Service {
private Handler mHandler = new Handler();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerReceiver(stopReceiver, new IntentFilter("com.android.STOP_HANDLER"));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
mHandler.postDelayed(task, 40000);
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(stopReceiver);
}
private void dosomething() {
//perform my task
}
private BroadcastReceiver stopReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("receive","STOP");
mHandler.removeCallbacks(task);
}
};
private Runnable task = new Runnable() {
#Override
public void run() {
dosomething();
mHandler.postDelayed(this, 40000);
}
};
}

Related

How to manually stop a service?

I have tried to stop my service, even my destroy method also executed but my service is not stopping. I have done my best. Please help me.
my code is mentioned below:
MainActivity
Intent intent=new Intent(this,Myservice.class);
startService(intent); //in start button.
Intent intent=new Intent(this,Myservice.class);
stopService(intent); //in stop button.
Myservice
public class Myservice extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"runing",Toast.LENGTH_LONG).show();
{
myTherad th=new myTherad();
Thread thread=new Thread(th);
thread.start();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
super.onDestroy();
}
class myTherad implements Runnable {
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10;i++)
{
wait(1000);
Log.d("mfnhsdgjkfn","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}
}
I think your service is stopped, but not your Thread. Cancel your Thread as well in onDestroy of your service by introducing for e.g. some kind of state variable:
class myTherad implements Runnable {
// Indicates that the runnable should stop.
private boolean shouldStop = false;
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10 && !shouldStop;i++)
{
wait(1000);
Log.d("mfnhsdgjkfn","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
and declare your runnable as class attribute:
private myTherad runnable;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
runnable=new myTherad();
Thread thread=new Thread(runnable);
thread.start();
return super.onStartCommand(intent, flags, startId);
}
and stop the runnable within your onDestroy:
#Override
public void onDestroy() {
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
runnable.shouldStop = true;
super.onDestroy();
}
At least after the latest wait was executed, your thread should stop. You can optimize that, with an interruption.
We have to inturrpt thread that is running , thread.interrupt() will do that and give java.lang.InterruptedException , Try below code :
public class MyService extends Service {
public MyService() {}
myTherad th;
Thread thread;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"runing",Toast.LENGTH_LONG).show();
{
th=new myTherad();
thread=new Thread(th);
thread.start();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
thread.interrupt();
}
class myTherad implements Runnable {
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10;i++)
{
wait(1000);
Log.d("LOG","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}
}

Run Android Service every 30 seconds

I am creating a Notification using Android Service independent from UI. This works perfectly fine. Below is the code.
public class SendNotificationService extends Service {
Context context;
String test_heading;
String test_body;
final class notifThread implements Runnable {
int service_id;
notifThread(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
checkNewEntry.execute(requested_method, bu_status);
stopSelf(this.service_id);
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new notifThread(startId));
thread.start();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
This service also starts automatically on system boot. CheckNewEntry is my AsyncTask that checks the database and sends notification if there is any change. I have not added CheckNewEntry as it is beyond the scope of this question.
Now what I want to do is, run CheckNewEntry every 30 seconds or 1 minute.
Can anyone help?
After going through different Stackoverflow questions/answers, I managed to come up with my own solution.
Below is the code that I have created and is working now.
public class SendNotificationService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
#Override
public void onCreate() {
handler = new Handler();
runnable = new Runnable() {
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
checkNewEntry.execute(requested_method, bu_status);
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
If anyone of you can provide a better solution, please do post.
you can use handler like this.
public class SendNotificationService extends Service {
Context context;
String test_heading;
String test_body;
public static Runnable runn;
public static Handler hand =new Handler();
final class notifThread implements Runnable {
int service_id;
notifThread(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
String requested_method = "LoadBU";
String bu_status = "1";
CheckNewEntry checkNewEntry = new CheckNewEntry(SendNotificationService.this);
runn = new Runnable() {
#Override
public void run() {
checkNewEntry.execute(requested_method, bu_status);
hand.postDelayed(runn, 30000);
}
};
runn.run();
stopSelf(this.service_id);
}
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new notifThread(startId));
thread.start();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}

continue service working when the application closes

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");
}
};
}

android - how can I stop the thread inside the service?

I have a checked button in my MainActivity. If that button is checked it should start the service but if a user unchecked the button I want to stop the service.
So in uncheck condition I have written this stopService(intentname); but the problem is the service is not stopping. Here is my code snippet:
Service Class
public class SimpleService extends Service
{
String selectedAudioPath = "";
private MyThread myythread;
public Intent intent;
public boolean isRunning = false;
long interval=30000;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
myythread = new MyThread(interval);
}
#Override
public synchronized void onDestroy()
{
super.onDestroy();
if(!isRunning)
{
myythread.interrupt();
myythread.stop();
isRunning = false;
}
}
#Override
public synchronized void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
if(!isRunning)
{
//this.intent = intent;
//System.out.println("the intent is" + intent);
myythread.start();
isRunning = true;
}
}
class MyThread extends Thread
{
long interval;
public MyThread(long interval)
{
this.interval=interval;
}
#Override
public void run()
{
while(isRunning)
{
System.out.println("Service running");
try
{
String myString = intent.getStringExtra("name");
if(myString == null)
Log.d("Service","null");
else
{
Log.d("Service","not null");
if(myString.equalsIgnoreCase("image"))
{
uploadImages();
Thread.sleep(interval);
}
else if(myString.equalsIgnoreCase("audio"))
{
uploadAudio();
Thread.sleep(interval);
}
}
}
catch (InterruptedException e)
{
isRunning = false;
e.printStackTrace();
}
}
}
You can't stop a thread that has a running unstoppable loop like this
while(true)
{
}
To stop that thread, declare a boolean variable and use it in while-loop condition.
public class MyService extends Service {
...
private Thread mythread;
private boolean running;
#Override
public void onDestroy()
{
running = false;
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
running = true;
mythread = new Thread() {
#Override
public void run() {
while(running) {
MY CODE TO RUN;
}
}
};
};
mythread.start();
}
Source: Stopping a thread inside a service
Don't use Threads. Use AsyncTask instead.
public class MyService extends Service {
private AsyncTask<Void,Void,Void> myTask;
#Override
public void onDestroy(){
super.onDestroy();
myTask.cancel(true);
}
#Override
public void onStart(Intent intent, int startid) {
myTask = new AsyncTask<Void,Void,Void>(){
#Override
public void doInBackground(Void aVoid[]){
doYourWorkHere();
}
}
myTask.execute();
}
}

How to display the value in the text field of Activity which is updated from service class?

This is my service class in that i increment the i value based on time...
public class BackService extends Service {
int i=0;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I want to append the i value to the TextView. i.e the TextView value is dynamically change based on i value...
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
TextView tx=(TextView)findViewById(R.id.textView1);
}}
how to append the i value to tx...
Thank you in advance..
You will need to register Broadcast receiver for Sending data back from Service to Activity.see these usefull example for communication between Activity to service :
http://androidexperinz.wordpress.com/2012/02/14/communication-between-service-and-activity-part-1/
http://androidexperinz.wordpress.com/2012/02/21/communication-between-service-and-activity-part-2/
http://blog.philippheckel.com/2012/06/10/android-example-communication-between-activity-and-service-using-messaging/
Use this
public class MainActivity extends Activity {
TextView tx;
RefreshBroadcastReciver mBroadCastReciver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BackService.class));
tx =(TextView)findViewById(R.id.textView1);
}
#Override
protected void onResume() {
super.onResume();
mBroadCastReciver = new RefreshBroadcastReciver();
registerReceiver(mBroadCastReciver, new IntentFilter("sendData"));
}
private class RefreshBroadcastReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
tx.setText(intent.getIntExtra("i", 0)+"");
}
}
#Override
protected void onStop() {
super.onStop();
if(mBroadCastReciver!=null)
unregisterReceiver(mBroadCastReciver);
}
}
and your service is here
public class BackService extends Service {
int i=0;
Intent intent1;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
pollForUpdates();
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
intent1=new Intent("sendData");
}
private void pollForUpdates() {
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("Service class called", "service class called "+i);
getRunningApps();
i++;
Message msg=new Message();
msg.arg1=i;
handler.sendMessage(msg);
}
},0,1000);
}
private void getRunningApps()
{
}
#Override
public void onDestroy() {
super.onDestroy();
}
protected Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
intent1.putExtra("i", msg.arg1);
sendBroadcast(intent1);
}
};
}

Categories

Resources