Stop All Started Services on App Close / Exit - android

Is it possible to stop all started services when the user hits the Home Button?
I use:
startService(new Intent(ClassName.this, ClassName2.class));
stopService(new Intent(ClassName.this, ClassName2.class));
This means I will have to somehow add the 'stopService()' for 7+ of my app classes
I've researched this topic and I think there's 'onTerminate' but still not sure how this should be implemented.
Any help or hints would be appreciated!
Thanks!

Is it possible to stop all started
services when the user hits the Home
Button?
Not directly. For starters, you have no way of knowing they pressed HOME.
If you only want the service running while activities are using it, consider getting rid of startService(). Instead, use bindService() in the onStart() methods of the activities that need the service, and call unbindService() in their corresponding onStop() methods. You can use BIND_AUTO_CREATE to have the service be lazy-started when needed, and Android will automatically stop the service after all connections have been unbound.

If you want services to stop when the user leaves your app, I would ask if you want to use services at all. You may just be making your application way more complicated than it needs to be.
Also, this line is really questionable:
startService(new Intent(ClassName.this, ClassName2.class));
You are making an Intent whose action is the class name of one class, and data URI is the class name of another class...! Maybe you mean something like "new Intent(context, MyService.class)"?

Related

Is there anyway to create a background process service that will run whether or not the app created it is still running?

So, I want my app to create a Service that will initially run in the background and do some stuff. This background process will never stop. It will constantly keep running. The ONLY way the background process can be created or destroyed would be through the app. I understand that there are endless possibilities to kill a process. I guess I want my app to be able to tell me whether or not the process is running and retrieve real time information from that process. Along with that, be able to start and/or destroy the background process.
So, let's say that you were to open the app and start/create the service. Even when you close/terminal/call onDestroy for the app, I still want the background process to be running. The only way to destroy this service would be to re-open/re-create the app, and destroy it.
Does Android allow something like this? Is there a way to get around this?
I was going to create a IntentService and make it run an infinite loop. Though, my only problem is how to obtain information from the IntentService. From what I've learned, an IntentService is created and kills itself when it's done.
I'm still new to Android, so don't hesitate to be specific and/or remedial.
Answer is quite simple.
Create a Service (not IntentService, just a simple Service) and start it from your activity. IntentService will not work in your case as it will call stopSelf() on itself as soon as you return from onHandleIntent()
Your service will continue to run till somebody explicitly calls stop method on it or service itself calls stopSelf() method. But in low memory conditions, platform can kill your background services. When device has enough memory platform will restart your service provided you make your service STICKY by returning START_STICKY in onStartCommand().
call stopService() from your activity when required. It doesn't matter even if your activity got stopped/killed and restarted.
You dont really require to launch your service in another process. Because platform will make sure to start and keep your application process alive as long as any of its entities (Activities, Services, Receivers) are alive. Dont worry, your application will not appear in running apps list if your process is running but none of its activities are alive.
Hope this answers your question.
You dont need to make 2 apps for that, in fact, if your requirement is to only be able to stop/create the service from the main app it will only overcomplicate things (such as that you dont need aidl at all since its all in the same app) , that goes for the above answer (cant reply yet!).
Just create the app and the service class even on the same package as the other activities. Then on the manifest xml register the service like this at the application node:
<service
android:name="com.example.yourpackage.Service"
android:process=":remote">
<intent-filter>
<action
android:name="com.example.yourpackage.Service" />
</intent-filter>
</service>
What you are doing with the android:process=":remote" tag is explicitly setting the service to run in a different process (by the name of 'remote') than the rest of the app while still being part of it.
Then, to start and stop it simply use these from your activity:
startService(new Intent(this, Service.class));
·
·
·
stopService(new Intent(this, Service.class));
Make sure you read the documentation about services (and broadcastreceivers) anyway, but that will give you a general idea as to where to aim and what NOT to do to overcomplicate.
I've been working with services lately so im fresh on the matter, if you have any questions let me know here!
<<<<<<<<<<<< EDIT : >>>>>>>>>>>>>>>
Ah I think I get you now.. if you dont want the service to keep running after the "app" is finished just forget about the :remote part. That way they will both share same app lifecycle (but not context lifecycle as they have different ones), sorry if that part confused you and thanks for the vote!.
Just make 2 apps. one a service and one an app. (since the service & the app run on the 'UI' thread).. That way you have two separate processes. Use aidl to communicate between the two.. Would not use intent service, those are supposed to be short lived.
The solution the user SupressWarnings gave you is correct, except that you will be forcing the Service to run in a separate process, and I don't think you will be interested in that. It will only help you in keeping your service running even after the main process dies (probably because of an unhandled Exception), but the fact is that the main process should never die if you have a service running. And the problem with having your service in a separate VM process is that you will lose the ability to use the same memory space, so singletons, statics variables, etc., won't work as expected. And additionally every call from the main process to the service process will be serialized through the binder mechanism which incurs in speed penalties and limits the serialized data to not go beyond 1MB (which could happen if you pass a big byte array for example).
So my opinion is that you should use the SupressWarnings solution without the android:process attribute.
I ran into the same problem and I fixed it by calling startForeground() within my onStartCommand() of a regular Service, not IntentService. I recommend you make the switch to a regular Service as mentioned above.
Here is my code. Call this method in your onStartCommand():
final int id = 1234;
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
//Build the notification
Notification.Builder builder = new Notification.Builder(getBaseContext());
builder.setContentIntent(pendIntent);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setTicker("message");
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(false);
builder.setContentTitle("Test Service");
builder.setContentText("message");
Notification notification = builder.build();
//start foreground service
startForeground(id, notification);

How to make sure Service gets called from a specific activity

In android how to make sure that the service that I have in the application will get called only through an activity that is within the app.
(In other words I want to limit the service to get played by only a certain activity & not even by other activities within that app)
I tried studying Intent-filters but got a bit confused.
Can someone please suggest, if possible with an example?
Thank You
Use Context.startService(Intent service) to start the service from your activity.
Despite the name it doesnt only start the service. If the service is running already, it just calls it.
From the service perspective, the service will then call its onStartCommand(...) method.
Only an activity within the same application can call/start a service this way.
If you set exported="false" in your <service .. /> element of AndroidManifest.xml, the service cannot be called by activities outside your own app.
I know of no way to limit access to any particular activity within the app, but this seems a less pressing concern. Supposedly you can trust your own code?

Service sharing

I have a service which provides current location of the device. Several activities in my app can call this service at the same time. If I call stopService() in an activity, can it make the service running in different activity stop? I have read Android document but still confused about that. Please make it clear for me. Thanks.
There is only one instance of the service. You can call startService() from multiple activities, but it will have only one instance. As soon as any of the activities calls stopService() it will be stopped for all activities.

How can I programmatically close an application?

I am looking for code for a button that completely closes my app.
I tried with some stuff from Google, but my app is still running in the background. I need to close it completely. Is there code that does this?
Why do you need to really close your app? Assuming it's just a normal app and not running any background services or holding a wakelock (you'd know if you were doing those things), the system does a very good job of task management and will end your app if it's backgrounded and it needs the RAM without any manual intervention. Normally if you just finish() your base Activity this will happen on its own, but there's almost never a reason to do that.
(The only exception to this is if your Application is somehow holding onto references to already-finished Activities, which can cause ugly memory leaks and keep your app from closing normally, but you'd also probably know if you're doing anything fishy with an overridden Application subclass.)
That is: 99% of the time if you want to forcibly close your Application, you either need to fix whatever bug in your code makes you think the system can't handle it on it's own, or you need to reread the documentation on the Android application lifecycle again (because you should have already read this 3 times before you started writing an Android app :)).
Maybe this link will help developer page
I quoted the part below that i think might help you.
Shutting down components
A content provider is active only
while it's responding to a request
from a ContentResolver. And a
broadcast receiver is active only
while it's responding to a broadcast
message. So there's no need to
explicitly shut down these components.
Activities, on the other hand, provide
the user interface. They're in a
long-running conversation with the
user and may remain active, even when
idle, as long as the conversation
continues. Similarly, services may
also remain running for a long time.
So Android has methods to shut down
activities and services in an orderly
way:
An activity can be shut down by calling its finish() method. One
activity can shut down another
activity (one it started with
startActivityForResult()) by calling
finishActivity().
A service can be stopped by calling its stopSelf() method, or by
calling Context.stopService().
Components might also be shut down by
the system when they are no longer
being used or when Android must
reclaim memory for more active
components. A later section, Component
Lifecycles, discusses this possibility
and its ramifications in more detail.
You can close all activities from background and when re-open the app It starts from first activity
this.finish();
Intent intent = new Intent(getApplicationContext(), CloseApp.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
You can close all activities from background and when re-open the app It starts from paused activity[where you closed] activity
this.finish();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Android doesn't like you closing your apps.
Here's a discussion on that:
Is quitting an application frowned upon?
If you really want to do it, for whatever reason, you need to close all your activities.
Here's a discussion on how you could do it:
Closing several android activities simultaneously
have in mind that:
finish();
method closes current Activity only.
If you have multiple Activities opened, you should call finish() per Activity.
Note: Closing Service is different.

How can you tell if any Activity in your application is foregrounded?

I've got an Android app which has a periodic background Service. I want this Service to react differently depending on whether any Activities in my application are open. The issue is that the Service just keeps itself running via the AlarmManager making it on kind of on a separate "track" from the Activities, so I don't know whether the application is open when it runs.
The best solution I can think of is to flip a boolean on/off whenever onResume() or onPause() is called in all my Activities, but this seems like a lot of footwork. Is there a simpler, more elegant solution?
Is there a simpler, more elegant
solution?
Well, it depends a bit on what "react differently" means.
Let's suppose you want to raise a Notification if your activities are not in the foreground, but you want to pop a dialog if an activity is in the foreground.
In that case, you need some communication path from the service to the activity anyway. So, register a callback (supplied by the activity) with the service in onResume() and unregister it in onPause(). Your service uses the callback if one exists; if there is no callback, it raises the Notification.
You could accomplish the same thing with a broadcast Intent (register/unregister the receiver in the activity in onResume()/onPause()) if you wanted.

Categories

Resources