Error when starting a service in BroadcastReceiver - android

I am having a situation where I get this error when I am trying to start a service from a receiver when app is closed or runs in the background.
But the docs clearly state:
The state of your BroadcastReceiver (whether it is running or not)
affects the state of its containing process, which can in turn affect
its likelihood of being killed by the system. For example, when a
process executes a receiver (that is, currently running the code in
its onReceive() method), it is considered to be a foreground process.
The system keeps the process running except under cases of extreme
memory pressure.
In other words when the app is in the foreground therefore it can theoretically start a service.
So whats the problem here?
#Override
public void onReceive(Context context, Intent intent) {
// assumes WordService is a registered service
context.startService(new Intent(context, HelloService.class));
}
Error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.testapp, PID: 26026
java.lang.RuntimeException: Unable to start receiver com.example.testapp.MyReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.example.testapp/.HelloService }: app is in background uid UidRecord{bee03a7 u0a82 RCVR bg:+1m19s133ms idle change:uncached procs:1 seq(0,0,0)}
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3194)
at android.app.ActivityThread.-wrap17(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
at android.os.Handler.dispatchMessage(Handler.java:106)

The more relevant documentation for your situation is in the Android 8.0 release notes.
The system distinguishes between foreground and background apps. (The definition of background for purposes of service limitations is distinct from the definition used by memory management; an app might be in the background as pertains to memory management, but in the foreground as pertains to its ability to launch services.) An app is considered to be in the foreground if any of the following is true:
It has a visible activity, whether the activity is started or paused.
It has a foreground service.
Another foreground app is connected to the app, either by binding to one of its services or by making use of one of its content providers. For example, the app is in the foreground if another app binds to its:
IME
Wallpaper service
Notification listener
Voice or text service
If none of those conditions is true, the app is considered to be in the background.
(emphasis added)
So, from the standpoint of starting a background service, a BroadcastReceiver is not in the foreground.

Related

Can I keep one foreground service running to prevent other background service being killed in android

From google doc it said:
The system distinguishes between foreground and background apps. An app is
considered to be in the foreground if any of the following is true:
1.It has a visible activity, whether the activity is started or paused.
2.It has a foreground service.
And it also said:
While an app is in the foreground, it can create and run both foreground and background services freely
So, say I start a foreground service when user started the app (it can always has the notification displayed and this is fun) and keep it running until user force quit the app. Then will my intentservice that try to fetch some data in the background get killed if the app entered background?
PS. the foreground service will not doing anything, it's just there to prevent other background service getting killed. (cause call startservice() will get IllegalArgumentException in the background after API 26)
Will this work?

Keep Android service running even after Activity is closed

I am building one of those SOS apps. Whenever the device is shaken above a threshold value (detected through accelerometer), I am showing a Toast (as of now)
1) App is launched. User gives name, email, etc.. and clicks finish on last screen.
2) Service is started which keeps listening for shake.
3) It detects the shake correctly if the App is running.
4) If I close the app (the activity), the service gets killed along with it.
How do I keep the service running even if app is closed, so that it can listen to shakes from background? (That's the whole purpose of this app)
[1.I am returning START_STICKY in onStartCommand
I also tried using a BroadcasterReciever which will restart service by receiving broadcast from onTaskRemoved
I am testing on ASUS Xenfone Max, Marshmallow OS
]
You have two options:
Start your service as foreground service (with startForeground(int id, Notification notification): docs. But in this case you will have to show Notification in notification tray for as long as your service is running
Use separate process for your service adding in manifest to your process android:process=":nameofyourprocess"
Try starting a service without binding it to the activity (Simple unbound service). Return null on your onBind() function. Sticky services attach itself to a activity and has a lifetime as long as the attachment survives. You might have a constant notification related to your application when you use foreground services.
You can put a Service in foreground, in which case it will always be considered as active (and it will therefore have its own notification, so the user knows that an active Service is running). It won't be stopped until it goes back to background. That is what you want in your case, as you want your Service to stay alive as long as possible. As described in the Android Service documentation:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.
The idea is the same for Activities and Services, actually: when Android needs memory, it starts killing processes. The foreground processes (e.g. the Activity that is displayed on the screen, or foreground services) have a higher priority than the ones that are in background (say, a paused Activity), so they will be the last ones to be stopped by the system.
Using START_STICKY just tells the system that if it has to kill your Service, then you'd like it to restart it can. That doesn't say this Service is higher priority than the others.

Which one is better launching service in normal way(startService()) or by using startForeground()

I am launching a service in my app.Currently I am starting my service in my activity in a simple way:
Intent i=new Intent(this,WindowService.class);
startService(i);
It works fine in most of the devices,But in some devices like lenovo and some devices when I remove my app from recent tasks the service also gets killed with activity.So I found that startForeground() method will solve this issue.Is it true that startForeground() method allows my service run even if the application is removed from recent tasks.
Yes its true, startForeground() started a foregrounded service with notification which show the user that the service still running. This is because a foregrounded service consumes a heavier amount of resources and is subject to different scheduling constraints (i.e., it doesn't get killed as quickly) than background services.
the common used its for playing music, download files and etc.
From Service Docs
A started service can use the startForeground(int, Notification) API
to put the service in a foreground state, where the system considers
it to be something the user is actively aware of and thus not a
candidate for killing when low on memory. (It is still theoretically
possible for the service to be killed under extreme memory pressure
from the current foreground application, but in practice this should
not be a concern.)
so from the docs it seems the system will not kill the foreground service

Stop routine Service start from bringing an existing background process to foreground

I have an app with a service that polls at set intervals using the AlarmManager, and when the main app activity is active on screen. The issue I have is, if the app's process is in the background (has not been killed) and the service begins to poll, it brings the main app activity to the foreground.
How do I stop this from happening? Essentially, I want all of the app's processes to remain in the background, unless the user chooses otherwise.
Thanks
The issue I have is, if the app's process is in the background (has not been killed) and the service begins to poll, it brings the main app activity to the foreground.
Then you are calling startActivity(), or possibly startForeground() (I'm not aware that startForeground() would push an existing task to the foreground, but I haven't tried it and cannot rule it out).

Stop android app from closing

I'm using the BroadcastReceiver to receive SMS messages with my app, and then edit a database based on what the message says. The app works fine when it's open, but If I leave it on for a long period of time and it automatically closes the app will force close when it receives a message (I think the BroadcastReciever is still working, but the rest of the app has closed). IS there any way to keep the app from closing, or resuming it when it receives a text message?
Thanks
If you want the receiver to be persistent you should consider using a Service instead of a standard Activity for your application. BroadcastReceivers that exist in a standard activity are considered to be a foreground service only when processing onReceive as soon as the execution returns the Activity resumes its normal process priority and can be terminated by the system as needed.
From: BroadcastReceiver
Process Lifecycle
A process that is currently executing a BroadcastReceiver (that is, currently running the code in its onReceive(Context, Intent) method) is considered to be a foreground process and will be kept running by the system except under cases of extreme memory pressure.
Once you return from onReceive(), the BroadcastReceiver is no longer active, and its hosting process is only as important as any other application components that are running in it. This is especially important because if that process was only hosting the BroadcastReceiver (a common case for applications that the user has never or not recently interacted with), then upon returning from onReceive() the system will consider its process to be empty and aggressively kill it so that resources are available for other more important processes.
This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the containing process active for the entire time of your operation.
For more information on creating a service:
Developer Guides
For a detailed discussion about how to create services, read the Services developer guide.

Categories

Resources