问题描述
因此,对于 Android O,如果您希望每小时接收的不仅仅是几个位置更新,您需要将您的服务作为前台服务运行.
我注意到启动前台服务的旧方法似乎适用于 O.即
startForeground(NOTIFICATION_ID, getNotification());
根据此处的行为更改指南:https://developer.android.com/preview/behavior-changes.html
NotificationManager.startServiceInForeground() 方法启动前台服务.启动前台服务的旧方法不再有效.
虽然新方法仅适用于针对 O 的情况,但无论是否针对 O,旧方法似乎仍然适用于 O 设备.
编辑包括示例:
Google 示例项目 LocationUpdatesForegroundService 实际上有一个工作示例,您可以在其中直接看到问题.https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService
startForeground 方法似乎可以毫无问题地工作,无论是针对 API 级别 25 进行定位和编译还是针对 O 进行定位和编译(如此处所示:https://developer.android.com/preview/migration.html#uya)
所以,要重现:
- 按照上一个链接中的说明配置应用程序 gradle
- 打开应用
- 请求位置更新
- 关闭应用(通过后退按钮或主页按钮)
服务正在前台运行(由通知阴影中的图标显示).即使在运行 O 的设备上,位置更新也会按预期进行(每 10 秒一次).我在这里缺少什么?
这对我有用.
- 在 Activity 类中,使用 startForegroundService() 而不是 startService() 启动服务
Intent myService = new Intent(this, MyService.class);如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(myService);} 别的 {开始服务(我的服务);}
- 现在在 onStartCommand() 的 Service 类中执行以下操作
@Overridepublic int onStartCommand(意图意图,int标志,int startId){......如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID).setContentTitle(getString(R.string.app_name)).setContentText(文本).setAutoCancel(true);通知通知 = builder.build();startForeground(1, 通知);} 别的 {NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setContentTitle(getString(R.string.app_name)).setContentText(文本).setPriority(NotificationCompat.PRIORITY_DEFAULT).setAutoCancel(true);通知通知 = builder.build();startForeground(1, 通知);}返回 START_NOT_STICKY;}
注意:使用 Notification.Builder 而不是 NotificationCompat.Builder 使其工作.只有在 Notification.Builder 中,您才需要提供频道 ID,这是 Android Oreo 中的新功能.
希望它有效!
如果您面向 API 级别 28 或更高级别,则需要 FOREGROUND_SERVICE 权限,否则您的应用将崩溃.
只需将其添加到 AndroidManifest.xml 文件中即可.
So, with Android O, you need to have your service running as a foreground service if you want to receive more than just a few location updates per hour.
I noticed that the old method for starting a foreground service does seem to work on O.i.e.
startForeground(NOTIFICATION_ID, getNotification());
According to the behaviour changes guide here:https://developer.android.com/preview/behavior-changes.html
Though the new method only works when targeting O, it seems that the old method still seems to work on an O device whether targeting O or not.
EditIncluding example:
The Google sample project LocationUpdatesForegroundService actually has a working example where you can see the issue first hand.https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService
The startForeground method seems to work without issue whether targeting and compiling against API level 25 OR targeting and compiling against O (as directed to here: https://developer.android.com/preview/migration.html#uya)
So, to reproduce:
- Configure the app gradle as mentioned in the previous link
- Open the app
- Request location updates
- Close app (either via back button or home button)
Service is running in foreground (shown by icon in notification shade). Location updates are coming through as expected (every 10 seconds) even on a device running O. What I am missing here?
This worked for me.
Intent myService = new Intent(this, MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(myService);
} else {
startService(myService);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
......
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(text)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
}
return START_NOT_STICKY;
}
Hope it works!
EDIT:
If you target API level 28 or higher, you need FOREGROUND_SERVICE permission otherwise, your app will crash.
Just add this to the AndroidManifest.xml file.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
这篇关于Android O - 旧的开始前台服务仍然有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!