java.lang.NoSuchMethodError: No virtual method startForeground

java.lang.NoSuchMethodError: No virtual method startForeground

我正在尝试启动前台服务,但收到 NoSuchMethodError。它说没有找到 startForeground,但看起来它存在。我确实拥有清单文件中声明的服务和 android.permission.FOREGROUND_SERVICE 权限。

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);
    }
}

并收到此错误:

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)

驱动服务:

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;
    }
}

您选择的 startForeground() 重载仅在 API 29 中添加。您的设备可能来自更早的 API 级别。

解决方案:如果 Build.VERSION.SDK_INT 小于 Build.VERSION_CODES.Q,则使用 startForeground(int, Notification)

我不知道这是怎么通过你的 lint 的。

问题出在 startForeground(getId(), getNotification(), getServiceType()); 方法(3 个参数)上。将其更改为 startForeground(getId(), getNotification())(2 个参数)后一切正常;