how can i stop my RECEIVE_BOOT_COMPLETED service - android

seeing many questions about this but im unable to fix this.
I have this code
public class myBroadcastReceiver extends BroadcastReceiver {
private final String TAG = "myBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Consts.ANDROID_INTENT_ACTION_BOOT_COMPLEATE)){
Intent newinIntent = new Intent(context, ServiceBootCompleated.class);
context.startService(newinIntent);
}
}
}
It starts a Service and i can debug it using this line
android.os.Debug.waitForDebugger();
I see that return START_NOT_STICKY; is executed but still
the service is visible as a "running" service in the
Setttings>programs>Running Services
the onDestroy() is never called unless i stop it manually.
What do i have to do to stop it,
remove it from "Setttings>programs>Running Services " window?

Once you have completed the work you wanted to do in the background call stopSelf()
Be sure that any real work you do in the Service is done as a background thread and not in onCreate or onStartCommand.
See http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle for more details on the Service Lifecycle.
Example:
public int onStartCommand(final Intent intent, final int flags, final int startId)
{
Thread thread = new Thread(new Runnable()
{
#Override
public void run()
{
//do work
stopSelf();
}
},"MyWorkerThread");
thread.start();
return Service.START_NOT_STICKY;
}

on completion of task, you have to do context.stopService() for stopping this type of unbound service.
Regards,
SSuman185

Related

How to dismiss progress dialog from service?

I have an activity and it shows progress dialog when the user starts download
And the download from ftp start in a service
I want to dismiss this progress dialog when the service finishes downloading file
How to dismiss it from service?
A better approach would be to use LocalBroadcastManager for notifying Activity from Service.
Step1: Send the local broadcast from your service
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// do your operation here(create worker thread for blocking operations)
sendLocalBroadCast() //call this method as soon as above operations completes
return Service.START_NOT_STICKY;
}
}
private void sendLocalBroadCast() {
Intent intent = new Intent("MY_SERVICE_NOTIFICATION");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Note that the system calls onStartCommand(Intent intent, int flags, int startId) on your service's main thread. A
service's main thread is the same thread where UI operations take
place for Activities running in the same process. You should always
avoid stalling the main thread's event loop. When doing long-running
operations, network calls, or heavy disk I/O, you should kick off a
new thread, or use AsyncTask
Step2: Make your Activity listen to this broadcast
public class MyActivity extends Activity{
BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// you can dismiss your progress dialog here. This method will be called when we receive broadcast from service after the service operation is completed
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
//register for listening to "MY_SERVICE_NOTIFICATION" event
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
new IntentFilter("MY_SERVICE_NOTIFICATION"));
}
#Override
protected void onDestroy() {
super.onDestroy();
// remove the receiver
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
}
}
Create an interface finishListener which has listen method, implement it in the activity to do whatever you want and pass it to the service constructor from there call listen method
Its simple
alertdialog.dismiss();
just put that in the bottom of your install code

Background Service not working on 7+ android version

I want to show local notification in an Android app that i am working. notification are based on network transaction completed in background.
I have tried service, intent service, jobservice etc but nothing is working when the app is closed.please share some working code for the reference.....
//Here is my service----
public class JobSyncFAQ extends Service {
private Message msg;
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
public JobSyncFAQ() {
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// here is my stuff
stopSelf(msg.arg1);
}
}
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("JobSyncFAQ", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mServiceHandler.removeCallbacks(mServiceLooper.getThread());
mServiceLooper.quit();
Intent intent = new Intent(getApplicationContext(),JobSyncFAQ.class);
sendBroadcast(intent);
}
//and in my receiver
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, JobSyncFAQ.class));
}
please note - i am facing this issue only for N+ version
When you "close" your app (i. e. you swipe it away on the recent apps screen), you don't actually close the app, you only close the underlying activity. In most cases, this corresponds to the app being closed, but if you have a background service running, the service is not terminated. This is for a good reason: YOu still want to receive WhatsApp messages, even when WhatsApp is closed. Hence, WhatsApp starts a background service to check for new messages, even when the app is closed.
For that reason, you need to notify your background service about the fact that it should cancel its task.
I developed a media application that uses a MediaBrowserService which is connected to a MediaController. Therefore, I can do the following in my activities onDestroyMethod:
MediaControllerCompat mediaControllerCompat = MediaControllerCompat.getMediaController(getActivity());
if (mediaControllerCompat != null)
mediaControllerCompat.getTransportControls().stop();
This tells the MediaBrowserService to stop and quit.
Edit: Since you use a generic service, you need to call stopService:
stopService(new Intent(MyActivity.this, JobSyncFAQ.class));

Android: make call service thread-safe

I have a loop which do call to service:
context.startService(intent);
In and want to get back the result after the service finish its processing for each request. So I pass an unique id to intent to be able to distinguish the response.
But unfortunately, the startService which call to onStartCommand is not thread-safe. This leads to the response is always the last id, as the intent was changed in later call.
The service code is similar:
public class MyService extends Service {
protected Bundle rcvExtras;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
rcvExtras = intent.getExtras();
// Todo with information in rcv Extra
BaseRestClient restClient = new BaseRestClient(rcvExtras.getString(Constants.INTENT_KEY_OBJECT_TYPE));
restClient.post(data, rcvExtras.getString(Constants.INTENT_KEY_URL), new CallBackHandler(this)); // This is an async call
return super.onStartCommand(intent, flags, startId);
}
private class CallBackHandler extends Handler {
private final WeakReference<MyService> myServiceRef;
public CallBackHandler(MyService myService) {
myServiceRef = new WeakReference<>(myService);
}
#Override
public void handleMessage(Message msg) {
Intent result = new Intent(Constants.WS_CALL_BACK);
rcvExtras.putInt(Constants.INTENT_KEY_STATUS, msg.what);
result.putExtras(rcvExtras);
log.info("Broadcast data");
sendBroadcast(result); // Broadcast result, actually the caller will get this broadcast message.
MyService myService = myServiceRef.get();
log.info("Stopping service");
myService.stopSelf(startId);
}
}
}
How can I make service calling thread-safe?
I can see your problem, this is programatic issue not caused by framework. Here from you call startService until you call stopself, your MyService is singleton, and your rcvExtras is a global variable and will be shared between threads.
It is simple to fix:
Move the declaration of rcvExtras to method scope, here is onStartCommand.
Extend the CallBackHandler to allow your rcvExtras, and use it once callback.
At this time you do not have any varable can be shared, and you safe.
Hope this help.

Service stops when deploying android app (disapears from settings>>application>>RunningServices)

This is my situation: I have a service running and every time I deploy my app the service disappears from settings>>application>>runningService (therefore, the service is not running) how can I set it so that the service does not disappears?
I have tried to startForeground but it did not worked.
AndroidManifest:
<service
android:name=".service.PhoneCallInOutService"
android:enabled="true"
android:exported="false" >
</service>
This is how I start the service in my Activity:
chkCallsRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean isChecked = chkCallsRecord.isChecked();
updateBackgroundTasks(isChecked);
}
});
The method actually starting the service:
private void updateBackgroundTasks(boolean start) {
Intent serviceIntent = new Intent(getApplicationContext(),PhoneCallInOutService.class);
if (start) {
getApplicationContext().startService(serviceIntent);
} else {
getApplicationContext().stopService(serviceIntent);
}
}
And here is the service:
public class PhoneCallInOutService extends Service {
private TelephonyManager telephonyMgr;
private PhoneCallStateListener pcsListener;
private OutgoingCallReceiver ocReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Listener
pcsListener = new PhoneCallStateListener(getApplicationContext(),appDto);
telephonyMgr = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_CALL_STATE);
// Receiver
ocReceiver = new OutgoingCallReceiver(getApplication());
IntentFilter intentF = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
getApplicationContext().registerReceiver(ocReceiver, intentF);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Listener
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_NONE);
// Receiver
getApplicationContext().unregisterReceiver(ocReceiver);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Thank you very much in advance.
If by deploy you mean you try to launch new build of your app, then this is actually normal and expected behaviour. By deploying new build you replace old code (incl. service code) therefore it have to be killed first to avoid any crashes and other oddities. So your old iteration of app is completely killed. Then new app is installed and most often auto-launched. Your data create by the app usually stay, but it's also normal.
EDIT
For security reasons you are not allowed to re-launch itself after being updated. User has to to this. As for "he/she may assume the service is still there running, which is not true", use notification of type "On Going" to indicate running service

How can we prevent a Service from being killed by OS?

I am using Service in my application and it needs to run until my application is uninstalled, but the problem is it gets killed by OS.
How can we prevent it from being killed by OS? Or if it gets killed can we restart that service again through programmatically?
You may run the service in the foreground using startForeground().
A foreground service is a service that's considered to be something
the user is actively aware of and thus not a candidate for the system
to kill when low on memory.
But bear in mind that a foreground service must provide a notification for the status bar (read here), and that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
Note: This still does not absolutely guarantee that the service won't be killed under extremely low memory conditions. It only makes it less likely to be killed.
I've been puzzled by the same issue to yours recently.but now,I've found a good solution.
First of all,you should know that, even your service was killed by OS, the onCreate method of your service would be invoked by OS in a short while.So you can do someting with the onCreate method like this:
#Override
public void onCreate() {
Log.d(LOGTAG, "NotificationService.onCreate()...");
//start this service from another class
ServiceManager.startService();
}
#Override
public void onStart(Intent intent, int startId) {
Log.d(LOGTAG, "onStart()...");
//some code of your service starting,such as establish a connection,create a TimerTask or something else
}
the content of "ServiceManager.startService()" is:
public static void startService() {
Log.i(LOGTAG, "ServiceManager.startSerivce()...");
Intent intent = new Intent(NotificationService.class.getName());
context.startService(intent);
}
However, this solution is just available for the situation of your service being killed by GC.Sometimes our service might be killed by user with Programme Manager.In this situation,your prosses will be killed,and your service will never been re-instantiated.So your service can not be restarted.
But the good news is,when the PM kill your service,it will call your onDestroy method.So we can do something with that method.
#Override
public void onDestroy() {
Intent in = new Intent();
in.setAction("YouWillNeverKillMe");
sendBroadcast(in);
Log.d(LOGTAG, "onDestroy()...");
}
The string of "YouWillNeverKillMe" is a custom action.
The most important thing of this method is,don't add any code before send the broadcast.As system will not wait for completion of onDestroy(),you must send out the broadcast as soon as posible.
Then regist a receiver in manifast.xml:
<receiver android:name=".app.ServiceDestroyReceiver" >
<intent-filter>
<action android:name="YouWillNeverKillMe" >
</action>
</intent-filter>
</receiver>
Finally,create a BroadcastReceiver,and start your service in the onReceive method:
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOGTAG, "ServeiceDestroy onReceive...");
Log.d(LOGTAG, "action:" + intent.getAction());
Log.d(LOGTAG, "ServeiceDestroy auto start service...");
ServiceManager.startService();
}
Hope this will be helpful to you,and excuse my poor written english.
Override method onStartCommand() in your service class and simply return START_STICKY (as suggested by "Its not blank"). That's all you need. If the process that runs your service gets killed (by a low memory condition for example), the Android system will restart it automatically (usually with some delay, like 5 seconds).
Don't use onStart() anymore as suggested in another answer, it's deprecated.
use
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//**Your code **
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
ref Documentation lifecycle of Service.
Edit added method.
As far i know, onDestroy() will be called only when the service is explicitly stopped(Force Stop). But this method won't get called in case the service gets killed by OS/swiping the Recent Apps list. In those cases another event handler named onTaskRemoved(Intent) gets called. This is due to a defect in Android 4.3-4.4 as per the link here. Try using the below code:-
public void onTaskRemoved(Intent intent){
super.onTaskRemoved(intent);
Intent intent=new Intent(this,this.getClass());
startService(intent);
}
I found another solution of the problem which gurantees that your service will be always alive. In my case, this scheme resloves also the problem with FileObserver, which stops work after some period of time.
Use an activity (StartServicesActivity) to start the service (FileObserverService) as Foreground service.
Use BroadcastReceiver class (in example CommonReceiver) to restart your service in some special situations and in case it was killed.
I used this code in my app "Email Pictures Automatically"
https://play.google.com/store/apps/details?id=com.alexpap.EmailPicturesFree
Here is CommonReceiver class.
public class CommonReceiver extends BroadcastReceiver {
public void onReceive(Context paramContext, Intent paramIntent)
{
paramContext.startService(new Intent(paramContext, FileObserverService.class));
}
}
Here is its definition in AndroidManifest.xml just before application closing tag.
<receiver android:name="com.alexpap.services.CommonReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
Start service in StartServicesActivity activity.
Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class);
StartServicesActivity.this.startService(iFileObserver);
Here is onStartCommand() method of the service.
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
/*** Put your code here ***/
startServiceForeground(intent, flags, startId);
return Service.START_STICKY;
}
public int startServiceForeground(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, StartServicesActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("File Observer Service")
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(300, notification);
return START_STICKY;
}
I tested this code using Task Killer app, and each time the service was killed, it was restarted again almost immediately (performs onStartCommand()). It is restarted also each time you turn on the phone and after rebooting.
I use this code in my application, which emails every picture you take with your phone to predefinde list of emails. The sending email and list of receiving emails are set in another activity and are stored in Shared Preferences. I took about 100 pictures in several hours and all they were sent properly to receiving emails.
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, YourService.class));
}
write above code in your service and your service will never stop even user want to destroy it or they want to kill it it will never kill untill your app not get uninstall from your device
You can try to start your service repeatedly, for example every 5 sec.
This way, when your service is running, it will perform onStartCommand() every 5 sec. I tested this scheme and it is very reliable, but unfortunately it increases slightly phone overhead.
Here is the code in your activity where you start the service.
Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class);
PendingIntent pendingIntentFileObserver = PendingIntent.getService(StartServicesActivity.this, 0, iFileObserver, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Date now = new Date();
//start every 5 seconds
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, now.getTime(), 5*1000, pendingIntentFileObserver);
And here is onStartCommand() of the service.
//class variable
public static boolean isStarted = false;
public int onStartCommand(Intent intent, int flags, int startId) {
int res = super.onStartCommand(intent, flags, startId);
//check if your service is already started
if (isStarted){ //yes - do nothing
return Service.START_STICKY;
} else { //no
isStarted = true;
}
/**** the rest of your code ***/
return Service.START_STICKY;
}
First create service in another process, and write broadcaster which runs in recursion in time intervals
protected CountDownTimer rebootService = new CountDownTimer(9000, 9000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
sendBroadcast(reboot);
this.start();
Log.d(TAG, "rebootService sending PREVENT AUTOREBOT broadcast");
}
};
After that register broadcast receiver in main process also with timer recursion that is launched after first broadcast from service arrived
protected static class ServiceAutoRebooter extends BroadcastReceiver {
private static ServiceAutoRebooter instance = null;
private RebootTimer rebootTimer = null;
private static ServiceAutoRebooter getInstance() {
if (instance == null) {
instance = new ServiceAutoRebooter();
}
return instance;
}
public class RebootTimer extends CountDownTimer {
private Context _context;
private Intent _service;
public RebootTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
_context.startService(_service);
this.cancel();
Log.d(TAG, "Service AutoRebooted");
}
}
#Override
public void onReceive(Context context, Intent intent) {
if (rebootTimer == null) {
Log.d(TAG, "rebootTimer == null");
rebootTimer = new RebootTimer(10000, 10000);
rebootTimer._context = context;
Intent service = new Intent(context, SomeService.class);
rebootTimer._service = service;
rebootTimer.start();
} else {
rebootTimer.cancel();
rebootTimer.start();
Log.d(TAG, "rebootTimer is restarted");
}
}
}
Service will be auto-rebooted if time at RebootTimer (main process) expires, which means that "PREVENT AUTOREBOT" broadcast from service hasn't arrived
i found a solution .... late answer but i wanted to answer...
we can send a broadcast in the ondestroy of the service and create a receiver that receives the broadcast and starts the service again.... when it is destroyed by any reasons...
pls try following:
final Messenger mMessenger = new Messenger(new IncomingHandler());
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
default:
super.handleMessage(msg);
}
}
}
#Override
public void onCreate() {
super.onCreate();
makeServiceForeground();
}
#Override
public IBinder onBind(Intent arg0) {
return mMessenger.getBinder();
}
private void makeServiceForeground() {
IActivityManager am = ActivityManagerNative.getDefault();
try {
am.setProcessForeground(onBind(null), android.os.Process.myPid(), true);
} catch (RemoteException e) {
Log.e("", "cant set to foreground" + e.toString());
}
}
also need add in manifest.xml
<uses-permission android:name="android.permission.SET_PROCESS_LIMIT"/>

Categories

Resources