Android O - 旧的开始前台服务仍然有效吗? [英] Android O - Old start foreground service still working?

查看:28
本文介绍了Android O - 旧的开始前台服务仍然有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,对于 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)

所以,要重现:

  1. 按照上一个链接中的说明配置应用程序 gradle
  2. 打开应用
  3. 请求位置更新
  4. 关闭应用(通过后退按钮或主页按钮)

服务正在前台运行(由通知阴影中的图标显示).即使在运行 O 的设备上,位置更新也会按预期进行(每 10 秒一次).我在这里缺少什么?

解决方案

这对我有用.

<块引用>

  1. 在 Activity 类中,使用 startForegroundService() 而不是 startService()
  2. 启动服务

 Intent myService = new Intent(this, MyService.class);如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(myService);} 别的 {开始服务(我的服务);}

<块引用>

  1. 现在在 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

The NotificationManager.startServiceInForeground() method starts a foreground service. The old way to start a foreground service no longer works.

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.

Edit Including 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:

  1. Configure the app gradle as mentioned in the previous link
  2. Open the app
  3. Request location updates
  4. 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.

  1. In Activity class, start service using startForegroundService() instead of startService()

    Intent myService = new Intent(this, MyService.class);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(myService);
    } else {
        startService(myService);
    }

  1. Now in Service class in onStartCommand() do as following

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

Note: Using Notification.Builder instead of NotificationCompat.Builder made it work. Only in Notification.Builder you will need to provide Channel ID which is new feature in Android Oreo.

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 - 旧的开始前台服务仍然有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆