java.lang.IllegalStateException:尝试 运行 RingtoneService 时不允许启动服务 Intent

java.lang.IllegalStateException: Not allowed to start service Intent while trying to run RingtoneService

我正在创建一个管理器应用程序,其中包含许多功能,其中一个是闹钟,而在大多数时候尝试为我的闹钟启动 RingtoneService 时,我收到此异常 "java.lang.IllegalStateException: Not allowed to start service Intent" 因为它是 运行 在后台(有时会延迟运行)! 我广泛搜索了答案并尝试了以下方法并且 none 起作用了: - JobScheduler:我得到同样的异常 - bindService() 并在 onServiceConnected() 中编写代码:它永远不会触发 onServiceConnected()

以下是我的代码的重要部分:

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {

        Intent serviceIntent = new Intent(context, RingtonePlayingService.class);
        context.startService(serviceIntent);
    }
}

来自下方 activity 的广播呼叫:

Intent intent = new Intent(AddAlarm.this, AlarmReceiver.class)
                .putExtra("ALARM_ON", true);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

以下服务 class:

public class RingtonePlayingService extends Service {

    // Player
    MediaPlayer player;
    boolean isRunning;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (!isRunning) {

            player = MediaPlayer.create(this, R.raw.ringtone);
            player.start();

            this.isRunning = true;

            showNotification();

        }
        else if (isRunning) {

            player.stop();

            this.isRunning = false;

        }

        return START_STICKY;
    }
}

如果您 运行 您的代码是 Android 8.0,那么这种行为是正常的。基于 documentation,从 Android 8.0 开始,如果您的应用程序不在前台,则无法在后台启动服务。您需要替换以下内容:

Intent serviceIntent = new Intent(context, RingtonePlayingService.class);
context.startService(serviceIntent);

Intent serviceIntent = new Intent(context, RingtonePlayingService.class);
ContextCompat.startForegroundService(context, serviceIntent );

确保在带有通知的 onHandleIntent 中调用 startForeground()。你可以参考这个来实现它的细节