i have a problem in my service, the service is runnig from MainActivity (i am doing test) and extends of service.
i want to use the service from foreground and background (when the app is closed) and i already have my first problem:
my service(have a counter that is displayed by LOG) is restarting when i close the app.
also i want to be able to use the service with the open app and close app, in other words to use both the Service Started and Link Service
public class MyService extends Service {
private Thread backgroundThread;
private boolean isRunning;
public MyService() {
Log.e("MyService","constructor");
}
#Override
public void onCreate() {
super.onCreate();
isRunning = false;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
Log.e("onStartCommand","Servicio Llamado");
if (!this.isRunning) {
Log.e("onStartCommand","hilo iniciandose");
this.backgroundThread = new Thread(myTask);
runTask();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("onDestroy","servicio destuido");
}
private void runTask(){
this.isRunning = true;
this.backgroundThread.start();
}
private Runnable myTask = new Runnable() {
public void run() {
Log.e("myTask","hilo iniciado");
int i = 0;
do{
pauseService();
Log.e("myTask","hilo contador: "+i);
//Toast.makeText(getApplicationContext(),"CONTADOR = "+j, Toast.LENGTH_SHORT).show(); //no working :(
i++;
}while (i<10);
/*
//linea de detencion del servicio
//stopSelf();
isRunning=false;
backgroundThread.interrupt();
//backgroundThread = new Thread(myTask);
*/
Log.e("myTask","hilo cerrado");
}
};
private void pauseService(){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In main Activity
Intent intent = new Intent(MainActivity.this,MyService.class);
intent.putExtra("iteraciones",10);
startService(intent);
why because the service restarts when I close the application and how can I avoid it?
Related
I have searched and found questions similar to the title, but no solution so far.
I have the following service
public class MyService extends Service {
public MyService() {
}
private static final String TAG =
"ServiceExample";
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service onCreate");
}
#Override
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 " + currentId);
}
//stopSelf();
}
};
Thread t = new Thread(r);
t.start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
Log.i(TAG, "Service onDestroy");
super.onDestroy();
//Log.i(TAG, "Service Destroyed");
}
}
And this is called from my activity that has two buttons: One for starting the service and one for stopping it
public class ServiceExampleActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_example);
}
public void buttonClick(View view)
{
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
public void stopClick(View view)
{
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
However this does not work. The service is not stopped.
Strangely the onDestroy function is called but after that the runnable is still running.
How can I stop the service?
=============================================
EDIT: I finally achieved it by the following changes:
In the onDestroy function
#Override
public void onDestroy() {
Log.i(TAG, "Service onDestroy");
// mHandler.removeCallbacks(r);
t.interrupt();
super.onDestroy();
//Log.i(TAG, "Service Destroyed");
}
the thread t had to be a class member (before it was declared inside onStartCommand) and I modified the runnable as this
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) {
return; //HERE to detect if the thread has been interrupted
}
}
}
Log.i(TAG, "Service running " + currentId);
}
stopSelf();//I have to use this otherwise it doesn't stop
}
};
I wonder why normally I have to use stopSelf but when interrupted it is not necessary. I suppose stopSelf just calls onDestroy
Stopping a service just kills the context. The framework does not know about any other Threads you may have started- its your job to kill them in onDestroy(). Save the Thread when you create it. In onDestroy(), interrupt it. And in your thread's runnable, regularly check to see if the Thread is interrupted, and return if so. Do not call Thread.stop(), as it may leave your app in an unsafe state.
Service stop working when turn on /of Wi-Fi many time, when I start service do counter 1,2,3 etc or any thing then turn on /of Wi-Fi many time the service stops working ,I have BroadcastReceiver class doing start service, no exceptions , error appear , only I sent one message to phone to start service..
This is the code inside BroadcastReceiver:
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Intent recorderIntent = new Intent(context, Start2.class);
context.startService(recorderIntent);
}
This My Start2 Service:
public class Start2 extends Service {
private static final String TAG = Start2.class.getSimpleName();
int mStartMode;
#Override
public void onDestroy() {
Log.d(TAG, "Stop Service onDestroy");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
int i = 0 ;
#Override
public void run() {
try{
//do your code here
Log.d(TAG, "Start Service Repeat Time.. " + i);
i++;
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable to call it at regular interval
handler.postDelayed( this, 5000 );
}
}
};
handler.postDelayed(runnable, 1000 );
return null;
}
};
task.execute();
return mStartMode;
}
}
I am creating bound service for socket connection.Which means it is creating a long polling connection and listens my server.If user closes the app in task manager my service is killing i have no problem with this.But when user presses the back button I am calling activity.finish() method for close app.But with this method my service doesn't kill,it is still connected to socket server.
Is this normal ? And Could be this drain the battery ?
My service:
public class SocketService extends Service {
//you need constants to tell servise and activity what you are sending a message for
public static final int REGISTER_CHAT_ACTIVITY = 1;
public static final int MESSAGE_RECEIVED = 2;
final Messenger mMessenger = new Messenger(new IncomingHandler());
Messenger chat;
private Socket socket;
#Override
public void onCreate() {
try {
socket = IO.socket("ip");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
}
}).on("connected", new Emitter.Listener() {
#Override
public void call(Object... args) {
}
}).on("message", new Emitter.Listener() {
#Override
public void call(Object... args) {
try {
chat.send(android.os.Message.obtain(null, MESSAGE_RECEIVED, args[0]));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
//and add all the other on listeners here
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (socket != null) {
socket.disconnect();
socket.connect();
} else {
try {
socket = IO.socket("ip");
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
class IncomingHandler extends Handler {
#Override
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case REGISTER_CHAT_ACTIVITY:
chat = msg.replyTo;
break;
}
}
}
public class LocalBinder extends Binder {
SocketService getService() {
return SocketService.this;
}
}
}
I had something similar a while ago i solved the issue by using shared preferences.(Note: I dont think it's the best answer but it solved my problem)
I saved in preferences a boolean to register when i dont need the service anymore but lost reference of it.
public class YourService extends Service {
private YourService serv;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
serv = this;
Then Somehwere on your code that the service does frequently.
if(!sharedPref.getBoolean("TurnOffService", false)){
serv.stopSelf();
}
Hope it helps.
I start a Service from an activity that gets messages from service and shows in a Dialog. When I click back or Home button, app is killed. And app is not found in the multitasking area. I didn't write any code on onBackPressed(). How may I rectify this issue? Service Code.
public class BleepService extends Service{
String gotAlert;
Context context;
String drAlert=null;
public static boolean status = false;
public static final String TAG = BleepService.class.getSimpleName();
int counter = 0;
static final int UPDATE_INTERVAL = 5000;
private Timer timer = new Timer();
String resServer;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("SERVICE", "COMES TO THE ON STARTCOMMAND");
doRepeat();
//return super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
private void doRepeat() {
Log.i("SERVICE", "COMES TO THE DOREPEAT METHOD");
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
new GetStatus().execute();
}
}, 1000, UPDATE_INTERVAL);
}
class GetStatus extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... params) {
ServiceHandler sh = new ServiceHandler();
resServer = sh.makeServiceCall(Urllist.urlGetPagerStatus, ServiceHandler.GET);
while(resServer.equals("1"))
{
status = true;
resServer = sh.makeServiceCall(Urllist.urlGetMsg, ServiceHandler.GET);
}
return resServer;
}
#Override
protected void onPostExecute(String result) {
Log.i("SERVICE", "COMES TO THE GetStatus AsyncTask Class");
super.onPostExecute(result);
if(!result.equals("0"))
{
Intent i = new Intent("com.bleep.DR_ALERT_MESSAGE");
i.putExtra("msg", result);
sendBroadcast(i);
}else{
Toast.makeText(getApplicationContext(), "No New Message", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onDestroy() {
//timer.cancel();
//super.onDestroy();
/*if (timer != null){
timer.cancel();
}*/
}
}
Make sure your Service returns START_STICKY in its onStartCommand. This way OS will restart it if it ever gets killed.
It is legal for an app to be killed by the Android any time while the app is in the background.
However, OS very rarely kills Services. Are you sure you do not somehow kill it yourself, maybe, due to some bug?
I know there are a lot of questions on this already but it doesn't seem to work, so basically I have a custom Service, the service works fine when the timer inside it expires, and calls the stopservice method. however when I try and stop the service from another activity it doesn't work?
code for custom service:
public class ConnectionService extends Service {
Intent service_intent;
Timer t;
int expiry_time = 0;
int timer_tick_starter = 0;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
t = new Timer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
service_intent = intent;
Log.d("onConnectionService", "onStartCommand");
expiry_time = Integer.parseInt(intent.getStringExtra("expiry"));
//convert the minutes to milliseconds
timer_tick_starter = (expiry_time * 60000);
Log.d("onConnectionService", "Expiry Time (in milliseconds) " + timer_tick_starter);
} catch (Exception e) {
Log.d("onConnectionService", e.getMessage().toString());
}
//timer will only start to run on the expiry_time which will then close the connection
t.schedule(new TimerTask() {
#Override
public void run() {
Log.d("onConnectionService", "inside expiry time");
//close the connection
stopService(service_intent);
}
}, 30000);
return START_NOT_STICKY;
}
#Override
public boolean stopService(Intent name) {
Log.d("onConnectionService", "StopService called");
String message = name.getStringExtra("msg");
//broadcast sender
Intent intent = new Intent();
intent.putExtra("msg", message);
intent.setAction("fi.android.inetkeyapplication.CUSTOM_INTENT");
intent.putExtra("is_selected", UserConnectionState.getInstance().is_selected);
sendBroadcast(intent);
Log.d("onConnectionService", "Service has been killed");
return super.stopService(name);
}
#Override
public void onDestroy() {
Log.d("onConnectionService", "Destroy called");
}
}
here I start the service from onCreate:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.d("onConfigurationActivity", "Service starting ");
// Intent i = new Intent(ConfigurationActivity.this, ConnectionService.class);
Intent i = new Intent(context, ConnectionService.class);
i.putExtra("expiry", "1");
startService(i);
}
});
thread.start();
however later in my app when I try to kill it from the activity in which I start it, it doesn't work:
Button exit_button = (Button) findViewById(R.id.btnExit);
connect_button.setTypeface(roboto_light);
exit_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//do closing call
response_close = "";
//need to close service
//also kill the service
Log.d("onConfigurationActivity", "killing service");
Intent intent = new Intent(context, ConnectionService.class);
intent.putExtra("msg", "You have been disconnected");
stopService(intent);
}
});
I have tried my class - ConfigurationActivity.this (as context) and I have tried (this) at the moment I am using a custom context that I simply get inside onCreate. however nothing seems to work what am I missing?
thanx
ok so apparently stopping the service doesn't stop the timer. so I just called cancel() on timer