I would like to build an android app with a permanent background process. I thought of using a Job, but is there a better class for doing this?
A service may be what you're looking for. These always run in the background, however have many limitations and are often killed by the OS.
If you need your service to (almost) always be alive, it can either be woken up by system intents / notifications, or run as a foreground service (notification is shown to user, but app is almost always active).
From the above link:
Foreground
A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app.
Background
A background service performs an operation that isn't directly noticed by the user. For example, if an app used a service to compact its storage, that would usually be a background service.
As mentioned in comments, IntentService is another option, here's a comparison between it and a normal Service. It will however suffer the same restrictions as a normal background service.
For a more accurate answer, I'd suggest editing your question to include what your service needs to do.
Related
I don't want to use services run in foreground because they uses resources. If I open my app later the alarm triggers. One more point, if I whitelist my app from battery optimization it works well. Any suggestion?
Some devices do not permit applications from running in the background, or from being started by AlarmManager. These applications need to be "whitelisted" or added to a list of apps permitted to do this. Different manufactureres handle this differently. If you are running your app on such a device, you will need to have the app (manually) added to the whitelist or list of protected apps, or list of background apps, or whatever.
I know that it is a real problem with running apps in background for different OEMs, but how can I solve this problem?
My app has a webview integrated from an online radio, everything is ok, but after 5 minutes (in locked screen mode), the player stop playing... I can configure my mobile settings, going to Apps, Special access, Optimize battery usage, search for my app and disable that button, but I win only 10 minutes (15 in total), and the app will stop again...
I found something about services, but I'm a really beginner, I don't understand why should I use a service to run in foreground... I have also a notification icon (+title+message) which is showing on display even if the mobile screen is locked. For my understandings, that means the app is running in foreground and in background. Can't figure out how to solve this.
I'm a beginner, but I want to go with this app in production (Google Play), and I want to be useful, not to be just another app...
I hope somebody will have the patience to respond on my issue. Thank you!
(At least some advice, what should I do...)
You need services to run in the background when your application is not visible to the user. Android automatically kills some apps especially when they are resource intensive. This can also be done by some antivirus software, task cleaners, memory cleaning apps etc.
You need to build your application around these challenges because users will not be required to optimize their settings for your application to run.
This services can be triggered by some android activity lifecycles. When you lock your screen, some life cycle methods like the onPause() and the onStop() could be called in your applications by default. You need to handle these events.
Services
A Service is an application component that can perform long-running operations in the background. It does not provide a user interface. Once started, a service might continue running for some time, even after the user switches to another application. You need to create a service that will perform the tasks you want and periodically update the call back in your application.
E.g. The app may fetch notifications from a remote backend and periodically show them to the user at the notifications panel.
Android activity life cycles
As a user navigates through, out of, and back to your app, the Activity instances in your app transition through different states in their lifecycle. The Activity class provides a number of callbacks that allow the activity to know that a state has changed: that the system is creating, stopping, or resuming an activity, or destroying the process in which the activity resides.
Within the lifecycle callback methods, you can declare how your activity behaves when the user leaves and re-enters the activity.
References
Android Services -> Learn about android services
Activity Life Cycles -> Learn about activity life cycles
Hi I am trying to make a chathead bubble, like the one facebook has, for an app in android studio. I have been able to successfully display the bubble using Overlay and make it a service which continues to run even after the app is closed (not killed). However when I open another app or if I dont use my phone for more than 10 minutes, the chathead bubble disappears, unlike Facebook's bubble. How can I go about making the bubble display on the home screen and other apps for a longer period of time(potentially forever)?
For context, I used https://www.androhub.com/android-floating-widget-like-facebook-messenger-chat-head/ to make the bubble, using a View and a Service.
Thanks in advance
Your app's service will get killed by the android system to save battery. There is no exact and easy way to do that. You have to implement multiple methods to do that.
Use Foreground Service(You may have already doing this but just in case if not.)
Ask for permission to restrict Battery Optimization.
In some devices like Xiaomi and Vivo, you need special permission to always run in the background ask for that.
Ask the user to lock the app in recent tab so it won't get killed by the system.
If you are implementing the service, override onStartCommand() and return START_STICKY as the result. It will tell the system that even if it will want to kill your service due to low memory, it should re-create it as soon as memory will be back to normal.
If you are not sure 1st approach will work - you'll have to use AlarmManager http://developer.android.com/reference/android/app/AlarmManager.html . That is a system service, which will execute actions when you'll tell, for example periodically. That will ensure that if your service will be terminated, or even the whole process will die(for example with force close) - it will be 100% restarted by AlarmManager.
TL;DR: My app is hogging the user's microphone. Can I turn it off automatically whenever another app needs to use the mic?
I have an Android app that has some really cool microphone functionality, similar to Amazon Alexa, that stays on all the time in a background service. The problem is, my app hogs the users' microphone, making it unusable:
However, this is terrible application behavior on my behalf, and I want to do my best to avoid it. Is it possible to be notified when another application requests to use the microphone, so that I can automatically stop my service?
PS: I am using the Pocketsphinx library for continuous background voice recognition.
This is tricky, as I'm not a ware of any API for this. This surely will require system-level APIs to work like an "Ok Google" type of thing.
A viable option would be (from https://stackoverflow.com/a/43623308/603270) to run a Job at regular intervals, checking for foreground apps using android.permission.PACKAGE_USAGE_STATS.
This might suffice. But you could also add things regarding phone calls (how to detect phone call broadcast receiver in android) using android.intent.action.PHONE_STATE or media playback (via Receiver or maybe even MediaPlayer directly).
If you're really wanting to get this thing working, an alternative would be to get an array list of all installed apps on the system and which ones require permission to use the mic or not, then use an accessibility service to monitor the users screen if an app the user just opened requires the mic (which you'll know from the array you just grabbed). From there, disable the mic in your app if their app needs the mic. The background service can then check in intervals of, say, two minutes, to see if the app that required the mic is still open. This is really inefficient. But if you don't care, then this might be a good option.
There is no standard way to inform another app that you want access to the microphone (so that they release the resources and let you access it). You could however send a broadcast to all other apps ("requesting the microphone"), but the other apps would have to implement this feature (and very few or zero developers will do this).
I would recommend you to simply inform the user that the microphone is currently not available, because you can't do anything else.
I'm attempting to add a MediaBrowserService for Android Auto to an existing media-player app. The app has a single activity which manages the MediaSession, Callbacks and related state. It has been set up so that it emits events, which the background MediaBrowserService consumes and uses to build its content tree.
This all works fine when the flow is like:
Start my app -> Start Android Auto -> Browse media
However, it falls flat on its face when the flow is:
Start Android Auto -> Browse media
...as in, when the app is not started and running in the background prior to when Android Auto is launched.
The problem appears to be that although my MediaBrowserService will be automatically launched by Android Auto, it does not create a corresponding instance of my app's Activity when it does so (which means no events to inform the MediaBrowserService, and consequently no content available in Android Auto).
Ideally it seems like the MediaBrowserService needs to be able to check and see if the app's "main" Activity is running, and spawn a new instance if/when it is not. But not sure if that's possible, and it tends to feel like it's the wrong approach to take here.
What's the correct way to work around this issue? I don't want to replicate all of the app's MediaSession handling and playback-related code in the MediaBrowserService implementation. That should be kept as lightweight as possible. Is there a way to ensure that the app's Activity is always running whenever the MediaBrowserService is active?
The answer to this was refactoring. Lots and lots of refactoring.
In a nutshell, Android expects Activities to be used to fill a particular architectural niche. Specifically, the niche where you're displaying an interface to the user via the device's screen. Other use-cases, such as having a 'headless' Activity running in the background, appear to be neither expected nor supported.
Thus the answer was to take all of the app's playback-related code out of the Activity, move it into a background Service, and provide an API for passing on the relevant commands (and receiving data, state updates and so on) either from/to the foreground Activity (if/when the user is interacting with the app's UI) or from/to the MediaBrowserService (if/when the user is interacting through Android Auto's UI). Starting the service is something that can be easily done from either context, if/when needed.
That appears to be the solution. It certainly can be tedious if you've got a nontrivial existing codebase you're working with. Far better to anticipate this sort of issue, and architect your app accordingly from the start; keep things that aren't directly pertinent to your app's UI outside of your Activity implementation(s).