java - 对于 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
还是只保留startService
API >=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());
}
解决方案
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);
推荐阅读
- java - Java中的不记名令牌到期
- firebase - Google Cloud Scheduler 每分钟在设定的时间运行
- python - 如何在 Flask 中获取 HTML 按钮的数据值?
- java - 使用 Java Data(I/O)Stream 通过 TCP Socket 发送文件时文件损坏
- javascript - 如何消除
- bash - 通过 netcat 连接并在 bash 脚本中发送命令
- javascript - 如何从回调方法中获取状态的更新值?
- javascript - 有没有办法在 TypeScript 中扩展函数的类型以添加额外的参数?
- elasticsearch - Lucene 和 Elasticsearch 超出文档限制
- git - `git reset stash` 的语义是什么?