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");
}
};
}
Related
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();
}
}
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);
}
};
}
I have to create an app for sending programmed messages, if I create a single service for a single message is all ok, but if I create messages how do I handle the deletion of a specific service? also after the stop of the first service if i try to create other service crash all... i use a timer for my service
public class service extends Service
{
private static Timer timer = new Timer();
int i=1;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags,int startId){
Toast.makeText(getApplicationContext(), "service start", Toast.LENGTH_SHORT).show();
timer.scheduleAtFixedRate(new mainTask(), 0, 20*1000);
return service.START_NOT_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
Toast.makeText(getApplicationContext(), "distrutta", Toast.LENGTH_SHORT).show();
Log.i("PROVA SERVICE", "Distruzione Service");
}
private class mainTask extends TimerTask
{
public void run()
{
toastHandler.sendEmptyMessage(0);
}
} private final Handler toastHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
if (i==1)
{
Toast.makeText(getApplicationContext(), "test1", Toast.LENGTH_SHORT).show();
i++;}
else
{
i=0;
Toast.makeText(getApplicationContext(), "fine", Toast.LENGTH_SHORT).show();
stopSelf();
timer.cancel();
}
}
};
service call:
Intent i=(new Intent(this,service.class));
startService(i);
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();
}
}
I am having problems running a timer in a service I have created. The task that the timer calls simply isn't called. I know that the service starts as I have put toasts within it and they are called, but not when they are within the timer. Help appreciated.
service class:
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()
{
Toast.makeText(ctx, "test", Toast.LENGTH_SHORT).show();
}
}
public void onDestroy()
{
super.onDestroy();
Toast.makeText(this, "Service Stopped ...", Toast.LENGTH_SHORT).show();
}
}
Main class:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(RingerSchedule.this, LocalService.class));
}
Android does not allow UI events like Toasts from outside the main thread. The run is getting called, but the Toast is being ignored.
To create the Toast on the UI thread, you can use a Handler and an empty Message like so:
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)
{
Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_SHORT).show();
}
};
}
Thanks, I also needed to cancel the timer ..
public void onDestroy() {
timer.cancel();
Toast.makeText(this, "ServiceTalkGeology stopped.",
Toast.LENGTH_SHORT).show();
super.onDestroy();
}