onStartCommand is calling only once in service android? - android

i have a simple service need to run in background.below is the code for the service.i want to run the code in onStartCommand repeatedly simply for test purpose i displayed toast.but Toast also calling only once
import android.app.IntentService;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
/**
* An {#link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* TODO: Customize class - update intent actions and extra parameters.
*/
public class WiFiCheck extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionFoo(String param1, String param2) {
// TODO: Handle action Foo
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void handleActionBaz(String param1, String param2) {
// TODO: Handle action Baz
throw new UnsupportedOperationException("Not yet implemented");
}
}
but onStartCommand is calling only once getting toast only once.
i used
return START_STICKY;
starting service as below
startService(new Intent(this, WiFiCheck.class));
but still no use.any help

Toast will be twice and more called if you start again service
e.g.
startService(new Intent(this, WiFiCheck.class));
startService(new Intent(this, WiFiCheck.class));
new Intent is an intent which is in onStartCommand(Intent intent

Short answer
Call StartService as much times as you want the toast to show up.
About returning START_STICKY(Why doesn't returning START_STICKY show your toast twice?)
Returning START_STICKY at the end of onStartCommand() method lets your service start again(onStartCommand() is called again) when your service is KILLED(by some reasons like system resource depletion). So there is no relevence between return START_STICKY; and your goal.
Solution to reach your goal
Like the Kalyzunyu's answer, just call StartService() twice to show your toast twice. It does not instantiate your Service twice, but calls your onStartService() twice. So be free to call it again.
Refer here.
Or if you want to show the toast every 10 seconds until it is stopped try this.
public class WiFiCheck extends Service
{
private Thread thread;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
startForeground(1, new Notification());
thread=new Thread(new Runnable(){
#Override
public void run()
{
// TODO: Implement this method
while(true)
{
Toast.makeText(WiFiCheck.this, "Service Started", Toast.LENGTH_LONG).show();
try
{
Thread.sleep((long)10000);
}
catch (InterruptedException e)
{}
}
}
});
thread.start();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionFoo(String param1, String param2) {
// TODO: Handle action Foo
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void handleActionBaz(String param1, String param2) {
// TODO: Handle action Baz
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onDestroy()
{
// TODO: Implement this method
thread.stop();
super.onDestroy();
}
}
This code below is equivalant to above.
In Activity
new Thread(new Runnable()
{
#Override
public void run()
{
while(!isInterrupted()){
startService(new Intent(MainActivity.this, WiFiCheck.class));
Thread.sleep(10000L);
}
}
}).start();
Equivalent code #2:
public class WiFiCheck extends IntentService
{
public WiFiCheck() {
super("WiFiCheck");
}
#Override
protected void onHandleIntent(Intent intent)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
startForeground(1, new Notification());
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
}
To add words, starting a service does not mean it is repeatedly called by the system, but rather it can live longer without UI. Actually its context is continued until you manually call stopSelf() or any component calls stopService() on your service.

YES.., You just have to return START_STICKY as KYHSGeekCode suggested. It was down voted, but it is correct answer. So i up voted it back. Thank you

Related

Android: Run code when application is permanently closed

So I have code that I want called when my application is closed. Not just when it is sent to the background or the surface is destroyed. How do I do this? Is there a method that I can override in a SurfaceView or Activity class?
New Edit - current BackgroundService class:
public class BackgroundService extends Service {
private String savedString;
public void onCreate() {
System.out.println("Service created");
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("start command: ");
savedString = intent.getStringExtra("myString);
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
public void onTaskRemoved(Intent rootIntent) {
System.out.println("the saved string was: " + savedString);
super.onTaskRemoved(rootIntent);
}
public void onDestroy() {
System.out.println("destroyed service");
super.onDestroy();
}
}
Where I then have this in my other class:
Intent serviceIntent = new Intent(activity.getApplicationContext(), BackgroundService.class);
serviceIntent.putExtra("myString", "this is my saved string");
activity.startService(serviceIntent);
you need to add a background service
public class BackgroundServices extends Service
{
#Override
public void onCreate() {
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
then in your activity. where you want to trigger this service
use
startService(new Intent(getBaseContext(), BackgroundServices.class));
in your case it will be call on onDestory function of that activity
Yes when the process is terminated
That is not possible in general. Nothing in your app is called when the process is terminated.
For example when you open the running apps screen, and swipe away the app to stop it from running
That is a task removal. It may result in your process being terminated, and there are many ways in which your process can be terminated that has nothing to do with task removal.
To detect task removal, override onTaskRemoved() in a Service.

Service starts again when I close app

I am feeling strange behaviour with service when i close my app or my app is destoyed. Service starts from beggining means onStartCommand() method calls again. If service runs in background it should not be called again please help me why its happening
This is my service code
package gcmtutorial.androidbegin.com.socket;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
* Created by shuser on 21-07-2016.
*/
public class Services extends Service {
public static boolean status;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public class Hello implements Runnable{
public void run(){
synchronized (this){
int i=0;
while (i<100){
try {
wait(1000);
Log.e("Status:", "value "+i);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
stopSelf();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
status = true;
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Thread thread = new Thread(new Hello());
thread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
status = false;
super.onDestroy();
Log.e("Status:","Service Destroyed");
}
}
This is my MainActivity code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, Services.class);
if (Services.status == true) {
Log.e("Check:","Service is Running");
}else {
Log.e("Check:","Service Will run now");
startService(intent);
}
}
}
Please help me why such thing is happening with service. I get Toast as well Service Started and LogCat also shows value from 0
Per START_STICKY:
if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance;
If you'd like your Service to not automatically restart when your process is destroyed, return START_NOT_STICKY

SyncAdapter process killed when swiped from recents

I am trying to create SyncAdapter running background operation (without foreground notification).
It is working, except the case when activity (task) which triggered ContentResolver.requestSync(...) is swiped away from recent applications. In that case process is killed and onPerformSync(...) is not finished.
I know, this is expected Android behavior, but in regular Service I would set
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_REDELIVER_INTENT;
}
or maybe use
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
restartSynchronization();
}
to retry synchronization, but this is not working in the SyncAdapterService.
How can I ensure synchronization continues/retry after activity is swiped away from recent applications?
Thank you in advance.
After some reseach I found out, that onTaskRemoved(...) is called only when startService(...) is called and not when someone only binds to it.
So I did work around by starting service in onBind(...) and stopping it and its process in onUnbind(...) methods.
This is final code:
public class SyncAdapterService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static MySyncAdapter sSyncAdapter = null;
#Override
public void onCreate() {
super.onCreate();
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new MySyncAdapter(getApplicationContext());
}
}
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
/*
* Rescheduling sync due to running one is killed on removing from recent applications.
*/
SyncHelper.requestSyncNow(this);
}
#Override
public IBinder onBind(Intent intent) {
/*
* Start service to watch {#link #onTaskRemoved(Intent)}
*/
startService(new Intent(this, SyncAdapterService.class));
return sSyncAdapter.getSyncAdapterBinder();
}
#Override
public boolean onUnbind(Intent intent) {
/*
* No more need watch task removes.
*/
stopSelf();
/*
* Stops current process, it's not necessarily required. Assumes sync process is different
* application one. (<service android:process=":sync" /> for example).
*/
Process.killProcess(Process.myPid());
return super.onUnbind(intent);
}
}

Run Android services Until App Destroyed

Actually i have to perform some technique in which some particular method will be called after specified time until app destroyed.I Google it and have found services.Using services this work can be performed.I have gone through many Service tutorials so now i can work with services but can anybody tell me how to do this. Should i use services for call particular tack in the background of the activity after specified time?...Thanks....
Edit: I have used following code
public class MyService extends Service {
int count = 0;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
handler.removeCallbacks(updateTimeTask);
handler.postDelayed(updateTimeTask, 1000);
Toast.makeText(this, "Service started................",
Toast.LENGTH_SHORT).show();
}
private Runnable updateTimeTask = new Runnable() {
public void run() {
if (count == 50) {
count = 0;
Tocken_parser tocken = new Tocken_parser();
tocken.tockenParser("1");
Toast.makeText(MyService.this, "coutn===", Toast.LENGTH_SHORT)
.show();
System.out.println("Count ===============");
}
count++;
handler.postDelayed(this, 1000);
}
};
private Handler handler = new Handler();
#Override
public void onDestroy() {
super.onDestroy();
System.out
.println("Service destroyed........................................");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Its working properly but tell me one thing, how to stop services when activity destroyed.
The answer is YES. Also, the Service that spawned by Activity will be destroyed together; unless, you assign a schedule check on Alarm to wake up your dead Service.

Stop service doesn't work on android

I'm a student new to android, and I have an application which use background service.
I want to start/stop the service by clicking on a button, i'm doing it like this:
case R.id.enablepop:
if (!(pop.runningFlag))
startService(new Intent(mainScreen,PopUpService.class));
return true;
case R.id.disablepop:
if (pop.runningFlag)
stopService(new Intent(mainScreen,PopUpService.class));
return true;
In the onStart() function of the service I have runningFlag which I set to "true", then I create a thread that works while runningFlag is true.
I set the runningFlag to false on onDestroy().
The problem is that the service won't stop. Can someone help me plz?
Try to use Handler, like here you can use Handler like Thread.
here is the example
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
public class MyService extends Service{
private Handler handler;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
handler.post(updateStatus);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updateStatus);
handler = null;
}
#Override
public boolean onUnbind(Intent intent) {
handler.removeCallbacks(updateStatus);
handler = null;
return super.onUnbind(intent);
}
private Runnable updateStatus = new Runnable() {
#Override
public void run() {
// do something here
handler.postDelayed(updateStatus, 1000);
}
};
}
here the handler can was initialized into the oncreate method now after that when onStart method invoked then the updateStatus object will invoked through the handler.post() which will start the run method of this Runnable object.
Now in this, this will invoked the run() at once and execute the statement at once only so for repeating this task call inside this method on specific delay time like here 1000 milliseconds so after complete all the execution it will again call after 1 sec and repeating this task this will continue until you cannot remove the runnable object from the handler, so basically that was call into the onDestroy()

Categories

Resources