Why does an app throw android.app.RemoteServiceException without android:icon?

Viewed 196

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?

0 Answers
Related