【问题标题】:Oreo - Foreground service does not show foreground notificationOreo - 前台服务不显示前台通知
【发布时间】:2017-09-08 08:20:06
【问题描述】:

到目前为止,我已将代码调整为使用 ContextCompat.startForegroundService(context, intentService); 来启动我的服务。这样,它也适用于 android

我仍然看到差异,在 android oreo 中我没有看到我的自定义前台通知(我只看到“应用程序在后台运行”通知)。我还需要在那里调整什么吗?

我的服务如下所示:

public class BaseOverlayService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        moveToForeground();
    }

    private void moveToForeground() {
        Notification notification = ...;
        super.startForeground(NOTIFICATION_ID, notification);
    }
}

官方示例

此示例 (https://github.com/googlesamples/android-play-location/blob/master/LocationUpdatesForegroundService/app/src/main/java/com/google/android/gms/location/sample/locationupdatesforegroundservice/LocationUpdatesService.java#L200) 显示为注释,我应该使用以下注释,但 startServiceInForeground 不存在...

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
    NotificationManager mNotificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
    mNotificationManager.startServiceInForeground(new Intent(this, BaseOverlayService.class), NOTIFICATION_ID, notification);
} else {
    startForeground(NOTIFICATION_ID, notification);
}

编辑

我的通知是这样创建的,到目前为止,它在数千个 API

protected Notification foregroundNotification(int notificationId)
{
    boolean paused = MainApp.getPrefs().sidebarServicePaused();
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(R.drawable.icon_not);
    builder.setContentIntent(notificationIntent());
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
    builder.setContentTitle(getString(R.string.derived_app_name));
    builder.setContentText(getString(checkStatus() ? (paused ? R.string.service_notification_text_paused : R.string.service_notification_text_running) : R.string.service_notification_text_preparing));
    builder.setColor(Color.parseColor("#25baa2"));

    if (MainApp.getPrefs().hideNotificationIcon())
        builder.setPriority(NotificationCompat.PRIORITY_MIN);
    else
        builder.setPriority(NotificationCompat.PRIORITY_MAX);

    if (paused)
        builder.addAction(R.drawable.ic_play_arrow_black_24dp, getString(R.string.resume), resumeIntent(this));
    else
        builder.addAction(R.drawable.ic_pause_black_24dp, getString(R.string.pause), pauseIntent(this));

    return builder.build();
}

【问题讨论】:

    标签: android android-notifications android-8.0-oreo foreground-service


    【解决方案1】:

    您可能需要为您的应用定义通知渠道。检查日志,应该有警告。 查看this的介绍

    我会给你一些例子,它会在 kotin 中。 首先,做一个这样的类。您需要在应用程序启动时调用 createMainNotificationChannel() 一次。

    class NotificationManager(private val context: Context) {
    
        companion object {
            private val CHANNEL_ID = "YOUR_CHANNEL_ID"
            private val CHANNEL_NAME = "Your human readable notification channel name"
            private val CHANNEL_DESCRIPTION = "description"
        }
    
        @RequiresApi(Build.VERSION_CODES.O)
        fun getMainNotificationId(): String {
            return CHANNEL_ID
        }
    
        @RequiresApi(Build.VERSION_CODES.O)
        fun createMainNotificationChannel() {
                val id = CHANNEL_ID
                val name = CHANNEL_NAME
                val description = CHANNEL_DESCRIPTION
                val importance = android.app.NotificationManager.IMPORTANCE_LOW
                val mChannel = NotificationChannel(id, name, importance)
                mChannel.description = description
                mChannel.enableLights(true)
                mChannel.lightColor = Color.RED
                mChannel.enableVibration(true)
                val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as android.app.NotificationManager
                mNotificationManager.createNotificationChannel(mChannel)
        }
    }
    

    那么你就可以像这样使用util了

    fun createNotificationCompatBuilder(context: Context): NotificationCompat.Builder {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return NotificationCompat.Builder(context, NotificationManager(context).mainNotificationId)
        } else {
            return NotificationCompat.Builder(context)
        }
    }
    

    【讨论】:

    • 您添加的链接无论如何都很好,谢谢。但是有一个问题:这种变化是否意味着我不再需要在 android oreo 中显示前台服务通知?因为人们确实告诉我我的应用在没有通知的情况下也可以在 android oreo 上运行......
    • eghmmm... 实际上它不能在没有通知的情况下工作。在没有可见组件(如活动或通知)的情况下,android o 中不允许后台工作。如果您在没有可见组件的情况下运行您的服务,系统会在一段时间后将其杀死。因此,如果您想做后台工作,您需要通知服务。如果您需要在一段时间内在后台运行某些东西 - 您应该检查 firebase job dispatcher。它允许您运行预定的服务。
    • 我在WindowManager 上有一个带有 UI 元素的侧边栏应用程序,它似乎也适用于我迄今为止使用的隐形通知(隐形通知是没有频道的通知)。现在几天没有收到任何投诉。模拟器也不会在 5 秒内终止我的服务
    • @prom85 你的目标 api 设置为 26 吗?
    • 是的。无论如何,可见组件是有的,甚至有两个:一个用于我绘制的叠加层,一个用于在后台运行的服务......
    【解决方案2】:

    kotlin 中的代码

     private fun customNotification(title: String,notificationID: Int) {
    
                    val intent = Intent(this, MainActivity::class.java)
                    val pendingIntent = PendingIntent.getActivity(this, 0 /* request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    
    
                    val builder = NotificationCompat.Builder(this, title)
                    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                    .setContentText("Notification description")
                            .setSmallIcon(R.drawable.ic_mark_map)
                            .setContentIntent(pendingIntent)
                            .setOnlyAlertOnce(true)
    
                    val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        val channel = NotificationChannel(title,
                                "Channel human readable title",
                                NotificationManager.IMPORTANCE_DEFAULT)
                        mNotificationManager.createNotificationChannel(channel)
                    }
    
                     val notification = builder.build()
                     startForeground(notificationID, notification)
                }
    

    用途:

     customNotification("Title",101)
    

    【讨论】:

    • 它没有回答问题
    【解决方案3】:
      // Since android Oreo notification channel is needed.
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    NotificationChannel channel = new NotificationChannel(channelId,
                            getString(R.string.app_name),
                            NotificationManager.IMPORTANCE_HIGH);
    
                    AudioAttributes attributes = new AudioAttributes.Builder()
                            .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                            .build();
    
    
                    channel.setDescription(data.get("body"));
                    channel.enableLights(true);
                    channel.enableVibration(true);
                    channel.setSound(SoundUri, attributes); // This is IMPORTANT
    
                    notificationManager.createNotificationChannel(channel);
    
    
                }
    

    【讨论】:

      猜你喜欢
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      相关资源
      最近更新 更多