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.
Related
my goal is show an activity in every where(even lock screen) on a specific time.
i could in previous android versions until Oreo do this work , but after Oreo Google change the methods, "if you want to display a view on lockScreen use "Activity.this.setShowWhenLocked(true);" :Google says. then i have to create an activity and only use a service wasn't enough.
My Solution : i use AlarmManger to run a service in background on a specific time, that service start my activity(my goal).
Problem : in previous versions android until Oreo , i don't have problem. app works fine . even that time i close my app from recent app , or phone locked. but in Oreo and newer when app works when it is in foreground.
point : in my intent i use this flag :FLAG_ACTIVITY_NEW_TASK
question : how to run a specific activity from a background service even when app is close or phone locked, in Oreo and newer version?
You can't achieve this desired result using background service instead you must consider Foreground service for this task. Here you can find further details about Foreground Services in Android. docs reference
Hope this will help you.
Pardon, but the question here is how to run an activity or a task even when the app is closed. Foreground service will exist as long as the user is interacting with the app or there is a persistent notification showing the task progress, this isn't a case here.
I'd strongly recommend you to go for the workmanager to perform background task. There is a brilliant codelab on the same here :
https://codelabs.developers.google.com/codelabs/android-workmanager/#0
and read the docs here :
https://developer.android.com/topic/libraries/architecture/workmanager
in addition that works i done previous, i understood MIUI in Xiaomi prevent from displaying pop-up window that comes from back ground , then i got its permission and solved problem, now i can see my view anywhere i want. here is a brief for whom that want :
Permissins :
1.Overlay window
2.pop-up window from background(in Xiaomi and probably Other Chinese Phone UI)
Levels :
set a alarm from Activity with Calendar & PendingIntent in AlarmManger to run my Service in a specific time
when i computed my values in Service then Intent to ActivityViewer, in this step i add FLAG_ACTIVITY_NEW_TASK to my intent(according to google docs in android Pie you have to add this flag to your intent for this usage).
In my ActivityViewer according to google docs , I use Activity.setWhenLock() method to show my view even in lock screen and use TYPE_APPLICATION_OVERLAY for Oreo and newer , and use TYPE_TOAST for version 6 until Oreo , and use TYPE_SYSTEM_ERROR for before 6 , in setLayoutParams for setType.
I use this code for getting pop-up window from background permissin in Xiaomi :
Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
intent.setClassName("com.miui.securitycenter",
"com.miui.permcenter.permissions.PermissionsEditorActivity");
intent.putExtra("extra_pkgname", getPackageName());
startActivity(intent);
Starting with Oreo, Android forbidden use of implicit broadcast receivers in Manifest and adviced to register receiver at runtime and or use JobSchedule instead. There is a list of some exceptions as well, however I cannot find an acceptable answer to my situation.
I have a service which runs in the background only when the phone is in CAR mode, up till now I use this to determine when the device entered/exited the car mode and started/stopped the service accordingly:
<intent-filter>
<action android:name="android.app.action.ENTER_CAR_MODE"/>
<action android:name="android.app.action.EXIT_CAR_MODE" />
</intent-filter>
I had a look in the JobSchedule builder but I cannot find anything which relates to CAR, only to charging, network type, and other irrelevant stuff for my case.
How I'm supposed to tackle this?
Any ideas please?
Based on your needs
A service which starts when the device goes into car mode and ends when he leaves it without having the user watching at your application (so without opened activities)
is probably the type of things Google wanted to avoid with the new API 26 restrictions to prevent battery drains. Entering and exiting the car mode should produce only a change of the UI if the user is watching your app while doing this.
You could create a JobScheduler and run it at X minutes interval to check for the actual device condition with UiModeManager#getCurrentModeType() and start a foreground service if the condition is met, but this is a lot far from your current behaviour and the user will be notified of this by a fixed notification.
Alarm is working fine when I am working with the emulator. But not working when i try on actual devices.
Output when app is open.
RTC #8: Alarm{2c1fc9e type 1 when 1486492260454 user.com.hlthee}
tag=*alarm*:user.com.hlthee/.UpdateTables
type=1 whenElapsed=+22h43m2s644ms when=2017-02-08 00:01:00
window=-1 repeatInterval=86400000 count=0
operation=PendingIntent{7c4e37f: PendingIntentRecord{3f5fbf4c user.com.hlthee broadcastIntent}}
But when I closed the app then this entry removed.Why?? That's why Alarm is not ringing.
Alarm receiver broadcaster manifest file.
<receiver android:name=".UpdateTables"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Please don't say use service and register the receiver there. I think I am registering the receiver in manifest it will works. And also alarm in working fine in emulator. Not able to solve this issue from last 3 days. Any helps will be helpfull.
I have tried these method also:
using wakefullBroadcastReceiver instead of BroadcastReceiver
use setAlarmclock instead of setExact.
Anyone also facing the same problem.
If you are working on the MI device then you have to do some settings.
Go to Security/Permission/AutoStart/
Then select your app and enable it.
Hope it will work.
Your problem is not properly explained, if your are setting an alarm manager with that intent and your app is forced stopped set : FLAG_INCLUDE_STOPPED_PACKAGES as flag in your intent...
If set, this intent will always match any components in packages that are currently stopped. This is the default behavior when FLAG_EXCLUDE_STOPPED_PACKAGES is not set. If both of these flags are set, this one wins (it allows overriding of exclude for places where the framework may automatically set the exclude flag).
If your problem is you're not receiving the BOOT_COMPLETED this is what i suggest:
First: in your project properties, under the Manifest Tab, there is a checkbox list for choosing the permissions you want to provide, one of which is RECEIVE_BOOT_COMPLETED. Check that to provide these permissions.
Second: if your app installed on external storage(SD card), you will never receive Boot Complete action. So you have to specify android:installLocation="internalOnly" in the manifest tag.
Third : since version Android 3.1+ you don't receive BOOT_COMPLETE if user never started your app at least once or user "force closed" application. This was done to prevent malware automatically register service. This security hole was closed in newer versions of Android.
Fourth : open an adb shell on your device and force the event like this to test :
am broadcast -a android.intent.action.BOOT_COMPLETED
Do implement onTaskRemoved and onDestroy
#Override
public void onTaskRemoved(Intent rootIntent) {
//Set what to do when task is removed
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
//What to do when service i destroyed
super.onDestroy();
}
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 am working on an application where I am using Google Push Notification. Application receives notification when it is running in Xiaomi phone otherwise when it's killed it does not receive notification.
If we want to receive notification if application is killed then we need to allow auto restart app manually from security app of xiaomi. I want any trick to do this programmatically without asking user. Is there any way to do this ?
http://en.miui.com/thread-33826-1-1.html
There are five settings that needs to be done manually in case of xiaomi to properly run any application. I have done a lot of research on this and there's no way to fix these settings programmatically. These are the settings:
Auto Start -> ON (Toggle and restart your app)
MIUI Optimization under Developer Options -> OFF
Memory Optimization under Developer Options -> LOW/OFF
No restrictions on background activities under Battery & Performance Settings
Battery Saver -> OFF
There are many other devices in which the manual settings needs to be done in order for the app to work as expected e.g. Lenovo, some Micromax devices. Companies impose these kind on restrictions on background activities to improve the overall battery life. Some apps like facebook and whatsapp work correctly as these might have been included as system apps.
After MIUI 6 & 7:
MIUI power saving mode is default set to "Standard" (Background access to the location services and the network will be restricted)
Where to set:
Settings -> Additional settings -> Battery & performance -> Manage apps battery usage -> Power Saving Modes -> Set to Off (MIUI won't restrict background activities)
As for my understanding once you clear apps or clear memory in Recent Apps menu, xiaomi (or MIUI rom) will force close all the services and memory related to that app similar to user going to settings and force stopping app ,
This Link talks about the same issue, hence all the Broadcast receivers and Services will be ended unless started by the user again, so the notification wont be received,
However you can try just enabling auto-start for your app permissions in settings and If it still doesn't work try creating service that restarts by itself and enable auto-start in the settings,
AutoStart is very important in MIUI, untill its enabled all the notification or app activity will be force closed and will never start
I faced a similar issue and fixed it by adding a BOOT_COMPLETED receiver to my app.
Add following to manifest :
<receiver
android:name=".receivers.BootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Then create your BootReceiver class
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Intent startServiceIntent = new Intent(context, FBTokenService.class);
context.startService(startServiceIntent);
Intent notificationServiceIntent = new Intent(context, FBNotificationService.class);
context.startService(notificationServiceIntent);
}
}
}
It should work with this.