Some Chinese Android manufacturers make use of custom power-saving restrictions that inhibit sending push notifications to your users while your app is in the background, swiped away from recent apps, or after a device restart.
Chinese market devices from the following manufacturers include custom power-saving restrictions:
- Xiaomi
- Huawei
- OnePlus
- Samsung
- Oppo
- Vivo
- Asus
- Sony
- Honor
First, please ensure you aren't observing this behavior when running your app from within Android Studio. When you run your app from within Android Studio, and you later terminate it by swiping it away from the recent apps, it will no longer receive notifications until reopened (more info).
In order to receive notifications in the background on these devices, there are several options:
1) If the affected devices are not within mainland China, we recommend implementing FCM high priority fallback delivery. This is proven to work around several of these manufacturers' custom power saving mechanisms (Xiaomi, OnePlus, and more), by having Pushy deliver your notifications through MQTT and Firebase Cloud Messaging's high-priority channel simultaneously, while only waking up your app once.
2) If you can't make use of FCM high-priority fallback delivery for your use case, exempting your app from Android's power saving optimizations will make it possible to receive notifications during Doze mode:
a) If your app will be distributed through Google Play, consider asking your users to disable battery optimizations for your app by displaying an in-app dialog with instructions and firing the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
activity (completely safe and will not get your app suspended from Google Play):
The code for displaying this dialog is as follows:
// Android M (6) and up only
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Get power manager instance
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
// Check if app isn't already whitelisted from battery optimizations
if (!powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
// Instruct user to whitelist app from battery optimizations
new AlertDialog.Builder(this)
.setTitle("Disable battery optimizations")
.setMessage("To receive notifications in the background, please set \"Battery\" to \"Unrestricted\" in the next screen.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// Open settings screen for this app
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
// Set package to current package
intent.setData(Uri.fromParts("package", getPackageName(), null));
// Start settings activity
startActivity(intent);
}
})
.setNegativeButton("Cancel", null).show();
}
}
Note: To whitelist your app from battery optimizations manually, you can long press your app launcher icon -> App Info -> Battery -> Set to "Unrestricted".
b) If you're not distributing your app through Google Play, you can make it possible for your users to exempt your app from battery optimizations without leaving your app:
First, declare the following permission in yourAndroidManifest.xml
:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Next, call the following from one of your activities to display an in-app dialog to the user which will allow them to whitelist your app from battery optimizations without leaving your app:
// Get instance of Power Manager
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
// Android M (6) and up only
// Check if the user has not already whitelisted your app from battery optimizations
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
// Display an in-app dialog which will allow the user to exempt your app without leaving it
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse("package:"+getPackageName())));
}
Note: Please do not use the above solution if you are distributing your app through Google Play, as it will most likely lead to app suspension.
3) Consider implementing our foreground service functionality. The Pushy Android SDK will create a foreground service that the Android OS will never terminate, which will ensure that Chinese power saving restrictions will not terminate your app. In turn, a fully customizable notification will be displayed in the notification bar. It is possible to instruct your users to easily hide the ongoing notification. More details are available here.
Implementing one of the above solutions will make it possible for your users to receive notifications in real time on Chinese manufacturer devices with custom power saving modes.