startForeground fail after upgrade to Android 8.1
After some tinkering for a while with different solutions i found out that one must create a notification channel in Android 8.1 and above.
private fun startForeground() {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("my_service", "My Background Service")
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
From my understanding background services are now displayed as normal notifications that the user then can select to not show by deselecting the notification channel.
Update:
Also don't forget to add the foreground permission as required Android P:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Bad notification for startForeground error in Android
You do not need this line
notificationManager.notify(1,notification.build());
Try to remove it and place startForeground
into onCreate
method
@Override
public void onCreate() {
super.onCreate();
final NotificationCompat.Builder notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setContentTitle("Loading Dictionary")
.setSmallIcon(R.drawable.ic_file_download_black_24dp)
.setOnlyAlertOnce(true)
.setOngoing(true)
.setProgress(countMax,0,false);
final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// notificationManager.notify(1,notification.build()); <-- remove this
startForeground(1,notification.build());
//... other stuff
}
Notice that onStartCommand
method will be called multiple times unlike the onCreate
android.app.RemoteServiceException: Bad notification for startForeground
Issue is happening because you are creating a channel with an ID
but sending the notification in a different ID
:
// Here, you are using the package name as channel ID
NotificationChannel chan = new NotificationChannel(
getApplicationContext().getPackageName(),
"My Foreground Service",
NotificationManager.IMPORTANCE_LOW);
// But here, you are sending notifications to "MyChannelId"
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
this, "MyChannelId");
So, I believe you just need to change Channel ID to MyChannelID
as follows:
NotificationChannel chan = new NotificationChannel(
"MyChannelId",
"My Foreground Service",
NotificationManager.IMPORTANCE_LOW);
startForeground fails with Bad notification for startForeground
Self answer:
It was because of backup content.
In my code, I used SharedPreference to check if the notification channel was created. But BackupManager
saved my SharedPreference even after app was removed, so when the app is reinstalled, notification channel is not created.
I changed AndroidManifest.xml
as shown below and it cleared my SharedPreference. Now it works very well.
<application
android:allowBackup="false"
android:fullBackupOnly="false"
android:fullBackupContent="false"
Bad notification for startForeground error: invalid service notification
Solution:
- Go to Android-Settings > Build
- Turn off code optimization
- Build the solution
- Turn code optimization back on
Worked for me but don't know why
Foreground Notification in service not working in Android 8.1
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFMService";
String CHANNEL_ID = "com.app.app";
NotificationChannel mChannel;
private NotificationManager mManager;
private String title, msg, actionCode;
private int badge = 0;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle data payload of FCM messages.
Log.d(TAG, "FCM Message Id: " + remoteMessage.getMessageId());
Log.d(TAG, "FCM Notification Message: " + remoteMessage.getData() + "...." +
remoteMessage.getFrom());
if (remoteMessage.getData() != null) {
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
//Log.e("JSON_OBJECT", object.toString());
title = object.optString("title","");
actionCode = object.optString("action_code", "");
msg = object.optString("body", "");
if (remoteMessage.getData().containsKey("badge")) {
badge = Integer.parseInt(remoteMessage.getData().get("badge"));
//Log.d("notificationNUmber", ":" + badge);
setBadge(getApplicationContext(), badge);
Prefs.putBoolean(Constant.HAS_BADGE,true);
}
if (!(title.equals("") && msg.equals("") && actionCode.equals(""))) {
createNotification(actionCode, msg, title);
}
else {
//Log.e("Notification", "Invalid Data");
}
}
}
public void createNotification(String action_code, String msg, String title) {
Intent intent = null;
intent = new Intent(this, HomeActivity.class);
intent.putExtra(Constant.ACTION_CODE, action_code);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel androidChannel = new NotificationChannel(CHANNEL_ID,
title, NotificationManager.IMPORTANCE_DEFAULT);
// Sets whether notifications posted to this channel should display notification lights
androidChannel.enableLights(true);
// Sets whether notification posted to this channel should vibrate.
androidChannel.enableVibration(true);
// Sets the notification light color for notifications posted to this channel
androidChannel.setLightColor(Color.GREEN);
// Sets whether notifications posted to this channel appear on the lockscreen or not
androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getManager().createNotificationChannel(androidChannel);
Notification.Builder nb = new Notification.Builder(getApplicationContext(), CHANNEL_ID)
.setContentTitle(title)
.setContentText(msg)
.setTicker(title)
.setShowWhen(true)
.setSmallIcon(R.mipmap.ic_small_notification)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher_round))
.setAutoCancel(true)
.setContentIntent(contentIntent);
getManager().notify(101, nb.build());
} else {
try {
@SuppressLint({"NewApi", "LocalSuppress"}) android.support.v4.app.NotificationCompat.Builder notificationBuilder = new android.support.v4.app.NotificationCompat.Builder(this).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.mipmap.ic_small_notification)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher_round))
.setContentTitle(title)
.setTicker(title)
.setContentText(msg)
.setShowWhen(true)
.setContentIntent(contentIntent)
.setLights(0xFF760193, 300, 1000)
.setAutoCancel(true).setVibrate(new long[]{200, 400});
/*.setSound(Uri.parse("android.resource://"
+ getApplicationContext().getPackageName() + "/" + R.raw.tone));*/
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) System.currentTimeMillis() /* ID of notification */, notificationBuilder.build());
} catch (SecurityException se) {
se.printStackTrace();
}
}
}
private NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
}
Related Topics
Find Distance Between Two Points on Map Using Google Map API V2
Finish All Activities at a Time
This Version of the Application Is Not Configured for Billing Through Google Play
How to Hide Soft Keyboard When Activity Starts
Error Opening Trace File: No Such File or Directory (2)
Android Asynctask Threads Limits
Make Certain Area of Bitmap Transparent on Touch
Android: Customize Application's Menu (E.G Background Color)
Select Multiple Images from Android Gallery
Retrofit 2: Get JSON from Response Body
Intercept Back Button from Soft Keyboard
Datepicker: How to Popup Datepicker When Click on Edittext
Play Audio File from the Assets Directory
Capturing Mobile Phone Traffic on Wireshark
How to Add Apache Http API (Legacy) as Compile-Time Dependency to Build.Grade for Android M
Android: Allow Portrait and Landscape for Tablets, But Force Portrait on Phone
Android Sample Bluetooth Code to Send a Simple String via Bluetooth