Should i use StartService or StartForegroundService for API >= 26?

ぐ巨炮叔叔 提交于 2021-01-29 05:45:39

问题


I'm a bit confused because i read some posts where i'm supposed too use ContextCompat.StartForegroundService(); if the API is >= 26.

Now I still just use StartService and it works even though i'm supposed to get an IllegalStateException on an API >= 26 ( current api on phone is 27) according to this post.

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

I know Service is an old concept. Let me assure you we will not discuss the basics and we will learn the recent changes made to the service layer in Android 8.0+, we will solve the mystery of famous IllegalStateException and RemoteServiceException. This article is not a conventional way of understanding services, hang tight till you can.

So my question is if i should change startForeGroundService or just keep startService for API >=26?

My Class that handles my Service connection:

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

MainActivity:

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

    Main.startMusicService(getApplicationContext());

}

回答1:


startService will not work for api >=26

You can change your service to foreground service with help of following code. It will show the notification.

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

for more reference - https://android-developers.googleblog.com/2018/12/effective-foreground-services-on-android_11.html

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

another way (not recommended.. target sdk must be 26 or less)

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

Call by

 startService(context,MediaPlayerService.class);


来源:https://stackoverflow.com/questions/56471033/should-i-use-startservice-or-startforegroundservice-for-api-26

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!