I have added Google Now search within my application. The way it works is, the user types something in the EditText object and oonce they press the button, this intent runs -
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
String term = searchInput.getText().toString();
intent.putExtra(SearchManager.QUERY, term);
startActivity(intent);
However I am having issues killing the service after the intent has been launched.
calling finish();after the intent will not work unless I am directing the intent to a different class itself.
Here's a video preview fo what I mean, you can clearly see I am pressing home to close the app but when I reopen it . It opens to the Google Now app. But when pressing back, it stops. How exactly can I get the intent to stop after I press the home key?
And my app is a dialogue type app so I have excluded it from the recent menu because of allot of reasons. Everywhere else the app kills itself as soon as the user exits it but here the service keeps running.
Video - Video Preview
I have also tried many questions answers, have researched but nothing has helped so far. I may be doing something wrong. Could someone kindly help me out here, thank you very much! :)
A started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. So, the service must stop itself by calling stopSelf() or another component can stop it by calling stopService().
use stopSelf() upon compleetion of task assigned to service.
And if you want to finishs ervice when application finishes, then in onDestroy(), call stopService() after checking whether its running or not, such method can be used:
public static boolean isMyServiceRunning(Class<?> serviceClass, Activity pActivity) {
ActivityManager manager = (ActivityManager) pActivity.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
to stop service from activity use below code:
stopService(new Intent(yourMainActivity.this,yourIntentService.class));
or you can write condition in service to stop itself like below:
if(check your condition here)
stopSelf();
You don't have to stop an IntentService - it will terminate itself when it has no more work to do.
It runs on separate worker thread.
Multiple intents are queued on the same worker thread.
So even if your Activity was destroyed from where this service was started it will continue performing its tasks until all the queued ones are complete and after completion it is automatically terminated.
Caution: It's important that your application stops its services when it's done working, to avoid wasting system resources and consuming battery power. If necessary, other components can stop the service by calling stopService(). Even if you enable binding for the service, you must always stop the service yourself if it ever received a call to onStartCommand().
stopService() : Request that a given application service be stopped. If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started.
Note: that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed until all of these bindings are removed.
Related
I am using a service in my app. The service is used to show notifications. I send extras to the service when I start it. The problem is that when I remove the application window from the background the onStartCommand method is called again with a null intent so the extras become not exist. So my question is how can I stop the sticky service? Is it possible or no?
You can stop Stiky service by Calling stopService(intent_of_your_service) at onPause() or onDestroy() of your service.
Here, intent_of_your_service is the Intent you created at onCreate(), or Use stopSelf() (i.e., it stops the service) for stop sticky service.
I noted that when I close my app definitively, the method runInBackGround of the class MultiplyTask stops working. It works when the activity is in the phase STOP or PAUSE, but when I close my app, the method finishes ( it's a loop created with a cycle while(true) {...} ).
How can for example Whatsapp send notifications though it's closed? I want to create a similar thing. Thanks!
When the app is closed, all code will stop running. If you are looking to execute while the app is open and continue executing code while the app is closed, you will want to look into using a Service.
Take a thorough look at the Service documentation and it will hopefully be what you are looking for.
Services are also killed when your app is closed, but using the START_STICKY return value you can make sure your service is restarted upon termination.
EDIT WITH MORE INFORMATION:
<service
android:name="MyService" />
Add the above to your AndroidManifest.xml
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// This is where you would place your code that you want in the background
// Putting your while loop here will make sure it runs when the app is closed
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
Create a new class with the above code.
Intent i= new Intent(context, MyService.class);
startService(i);
Call this code from your launcher Activity to start the service when the app is launched.
Hope this helps!
Asynctask is ideal for short operation which are needed to be performed in the background. Usually Asyntask is implemented as sub class of activity which is destroyed when app is close. Also It communicates with the UI thread at some points ... so It needs the activity to be in memory... For long running operation, Service is better. Some Apps notify user even when they are not running. In fact they have one or more services running in background. You can see those in your phone setting->apps menu.
Study this for more information about services.
Hello I am running a background service to check in my server if there is a new data.
But if I kill the App, the background service also dies.
If I run the background service on it;s on process, the system kill it after it has run a couple times.
Manifest
<service
android:name=".backgroundSerive"
android:enabled="true"
android:exported="false"/>
Option 2
<service
android:name=".backgroundSerive"
android:process=":my_process"
android:enabled="true"
android:exported="false"/>
MainAActivity - Starting the service
Intent i = new Intent(this, backgroundSerive.class );
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(i);
Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...start runnable
return START_STICKY;
}
I try both option, The service keeps getting killed.
Any advice. To make my server always run.
thank you
You need to call startForeground() from within the service, to lower the chance of Android actually killing it. Please check out this sample for an example implementation.
startForeground function sends the service to foreground, so android system considers this operation as a foreground task. Which is very less likely to be killed.
If you have choosen the services destroy action as START_STICKY it would get destroyed but right after it destroyed it should be reinitialized with a null intent.
You may consider using Alarm for such event.
Since alarms are running in an internal process they reduce the app overhead, yet they provide recurring checks.
I am having difficulties trying to handle service behaviour in such case.
Basically I have a service running on a separate process that needs to issue httprequests every certain time whenever the app is closed, then write something into preferences or throw a notification.
The logic works fine. The problem I'm having is that I cannot find a way to properly stop/disable that service whenever the app is running, aswell as start it again when the app is being finished or put into background.
I've tried stopping it at #onResume()/#onStart() callbacks of my activities aswell as starting it at #onStop()/#onDestroy() but behaviour doesnt run as expected in any case...
I'll paste here some code snippets of what i've tried so far:
I start/stop services using:
stopService(new Intent(this,NotificationService.class));
startService(new Intent(this, NotificationService.class));
Random activity from my app (all implement this in their callbacks):
#Override
protected void onResume() {
if (Utility.isMyServiceRunning(this)){
Utility.serviceClose(this);
}
super.onResume();
}
#Override
protected void onStop() {
if (!Utility.isMyServiceRunning(this)){
startService(new Intent(this, NotificationService.class));
}
super.onStop();
}
This somehow doesnt work or brings unexpected behaviour since the app moves from many activities, and service ends up being alive when the app is running or stopped when the app is in background/finished.
I've also tried to toggle on/off service logic on service timertask every cicle by asking:
#Override
public void run() {
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService( ACTIVITY_SERVICE );
List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
for(int i = 0; i < procInfos.size(); i++){
if(procInfos.get(i).processName.equals("com.example.myapp")) {
return;
}
}
//service http request logic here
}
But that doesnt work either because process "com.example.myapp" never gets killed (and of course I cannot/want to force finish that), so it never issues any httprequest.
Any Ideas on how to implement this? Any help would be very welcome.
Thanks in advance.
How about binding to your service and then communicating directly with it? Implement a simple on/off boolean, expose a getter/setter on the binding, and then make sure the service checks the boolean before it does any work. That way you can disable it while the app is running without having to actually start/stop the service repeatedly.
http://developer.android.com/guide/components/bound-services.html
Solved with better handling of onStop() onResume() callbacks.
I am asking a vexed question that has been (partially, to my mind) addressed here and here. Let's say like in many examples we want to create a music application, using (say) a single activity and a service. We want the service to persist when the Activity is stopped or destroyed. This kind of lifecycle suggests a started service:
A service is "started" when an application component (such as an
activity) starts it by calling startService(). Once started, a service
can run in the background indefinitely, even if the component that
started it is destroyed
Ok, but we also want to be able to communicate with the service, so we need a service binding. No problem, we have both a bound and started service as this answer suggests:
At activity startup (or some other point) we call startService()
After that we call bindService() to obtain the IBinder interface, and proceed from there.
So far so good, but a problem arises from the fact that when the activity starts, we do not know if the service is around or not. It may have been started or it may not have been. The answer could be something like:
At startup, try to bind to the service (use bindService() without the BIND_AUTO_CREATE flag)
If that fails, then start the service using startService(), and then bind to it.
This idea is premised on a particular reading of the docs for bindService():
Connect to an application service, creating it if needed.
If zero flag means "service is not really needed" than we are OK. So we try something like this using the following code:
private void connectToService() {
Log.d("MainActivity", "Connecting to service");
// We try to bind to an existing service
Intent bindIntent = new Intent(this, AccelerometerLoggerService.class);
boolean bindResult = bindService(bindIntent, mConnection, 0);
if (bindResult) {
// Service existed, so we just bound to it
Log.d("MainActivity", "Found a pre-existing service and bound to it");
} else {
Log.d("MainActivity", "No pre-existing service starting one");
// Service did not exist so we must start it
Intent startIntent = new Intent(this, AccelerometerLoggerService.class);
ComponentName startResult = startService(startIntent);
if (startResult==null) {
Log.e("MainActivity", "Unable to start our service");
} else {
Log.d("MainActivity", "Started a service will bind");
// Now that the service is started, we can bind to it
bindService(bindIntent, mConnection, 0);
if (!bindResult) {
Log.e("MainActivity", "started a service and then failed to bind to it");
} else {
Log.d("MainActivity", "Successfully bound");
}
}
}
}
And what we get is a successful binding every time:
04-23 05:42:59.125: D/MainActivity(842): Connecting to service
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it
04-23 05:42:59.134: D/MainActivity(842): onCreate
The global question is "Am I misunderstanding bound versus started services and how to use them?" More specific questions are:
Is it the correct understanding of the docs to think that zero flag passed to bindService() means "Do not start the service"? If not, is there no way to call bindService() without starting the service?
Why does bindService() return true even if the service is not running? In this case it doesn't seem like the service has been started, based on Log calls.
If there the previous point is the correct/expected behavior of bindService(), is there a workaround (i.e. somehow ensure that startService is called only if the service is not running?)
P.S. I've moved on from the problem in my own code: I issue startService() calls regardless, since repeated startService() are simply ignored. However, I would still like to understand the issues better.
If you bindService with 0 flag then the service will not start. You can bindService with BIND_AUTO_CREATE flag and if the service is not started, it will be started. However, when you unbindService the service will be destroy.
bindService with 0 flag always returns true.
You can always call startService. If the service is already running then a new service will not be created. The running service onStartCommand will be called.
There should not be any problem if you startService in onCreate and then bindService in onResume and unbindService in onPause.