首页 > 解决方案 > 对于 API >= 26,我应该使用 StartService 还是 StartForegroundService?

问题描述

我有点困惑,因为ContextCompat.StartForegroundService();如果 API >= 26,我读了一些我应该也使用的帖子。

现在我仍然只使用StartServiceIllegalStateException并且根据这篇文章,即使我应该在 API >= 26 上获得一个(当前手机上的 api 是 27),它也可以工作。

https://medium.com/mindorks/mastering-android-service-of-2018-a4a1df5ed5a6

我知道服务是一个古老的概念。让我向你保证,我们不会讨论基础知识,我们将了解最近对 Android 8.0+ 中服务层所做的更改,我们将解开著名的IllegalStateException和 RemoteServiceException 之谜。本文不是理解服务的常规方式,请耐心等待。

所以我的问题是我应该改变 startForeGroundService还是只保留startServiceAPI >=26?

我的类处理我的服务连接:

/**This establishes the connection to the MediaPlayerService. */
public static ServiceConnection serviceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MediaPlayerService.MusicBinder binder = (MediaPlayerService.MusicBinder)service;
        mediaPlayerService = binder.getService();
        mediaPlayerService.musicBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        mediaPlayerService.musicBound = false;
    }
};

/**This is called to start the MediaPlayerService. */
private static Intent mediaPlayerServiceIntent = null;
public static void startMusicService(Context c) {

    /*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
    mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
    c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    c.startService(mediaPlayerServiceIntent);
    mServiceIsActive = true;
}

/**This is called to stop the MediaPlayerService. (onDestroy) */
public static void stopMusicService(Context c) {

    if (mediaPlayerServiceIntent == null)
        return;
    c.unbindService(serviceConnection);
    c.stopService(mediaPlayerServiceIntent);
    mediaPlayerServiceIntent = null;

    mediaPlayerService = null;
}

主要活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Main.startMusicService(getApplicationContext());

}

标签: javaandroidservice

解决方案


startService 不适用于 api >=26

您可以借助以下代码将服务更改为前台服务。它将显示通知。

private void runAsForeground(){
Intent notificationIntent = new Intent(this, MediaPlayerService.class);
PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,
        notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

Notification notification=new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_launcher)
                            .setContentText(getString(R.string.isRecording))
                            .setContentIntent(pendingIntent).build();

startForeground(NOTIFICATION_ID, notification);
}

更多参考 - https://android-developers.googleblog.com/2018/12/effective-foreground-services-on-android_11.html

https://developer.android.com/guide/components/services

另一种方式(不推荐..目标sdk必须为26或更少)

public static void startService(Context context, Class className) {
    try {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
            Intent restartServiceIntent = new Intent(context, className);
            restartServiceIntent.setPackage(context.getPackageName());
            PendingIntent restartServicePendingIntent = PendingIntent.getService(context, 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
            AlarmManager alarmService = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            if (alarmService != null) {
                alarmService.set(
                        AlarmManager.ELAPSED_REALTIME,
                        SystemClock.elapsedRealtime() + 500,
                        restartServicePendingIntent);
            }
        } else {
            Intent i = new Intent(context, className);
            context.startService(i);
        }
    } catch (Exception e) {
        MyLog.e(TAG, "startService: ", e);
    }
}

致电

 startService(context,MediaPlayerService.class);

推荐阅读