Android O - 旧的启动前台服务仍在工作?

标签 android location android-8.0-oreo

因此,对于 Android O,如果您希望每小时接收的不仅仅是几个位置更新,则需要将您的服务作为前台服务运行。

我注意到启动前台服务的旧方法似乎确实适用于 O。 即

startForeground(NOTIFICATION_ID, getNotification());

根据此处的行为更改指南: 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.

虽然新方法仅在针对 O 时有效,但旧方法似乎仍然适用于 O 设备,无论是否针对 O。

编辑 包括例子:

Google 示例项目 LocationUpdatesForegroundService 实际上有一个工作示例,您可以在其中直接看到问题。 https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService

无论是针对 API 级别 25 进行定位和编译,还是针对 O 进行定位和编译,startForeground 方法似乎都可以正常工作(如下所示:https://developer.android.com/preview/migration.html#uya)

所以,要重现:

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

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

最佳答案

这对我有用。

  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.

希望它有效!

编辑:

如果您的目标 API 级别为 28 或更高,则需要 FOREGROUND_SERVICE 权限,否则您的应用会崩溃。

只需将其添加到 AndroidManifest.xml 文件中即可。

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

关于Android O - 旧的启动前台服务仍在工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43251528/

相关文章:

java - IntentService 中未调用 OnHandleIntent()

android - 在Android中同时发送文本和图像

iphone - 输入位置时调用号码 - iOS

Android O 报告通知未发布到 channel - 但它是

android - 如果我无限期地在后台运行 Android 线程会发生什么

android - Oreo - 小部件服务和广播接收器 : Not allowed to start service Intent

android - 为什么我的通知小图标总是灰色的?

android - 在 Android Studio 上构建应用程序时出错

iOS 快速将我的位置按钮移动到右上角

android - 使用 fusedlocationapi 获取位置,而无需在时间间隔后请求位置更新