java.lang.NoSuchMethodError: No virtual method startForeground

Issue

I’m trying to lauch a foreground service, but receiving NoSuchMethodError. It says that no startForeground found, but it looks like it is present. I do have the service and the android.permission.FOREGROUND_SERVICE permission delared in the manifest file.

public void startForegroundService(Intent intent) {
    Log.d(TAG, "startForegroundService: " + intent);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        getContext().startForegroundService(intent);
    } else {
        getContext().startService(intent);
    }
}

And receiving this error:

java.lang.NoSuchMethodError: No virtual method startForeground(ILandroid/app/Notification;I)V in class Lcom/volnoor/backup/core/sync/BaseForegroundService; or its super classes (declaration of 'com.volnoor.backup.core.sync.BaseForegroundService' appears in /data/app/com.volnoor.backup-aFOxNxXCGe_PmUbYxrrdHw==/base.apk!classes2.dex)
    at com.volnoor.backup.core.sync.BaseForegroundService.onStartCommand(BaseForegroundService.java:27)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3567)
    at android.app.ActivityThread.-wrap20(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1718)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6687)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)

DriveService:

public class DriveService extends BaseForegroundService {

    @Override
    protected int getId() {
        return 1;
    }

    @Override
    protected Notification getNotification() {
        return new NotificationCompat.Builder(this, BackupApplication.CHANNEL_FOREGROUND_SYNC)
                .setContentTitle("TODO Title")
                .setContentText("TODO Text")
                .setSmallIcon(R.drawable.ic_google_drive)
                // TODO .setContentIntent(pendingIntent)
                .build();
    }

    @Override
    protected int getServiceType() {
        return FOREGROUND_SERVICE_TYPE_DATA_SYNC;
    }
}

BaseForegroundService:

public abstract class BaseForegroundService extends Service {

    private static final String TAG = "BaseForegroundService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");

        startForeground(getId(), getNotification(), getServiceType());

        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    protected void stopForegroundService() {
        Log.d(TAG, "stopForegroundService");

        stopForeground(true);
        stopSelf();
    }

    protected abstract int getId();

    protected abstract Notification getNotification();

    protected int getServiceType() {
        return FOREGROUND_SERVICE_TYPE_MANIFEST;
    }
}

Solution

The startForeground() overload you have selected was only added in API 29. Your device is likely from an earlier API level.

Solution: Use startForeground(int, Notification) if Build.VERSION.SDK_INT is less than Build.VERSION_CODES.Q.

I don’t know how this got past your lint.

Answered By – greeble31

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *