I am asking this question out of curiosity and hoping it may be useful to anyone who may encounter the same problem.
An app had been working fine for years with a background service to update widgets. I removed android.app from the application tag:
<application
android:name="androidx.multidex.MultiDexApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true"
tools:replace="android:theme, android:label">
The app started to crash a few seconds after its launch every time. Logcat shows the following:
FATAL EXCEPTION: main
Process: net.mydomain.myapp, PID: 15836
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid service notification: Notification(channel=widget_channel pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1737)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The crash stops as soon as I put back android:icon="@mipmap/ic_launcher".
The crash is caused by startForeground(1, notification) in the following code:
public class UpdateWidgetIntentService extends IntentService {
public UpdateWidgetIntentService() {
super("UpdateWidgetIntentService");
}
@Override
public void onCreate() {
super.onCreate();
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String CHANNEL_ID = "widget_channel";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Widget update",
NotificationManager.IMPORTANCE_NONE);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
utility.logWidgetInfo(this, "Notification channel created.");
}
} catch (Exception ex) {
utility.logExceptionAsync(this, "Exception from onCreate():", ex);
}
}
The service is started by OnBootReceiver:
<receiver
android:name=".OnBootReceiver"
android:enabled="true"
android:exported="false"
android:label="Service At Boot Receiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
public class OnBootReceiver extends BroadcastReceiver {
public OnBootReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, UpdateWidgetIntentService.class));
} else {
context.startService(new Intent(context, UpdateWidgetIntentService.class));
}
} catch (Exception ex) {
}
}
}
Could anyone shed some light on this?