My app takes up too much RAM. I found that placing the accessibility service in a different process will prevent it from being shut down alongside the app. It also apparently has the added benefit that if the app crashes then the accessibility service won't crash along with it.
I tried just adding android:process=":externalProcess" under the accessibility service in the manifest file but that doesn't work. How do I do it? Also one more question, how do I inform the OS that no matter how much RAM the accessibility service is taking it should never be shut down, i.e. highest priority.
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
Request White-list / optimization enabled your app
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
}
}
If this won't help in your case, try to use this library: https://github.com/iardelian/Revive-S
Related
I read a lot of articles on forums, but wasn't able to make the "unkillable" background service work. I tried disabling the battery optimalization ( didn't work), making the foreground service ( since making app from api 24-31, didn't find solution on how to make it work, maybe the right way to do it), making the broadcast receiver - "restarter". (Of course this isn't all, but it is everything that has something to do with the service)
Manifest:
<service android:name="PathToService" android:foregroundServiceType="dataSync|location" />
<receiver
android:enabled="true"
android:name="PathToReciever"
android:label="RestartServiceWhenStopped">
</receiver>
Receiver:
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, SERVICE));
}
Service:
#Override
public void onDestroy() {
Intent broadcastIntent = new Intent(this, SERVICE);
sendBroadcast(broadcastIntent);
}
incase if your whole problem is that the OS just randomly destroys the service after a while, you could returning START_STICKY in the onStartCommand method in the foreground service
according to Android Developers documentation :
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent unless there are pending intents to start the service. In that case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands but are running indefinitely and waiting for a job.
if that's the case then it gets solved by this code :
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
... \\ whatever your code contains here
return START_STICKY;
}
maybe that's why I'm telling you that I didn't notice that anything is killing my service rather during my tests.
N.B : take care that the lifetime of foreground services is higher than background ones, as since api 28 there's some restrictions on background services that might make it quite unusable for long work assignment that you should consider either switching to foreground services or use long-running-workers.
Foreground service
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.
When you use a foreground service, you must display a notification so that users are actively aware that the service is running. This notification cannot be dismissed unless the service is either stopped or removed from the foreground.
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.
Note: If your app targets API level 26 or higher, the system imposes restrictions on running background services when the app itself isn't in the foreground. In most situations, for example, you shouldn't access location information from the background. Instead, schedule tasks using WorkManager.
you can also check that question and its answer for more clarity
The expected behavior is that the app will be running all the time when it's in ON state. Some phones put the app in background mode when the app is not active for some time. I want the app to be running all the time even its in standby mode(standby mode means when we press the home button the app will go to background. and it will run for some time).
I found following code and I tried that
PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(POWER_SERVICE);
String packageName = "org.traccar.client";
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent i = new Intent();
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
i.setData(Uri.parse("package:" + packageName));
startActivity(i);
}
else{
i.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
i.setData(Uri.parse("package:" + packageName));
startActivity(i);
}
}
Even after working with the code the default state is Battery Saver(recommended)
I want the app in No Restriction mode once the app is opened, any solution for this?
The code you use is for battery optimization. Settings-->Batery-->Three Dots Menu Item (...)--->Battery Optimization-->(Choose an app from list)--->Optimize/ Don't optimize.
By choosing Don't optimize you are essentially bypassing Doze, not app standby.
Also be advised that doing this programmatically as you do may result in Google taking your app off the store. It is safer to do it manually following the path i described above.
More on Doze and App Standby here
I'm using Eclipse's Paho android library. This library internally starts a Service to fetch data. Now when my app is in background and push notification comes, Paho's service works well for pre-oreo devices. But on Oreo device, this work for few minutes duration after app goes to the background state. After this duration, although I'm sending high priority GCM message, service won't starts and gives warning in logcat Background start not allowed. As stated in offical docs, for high priority GCM messages, app becomes whitelisted for few minutes. In this case, it should work for high priority GCM message.
From my understanding app should become whitelisted whenever high priority GCM arrives. Is it correct?
To be ready for Android O:
1) Instead of IntentService; your service needs to extend JobIntentService.
2) Instead of onHandleIntent; you need to use onHandleWork.
3) Instead of startService; you need to use enqueueWork.
Check this out.
https://developer.android.com/reference/android/support/v4/app/JobIntentService.html
When dealing with broadcasts, you need to make sure the intent is explicit.
private static void sendImplicitBroadcast(Context ctxt, Intent i) {
PackageManager pm=ctxt.getPackageManager();
List<ResolveInfo> matches=pm.queryBroadcastReceivers(i, 0);
for (ResolveInfo resolveInfo : matches) {
Intent explicit=new Intent(i);
ComponentName cn=
new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
resolveInfo.activityInfo.name);
explicit.setComponent(cn);
ctxt.sendBroadcast(explicit);
}
}
This was from https://commonsware.com/blog/2017/04/11/android-o-implicit-broadcast-ban.html
Hi i am running a background service using alaram manager its working fine but for some mi devices background service is not working.I used sevices but it is not working how to run my background service in mi ?
MI UI has its own security options, so what you need to is not just above mentioned sticky Service,
you need to
Enable Autostart
go to power setting make changes as per these youtube videos
https://www.youtube.com/watch?v=-Ffgir-QgsU, or refer for this for more suggestions
https://www.quora.com/How-do-I-keep-an-app-running-in-the-background-in-MIUI
then you have created a custom broadcast receiver which will start the service when your service is destroyed
as per this example https://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android
If the 3rd option doesn't work onDestroy recall of the service call the custom broadcast receiver on
w
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.e(TAG, " In recieve Custome Broadcast receiver");
Intent broadcastIntent = new Intent("ac.in.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
}
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.Settings$HighPowerApplicationsActivity"));
startActivity(intent);
try this code
it will open one setting page
then find your app and then tap "Don't Optimize"
it will turn off battery optimization and your background services run without problem
When you start a service by extending an Service class than you will get the call inside OnStartCommand() this method has three types of return type on the basis of this return type operating system itself manage when to start a service.
So suppose if your service gets killed in between due to low memory or any other issue when you return a correct type from onStartCommand() than os will take care of when to start service again.
Three return types are:
START_STICKY : When this is the return type than os takes the guarantee to restart the service again if its get killed it will definitely start you service again even if there is no pending intent it will start the service by passing intent as null.
START_NOT_STICKY: says that, after returning from onStartCreated(), if the process is killed with no remaining start commands to deliver, then the service will be stopped instead of restarted. This makes a lot more sense for services that are intended to only run while executing commands sent to them. For example, a service may be started every 15 minutes from an alarm to poll some network state. If it gets killed while doing that work, it would be best to just let it be stopped and get started the next time the alarm fires.
START_REDELIVER_INTENT is like START_NOT_STICKY, except if the service's process is killed before it calls stopSelf() for a given intent, that intent will be re-delivered to it until it completes (unless after some number of more tries it still can't complete, at which point the system gives up). This is useful for services that are receiving commands of work to do, and want to make sure they do eventually complete the work for each command sent.
This is a known bug.
NotificationListenerService gets killed during app updates and sometimes even randomly and it isn't restarted automatically. Further, it can't even be started manually but we have to prompt the user to reboot the device, since the service only seems to be able to be started on device boot.
The following doesn't work (trying to start the service manually):
startService(new Intent(this, NotificationService.class));
Are there any workarounds for this? I need the service to be constantly running and getting the OnNotificationPosted events.
This might not solve your problem completely but it might help with the service being killed randomly. I had a similar problem with my own app. Although I worked around the problem in another way, I found out about foreground services.
Apparently, Android kills your notification service to save memory and that explains the seemingly random kills.
To work around this, you can use a foreground service that will not be killed by Android and the service will be running at all times. See Running a Service on Foreground.
Do you try setting START_STICKY?
More information about it: https://developer.android.com/reference/android/app/Service.html#START_STICKY
May be my answer can help you too. Please take a look at
https://stackoverflow.com/a/35435065/1554094
Try this code to manually disable & re-enable the service
private void toggleNotificationListenerService() {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(this, your.NotificationListenerServiceImpl.class), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, your.NotificationListenerServiceImpl.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
You can catch the broadcast Intent.ACTION_PACKAGE_CHANGED to know when the service gets disabled.
And you can use this code to check if your notification service is enabled.
private static boolean isNotificationListenerServiceEnabled(Context context) {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
if (packageNames.contains(context.getPackageName())) {
return true;
}
return false;
}
Solved,
Set the notificationListenerServer to be foreground service. Then the service would be alive.
createNotificationChannel();
startForeground(NOTIFICATION_ID, getNotification());