On my Android 12 device, the ActivityManager is stopping my foreground service when the device locks. The service's purpose is to get GPS info and do various tracking and specialty geofencing (which cannot be handled by the regular GeoFencing features). I need it to run all the time.
My Activity does:
Context context = getApplicationContext();
Intent intent = new Intent(context, NavService.class); // Build the intent for the Navigation service
if (!isNavServiceRunning())
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
Log.v(LOG_TAG, "startForegroundService(NavService)");
context.startForegroundService(intent);
} else
context.startService(intent);
}
and that Log.v entry does show up.
Then my Service does:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
Notification notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle(getText(R.string.nav_service_title))
.setContentText(getText(R.string.nav_service_message))
.setSmallIcon(R.drawable.logo_no_text_plain_24x24)
.setContentIntent(pendingIntent)
.setTicker(getText(R.string.nav_service_ticker_text))
.setAutoCancel(false)
.setOngoing(true)
.build();
Log.v(LOG_TAG, "startForeground");
startForeground(SERVICE_ID, notification);
}
// Now start the GPS updates. Note: Permissions were requested in main activity.
startGpsUpdates(); // My code to kick off updates.
return START_STICKY;
And that Log.v entry shows up.
I should add my manifest stuff here:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<service android:name=".NavService" android:foregroundServiceType="location" />
But when the phone locks, I get "ActivityManager: Stopping service due to app idle: u0a528 -1m16s853ms com.hubbardsoftware.racetac/.NavService"
Everything works fine up until then. The notification shows up as required. This seems to be per the documentation for long running services.
???
Thanks,
Dave
Related
Good day,
I've built a timer into my Android app that sends a message after a certain time. To do this, I added an AlarmManager with a pending intent. Everything works as it should when I have the app open. It also works in the lock screen. But when I close the app, the pending intent is no longer activated and no message appears at the given time.
This is my Alarm Manager:
Intent notifyIntent = new Intent(getContext(), MyReceiver.class);
alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast
(getContext(), NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//when the alarm gets activated:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
else {
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+delta_time2, pendingIntent);
}
In the IntentService-Class (where the notification is declared and called):
Intent notifyIntent = new Intent(this, BigTextMainActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);
PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
NotificationCompat.Action snoozeAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_alarm_white_48dp,
"Snooze",
snoozePendingIntent)
.build();
Intent dismissIntent = new Intent(this, BigTextIntentService.class);
dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);
PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
NotificationCompat.Action dismissAction =
new NotificationCompat.Action.Builder(
R.drawable.ic_cancel_white_48dp,
"Dismiss",
dismissPendingIntent)
.build();
NotificationCompat.Builder notificationCompatBuilder =
new NotificationCompat.Builder(
getApplicationContext(), notificationChannelId);
GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);
Notification notification = notificationCompatBuilder
.setStyle(bigTextStyle)
.setContentTitle(bigTextStyleReminderAppData.getContentTitle())
.setContentText(bigTextStyleReminderAppData.getContentText())
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(),
R.drawable.ic_alarm_white_48dp))
.setContentIntent(notifyPendingIntent)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setCategory(Notification.CATEGORY_REMINDER)
.setPriority(bigTextStyleReminderAppData.getPriority())
.setVisibility(bigTextStyleReminderAppData.getChannelLockscreenVisibility())
.addAction(snoozeAction)
.addAction(dismissAction)
.build();
//I am not quite shure, if I declared the foregroundservice for the notification at the right place
startForeground(NOTIFICATION_ID, notification);
mNotificationManagerCompat.notify(NOTIFICATION_ID, notification);
Vibrator vibrator = (Vibrator) getApplication().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2 * 1000);
These are my permissions:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Thank you for your help!
(btw if this question is stupid or something it's because I didn't really deal with the topic and just wanted to quickly set off an alarm for my app sorry in advance)
Based on your comments it looks like the alarm is triggering as it should, but your BroadcastReceiver is failing when trying to start your Service. The most likely reason is that your device has additional restrictions on background processing. Some devices, mostly low-end and Chinese manufacture, have restrictions on what apps are allowed to run "in the background". If your app isn't on a "white list" of allowed apps, Android won't allow components of the app to be launched in the background.
See https://developer.android.com/about/versions/oreo/background to read about background Service limitations and see https://stackoverflow.com/a/45482394/769265 as an example of an answer where I discuss the problem of certain manufacturers limiting background processing.
Note:
Since you cannot start a background Service on Android 8 and above (due to the limitations), you can start your Service as a foreground Service, like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent)
} else {
context.startService(intent)
}
I try to launch activity for a broadcastReceiver by using the next code
Intent i = new Intent(context, AlarmNotification.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // This is at least android 10...
NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (mgr.getNotificationChannel(CHANNEL_WHATEVER)==null) {
mgr.createNotificationChannel(new NotificationChannel(CHANNEL_WHATEVER,
"Whatever", NotificationManager.IMPORTANCE_HIGH));
}
mgr.notify(NOTIFY_ID, buildNormal(context, i).build());
}
private NotificationCompat.Builder buildNormal(Context context, Intent intent) {
NotificationCompat.Builder b=
new NotificationCompat.Builder(context, CHANNEL_WHATEVER);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(TEXT)
.setContentText(TEXT)
.setFullScreenIntent(buildPendingIntent(context, intent), true);
return(b);
}
private PendingIntent buildPendingIntent(Context context, Intent intent) {
return(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
In the beginning, everything work's perfectly fine. But if I enter the app settings, turn off the notification channel of CHANNEL_WHATEVER, and then turn it on again. Later when I call NotificationManager.notify it shows the notification in the notification drawer but does not start the activity. If I delete the app and reinstall, it works fine again. Is that a bug of android 10 which I should report on, or there is something I can do about it?
In Android 10 we need to add permission for USE_FULL_SCREEN_INTENT
Permissions changes for fullscreen intents
Apps that target Android 10 or higher and use notifications with fullscreen intents must request the USE_FULL_SCREEN_INTENT permission in their app's manifest file.
This is a normal permission, so the system automatically grants it to the requesting app.
Make sure you have added permission in manifest file
SAMPLE CODE
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nilu.demo">
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Android doesn't grant that the activity is shown even if you use a full screen intent:
On some platforms, the system UI may choose to display a heads-up
notification, instead of launching this intent, while the user is
using the device.
Please go through my article on medium on how to launch activity with full screen intent for OS 10. The article also explains how to display headsup notification and to handle action button clicks.
https://medium.com/#dcostalloyd90/show-incoming-voip-call-notification-and-open-activity-for-android-os-10-5aada2d4c1e4
not sure if this was answered. In addition to Permissions previously mentioned... The only way i found to make this work is to use a "NotificationManager.IMPORTANCE_HIGH" Channel and the Notification.
After setting to HIGH, the fullScreenIntent will be opened if the screen is off. Changing the Channel later seems to require an uninstall and reinstall.
Set up the Notification Channel before sending the Notification as (see also):
private static void createNotificationChannel(Context context) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = **"YOUR CHANNEL"**;
String description = "YOUR CHANNEL DESCRIPTION";
int importance = **NotificationManager.IMPORTANCE_HIGH**;
NotificationChannel channel = new NotificationChannel( "YOUR CHANNEL ID", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
I set both intents, unclear if you have to set both:
createNotificationChannel((context));
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, **"YOUR CHANNEL**");
builder.setContentIntent(pendingIntent);
builder.setFullScreenIntent(pendingIntent,true);
If you want to display your own activity on lock screen you need to enable showOnLockScreen in Manifest
<activity android:name="NewActivity" android:showOnLockScreen="true" />
and set flag showWhenLocked in your activity class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
}
}
Finally create a fullScreenIntent with your activity class and attach it to notification
Intent fullScreenIntent = new Intent(applicationContext, NewActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(applicationContext, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(applicationContext, channel)
.setSmallIcon(R.drawable.ic_small)
.setContentTitle(textTitle)
.setContentText(textContent)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setFullScreenIntent(fullScreenPendingIntent, true)
.setAutoCancel(true);
You should wake up the screen of Android, before showing the notification:
fun asquireWake() {
val mPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val mWakeLock: PowerManager.WakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
"YourApp:Whatever"
)
mWakeLock.acquire()
}
In my case the problem was in the notification id which is used to show the full screen intent notification.
If we have the previous notification with the same notification id, then the full screen intent activity will not be launched instead heads up notification will be shown in the lock screen.
so try using the unique notification id for the full screen intent notification.
For more info about how to setup full screen intent notification:Display time-sensitive notifications
for these who has problems with:
builder.setFullScreenIntent(pendingIntent, true)
please try to use instead:
builder.setContentIntent(pendingIntent)
I have used foreground service but when the app is in bg, it shows task Completed which I dont want. How can I remove it? If this line (.addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)) is removed, the bg service doesn't work. If this code is used: '.setContentIntent(servicePendingIntent)', when I click in the noti, the app doesn't open, noti closed and service stops. How can I solve it? Thanks in advance
private Notification getNotification() {
Intent intent = new Intent(this, LocationUpdatesService.class);
CharSequence text = Utils.getLocationText(mLocation);
// Extra to help us figure out if we arrived in onStartCommand via the notification or not.
intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);
// The PendingIntent that leads to a call to onStartCommand() in this service.
PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, LiveTrack.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
servicePendingIntent)
.setContentIntent(activityPendingIntent)
// .setContentIntent(servicePendingIntent)
.setContentText("App name")
.setContentTitle(Utils.getLocationTitle(this))
.setOngoing(true)
.setPriority(Notification.PRIORITY_HIGH)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(text)
.setWhen(System.currentTimeMillis());
// Set the Channel ID for Android O.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID); // Channel ID
}
return builder.build();
}
private void onNewLocation(Location location) {
mLocation = location;
// Notify anyone listening for broadcasts about the new location.
Intent intent = new Intent(ACTION_BROADCAST);
intent.putExtra(EXTRA_LOCATION, location);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
// Update notification content if running as a foreground service.
if (serviceIsRunningInForeground(this)) {
mNotificationManager.notify(NOTIFICATION_ID, getNotification());
}
}
public boolean serviceIsRunningInForeground(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
Integer.MAX_VALUE)) {
if (getClass().getName().equals(service.service.getClassName())) {
if (service.foreground) {
return true;
}
}
}
return false;
}
If you will look at official document, it says
For user-initiated work that need to run immediately and must execute
to completion, use a foreground service. Using a foreground service
tells the system that the app is doing something important and it
shouldn’t be killed. Foreground services are visible to users via a
non-dismissible notification in the notification tray.
Even in the services document it says
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.
So it seems, there must be non-dismissible notification when you are using foreground services.
by default all the service starts in Background using startService() before oreo version , but in oreo there is some restriction to start a service in background, Can I start a background service in oreo using startService() ?
You can use startService() as long as your app is in foreground , if your app goes background and you call startService() you will get IllegalStateException
Alternatively you can use startForeground() to start a service
From documentation
While an app is in the foreground, it can create and run both foreground and background services freely. When an app goes into the background, it has a window of several minutes in which it is still allowed to create and use services. At the end of that window, the app is considered to be idle. At this time, the system stops the app's background services, just as if the app had called the services' Service.stopSelf() methods
check Documentation for more info
You can run a service in background service. But if you want to run a background operations regardless if the app is in the foreground is not and you're not binding the service to a server then I'd use a foreground service. So in your main call this:
if(Build.VERSION.SDK_INT >25){
startForegroundService(new Intent(this, Service.class));
}else{
startService(new Intent(this, Service.class));
}
Then when you're in your service you have to document that the foreground service is running. You can call this method to handle documenting it in the foreground (it is a little clumsy):
private void startRunningInForeground() {
//if more than or equal to 26
if (Build.VERSION.SDK_INT >= 26) {
//if more than 26
if(Build.VERSION.SDK_INT > 26){
String CHANNEL_ONE_ID = "Package.Service";
String CHANNEL_ONE_NAME = "Screen service";
NotificationChannel notificationChannel = null;
notificationChannel = new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(notificationChannel);
}
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.background_running);
Notification notification = new Notification.Builder(getApplicationContext())
.setChannelId(CHANNEL_ONE_ID)
.setContentTitle("Recording data")
.setContentText("App is running background operations")
.setSmallIcon(R.drawable.background_running)
.setLargeIcon(icon)
.build();
Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
startForeground(101, notification);
}
//if version 26
else{
startForeground(101, updateNotification());
}
}
//if less than version 26
else{
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("App")
.setContentText("App is running background operations")
.setSmallIcon(R.drawable.background_running)
.setOngoing(true).build();
startForeground(101, notification);
}
}
private Notification updateNotification() {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
return new NotificationCompat.Builder(this)
.setContentTitle("Activity log")
.setTicker("Ticker")
.setContentText("app is running background operations")
.setSmallIcon(R.drawable.background_running)
.setContentIntent(pendingIntent)
.setOngoing(true).build();
}
you'll also have to document the presence of a service in the manifest (in between the activity tags):
<service android:name = ".Service"/>
like and comment if you need help making a notification icon
I am trying to start a foreground service. I get notified that the service does start but the notification always gets suppressed. I double checked that the app is allowed to show notifications in the app info on my device. Here is my code:
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("Revel Is Running")
.setTicker("Revel Is Running")
.setContentText("Click to stop")
.setSmallIcon(R.mipmap.ic_launcher)
//.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true).build();
startForeground(Constants.FOREGROUND_SERVICE,
notification);
Log.e(TAG,"notification shown");
}
Here is the only error I see in relation:
06-20 12:26:43.635 895-930/? E/NotificationService: Suppressing notification from the package by user request.
It's because of Android O bg services restrictions.
So now you need to call startForeground() only for services that were started with startForegroundService() and call it in first 5 seconds after service has been started.
Here is the guide - https://developer.android.com/about/versions/oreo/background#services
Like this:
//Start service:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(this, YourService.class));
} else {
startService(new Intent(this, YourService.class));
}
Then create and show notification (with channel as supposed earlier):
private void createAndShowForegroundNotification(Service yourService, int notificationId) {
final NotificationCompat.Builder builder = getNotificationBuilder(yourService,
"com.example.your_app.notification.CHANNEL_ID_FOREGROUND", // Channel id
NotificationManagerCompat.IMPORTANCE_LOW); //Low importance prevent visual appearance for this notification channel on top
builder.setOngoing(true)
.setSmallIcon(R.drawable.small_icon)
.setContentTitle(yourService.getString(R.string.title))
.setContentText(yourService.getString(R.string.content));
Notification notification = builder.build();
yourService.startForeground(notificationId, notification);
if (notificationId != lastShownNotificationId) {
// Cancel previous notification
final NotificationManager nm = (NotificationManager) yourService.getSystemService(Activity.NOTIFICATION_SERVICE);
nm.cancel(lastShownNotificationId);
}
lastShownNotificationId = notificationId;
}
public static NotificationCompat.Builder getNotificationBuilder(Context context, String channelId, int importance) {
NotificationCompat.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
prepareChannel(context, channelId, importance);
builder = new NotificationCompat.Builder(context, channelId);
} else {
builder = new NotificationCompat.Builder(context);
}
return builder;
}
#TargetApi(26)
private static void prepareChannel(Context context, String id, int importance) {
final String appName = context.getString(R.string.app_name);
String description = context.getString(R.string.notifications_channel_description);
final NotificationManager nm = (NotificationManager) context.getSystemService(Activity.NOTIFICATION_SERVICE);
if(nm != null) {
NotificationChannel nChannel = nm.getNotificationChannel(id);
if (nChannel == null) {
nChannel = new NotificationChannel(id, appName, importance);
nChannel.setDescription(description);
nm.createNotificationChannel(nChannel);
}
}
}
Remember that your foreground notification will have the same state as your other notifications even if you'll use different channel ids, so it might be hidden as a group with others. Use different groups to avoid it.
The problem was i am using Android O and it requires more information. Here is the successful code for android O.
mNotifyManager = (NotificationManager) mActivity.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannel(mNotifyManager);
mBuilder = new NotificationCompat.Builder(mActivity, "YOUR_TEXT_HERE").setSmallIcon(android.R.drawable.stat_sys_download).setColor
(ContextCompat.getColor(mActivity, R.color.colorNotification)).setContentTitle(YOUR_TITLE_HERE).setContentText(YOUR_DESCRIPTION_HERE);
mNotifyManager.notify(mFile.getId().hashCode(), mBuilder.build());
#TargetApi(26)
private void createChannel(NotificationManager notificationManager) {
String name = "FileDownload";
String description = "Notifications for download status";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel mChannel = new NotificationChannel(name, name, importance);
mChannel.setDescription(description);
mChannel.enableLights(true);
mChannel.setLightColor(Color.BLUE);
notificationManager.createNotificationChannel(mChannel);
}
For me everything was set correctly (also added FOREGROUND_SERVICE permission to manifest),
but I just needed to uninstall the app and reinstall it.
If none of the above worked you should check if your notification id is 0 ...
SURPRISE!! it cannot be 0.
Many thanks to #Luka Kama for this post
startForeground(0, notification); // Doesn't work...
startForeground(1, notification); // Works!!!
if you are targeting Android 9(Pie) api level 28 and higher than you should give FOREGROUND_SERVICE permission in manifest file.see this link : https://developer.android.com/about/versions/pie/android-9.0-migration#bfa
I can not believe it. In my case, after adding 'android:name=".App"' to AndroidManifest.xml, the notification started showing.
Example:
<application
android:name=".App"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
For Android API level 33+ you need to request POST_NOTIFICATIONS runtime permission. Although this doesn't prevent the foreground service from running, it's still mandatory to notify as we did for < API 33:
Note: Apps don't need to request the POST_NOTIFICATIONS permission in order to launch a foreground service. However, apps must include a notification when they start a foreground service, just as they do on previous versions of Android.
See more in Android Documentation.
In my case, it was caused by me using IntentService.
In short, if you want a foreground service then subclass Service.