I've made a foreground service to constantly scan for BLE devices around me. For some reason it seems to work flawlessly on my stock android device Google pixel and also on Samsung S9+.
But recently I tested the app with a Chinese ROM(Oneplus 6T, Xiaomi Poco F1) the foreground service seems to be killed there after a few minutes. I've used workmanager to restart service but the app is not restarting and I get a bug report instead for the app.
Also on Chinese ROM devices below android 8.0(Xiaomi redmi 3s prime), simple service wont work, I need to use a foreground service there as well. Is there any solution to solving this?
Ask users to whitelist your app. This is the only solution. Even foreground service + wake lock won't work.
There was a discussion last month: Workmanager reliability for periodic tasks on Chinese roms (Xiaomi, Huawei, and so on). There are some useful links in there but eventually you'll have to let users whitelist your app in every ROM's specific battery optimization(or other name) settings.
A simple approach would be to ask user to put your app in non-optimized apps by opening the battery optimization settings at the starting of your app
Use below code to open the setting:
Intent batterySaverIntent=new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
startActivity(batterySaverIntent);
Or you can try this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startForegroundService(new Intent(this, ServiceClass.class));
}
Related
When I clear my app from recent apps list, my app background service killed. I tried with android nougat and oreo. But it's working in Android 6.0. After searched about the issue. Lot of people navigated the answer to Background Execution Limits.
Any one have solution for this issue?
Android Nougat should not have those issues ideally. I've spend weeks on NotificationListenerService which runs perfectly fine in background in Nougat.
It also works great in Samsung S9 (Android Oreo) but I have some issues in Google devices and emulators.
I've raised a similar issue few weeks back.
Just to make sure, enable background services for your app through console.
Also, specify which service you are using?
try this
#TargetApi(Build.VERSION_CODES.O)
private void moveToStartedState() {
Intent intent = new MyIntentBuilder(this)
.setCommand(Command.START).build();
if (isPreAndroidO()) {
Log.d(TAG, "Running on Android N or lower");
startService(intent);
} else {
Log.d(TAG, "Running on Android O");
startForegroundService(intent);
}
}
Example
https://proandroiddev.com/deep-dive-into-android-services-4830b8c9a09
Simple answer:
Use foreground services instead of background services.
Why?
Because of changes in how latest Android SDKs treat background services and Doze mode.
Good luck :)
I'm here developed a hybrid cordova based android app in which i need to do some task before killing app for this i wrote below code onDestroy() in MainActivity and onTaskRemoved in one of service class which is calling perfectly on Samsum, Motorola, Asus etc. many device except Redmi MI Devices.
Some days back the same code was working in MI device but now its not after updating MI with MIUI 9.6.0 and above. I have tested one of MI device with MI 9.5.0 in which its working both the method but after upgrade of my device now its not working.
So is someone having the same issue? what we can do to achieve app killing event? is there any option through which it should start working or having any other way to do the same only for MI device?
I have checked over the internet and did changes for Autostart options as well still not working.
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.d(getClass().getName(), "App just got removed from Recents!");
Toast.makeText(getApplicationContext(),"18. onTaskRemoved()", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(),"16. onDestroy()", Toast.LENGTH_SHORT).show();
}
Few OEMs including (RedMi) customizes the stack ROM for battery/memory optimization and have blocked the "onDestroy()" and "onTaskRemoved" callbacks.
As an user you can prevent the App's service from killing by locking the App.
Or, White listing the app by enabling "Autostart" setting for the App. Programmatically you can prompt the user to enable the Autostart for the App: Please find details here
Please note: I have tested the Autostart enabling programatically on few devices but found that it does not works always. So not sure how to fix in a proper way, but this solution might worked at-least up-to certain extent.
This question not duplicate of onTaskRemoved() not getting called in HUAWEI and XIOMI devices
Problem:
When I press home button & kill the app onTaskRemoved() (Service class override method) - not called.
If I press back button & kill the app --> onTaskRemoved() called perfectly
This issue happen in Android lollipop versions & oreo versions
MyService.class -> Manifest declaration
<service android:name=".MyService"
android:label="MyService"
android:stopWithTask="false"
android:enabled="true"
android:exported="true"
/>
I already used the return START_STICKY; in onStartCommand()
Tested devices
Lenovo, Samsung - lollipop version
Samsung - oreo version
Any suggestions or comments are welcome. Your small tips will help to fix this huge issue.
Based on your use case, you should be able to meet the criteria for the White listing on Android N and above. You can follow this link to Whitelist your app. By requesting this permission, you can relax some restrictions (like accessing network or holding partial lock) implied by Doze mode and Android O. These restrictions are imposed by OS on the app those are not white-listed.
For Lollipop: Certain manufacturers using cyanogenmod or other custom implementation, could have impact on the intended behavior of START_STICKY. Workaround in this case would be to rely on onDestroy() method of service to:
Restart the service.
Trigger an AlarmManager which will trigger after few seconds and start the service.
If you use approach 2:
On normal devices where the START_STICKY behaves as intended, you can use the AlarmManager to check if service is running by:
Maintain a static variable in service to check if service has been started
Cancel the AlarmManager onStartCommand() of the service.
How do i detect if the app has been killed?
i have found a solution which is call activity on onDestroy
#Override
protected void onDestroy() {
super.onDestroy();
Intent intent = new Intent(this, ConnectionStablizer.class);
startActivity(intent);
// code here
}
it is working fine on galaxy note 3 (4.4.2) but not working on android emulator (android 4.2.2), galaxy y duos (2.3.6) and htc desire (4.0.2)
so i found another solution-
run a background service which detects when app gets destroyed and launch the activity again like this one
i have the exact implementation but it doesn't do anything? where am i wrong? my code is the same as in the link
where am I wrong
You are wrong trying to reopen your app once it's been destroyed. This is a hacky behavior...
Nevertheless, you can achieve your goal by using alarm manager and set an alarm for every second or so, to check if your app is alive if it's not you can bring it back.
Also, pay attention:
Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
I strongly recommend to not use my solution, nor attempting to find one.
If the app is removed from recent apps by user then you can get a notification from OS by overriding onTaskRemoved method in your service and take respective action. In general Android never kills any app unless otherwise in a low memory condition. In such case callbacks will be given to save the state of your application provided you handle all such callbacks.
I have developed a mdm server (mobile device manager) and an android application. I have manage to connect the two devices. In addition, I have wrote an android application ,which can work on any android platform. Now, I am trying to manage android application in a way it can not be closed without permission of me.In other words, android application will run from start of the cell phone until I have send a command to close itself.
I do not manage how I can do that. If you know, can you share your knowlege ?
It is impossible to have never ending applications on Android.
Whenever the system requires more resources for the current foreground task, it will kill background processes to free up RAM and CPU.
However, you could do one of the following:
Return START_STICKY or START_REDELIVER_INTENT using a Service
In your onStartCommand() for your service, return START_STICKY or START_REDELIVER_INTENT
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
Use a push notification service like GCM to trigger your app's launch only when needed
This is a much more battery efficient method, as your app isn't running when it isn't required. By integrating GCM, you have the ability to send push notifications to your app via the Google Services already installed on every Google approved Android device (anything with Google Play on it). When the device receives your notification, it will launch and notify your application on the device, hence starting it.
Not possible, you cannot prevent the User killing your application. (Task killers etc)
But what you can do is create a Service and start/stop it via startService/stopService. And make it STICKY.
Android can kill a Service when it is low on resource, STICKY will make the Service start again.
It is a well known saying that "Prevention is better than cure", By These lines I mean You should try and enclose the suspected instruction with try, catch and Finally blocks.
An Application does not close itself until and unless an unexpected flaw or error has occurred. Therefore make sure You've enclosed the sensitive program instruction, such as connecting, looking up for the devices etc. and apply proper instructions in the finaly block. Your program will work according to your demands. Thanks