Android前台服务通知未显示

Dre*_*Org 18 notifications android

我正在尝试启动前台服务.我收到通知,该服务确实启动但通知始终被抑制.我仔细检查了应用是否允许在我的设备上的应用信息中显示通知.这是我的代码:

private void showNotification() {
    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
            notificationIntent, 0);

    Bitmap icon = BitmapFactory.decodeResource(getResources(),
            R.mipmap.ic_launcher);

    Notification notification = new NotificationCompat.Builder(getApplicationContext())
            .setContentTitle("Revel Is Running")
            .setTicker("Revel Is Running")
            .setContentText("Click to stop")
            .setSmallIcon(R.mipmap.ic_launcher)
            //.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
            .setContentIntent(pendingIntent)
            .setOngoing(true).build();
    startForeground(Constants.FOREGROUND_SERVICE,
            notification);
    Log.e(TAG,"notification shown");

}
Run Code Online (Sandbox Code Playgroud)

这是我在关系中看到的唯一错误: 06-20 12:26:43.635 895-930/? E/NotificationService: Suppressing notification from the package by user request.

v1k*_*v1k 25

这是因为Android O bg服务的限制.

因此,现在您startForeground()只需要调用已启动的服务,并startForegroundService()在服务启动后的前5秒内调用它.

这是指南 - https://developer.android.com/about/versions/oreo/background#services

像这样:

//Start service:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  startForegroundService(new Intent(this, YourService.class));
} else {
  startService(new Intent(this, YourService.class));
}
Run Code Online (Sandbox Code Playgroud)

然后创建并显示通知(使用前面假设的频道):

private void createAndShowForegroundNotification(Service yourService, int notificationId) {

    final NotificationCompat.Builder builder = getNotificationBuilder(yourService,
         "com.example.your_app.notification.CHANNEL_ID_FOREGROUND", // Channel id
    NotificationManagerCompat.IMPORTANCE_LOW); //Low importance prevent visual appearance for this notification channel on top 
    builder.setOngoing(true)
    .setSmallIcon(R.drawable.small_icon)
    .setContentTitle(yourService.getString(R.string.title))
    .setContentText(yourService.getString(R.string.content));

    Notification notification = builder.build();

    yourService.startForeground(notificationId, notification);

    if (notificationId != lastShownNotificationId) {
          // Cancel previous notification
          final NotificationManager nm = (NotificationManager) yourService.getSystemService(Activity.NOTIFICATION_SERVICE);
          nm.cancel(lastShownNotificationId);
    }
    lastShownNotificationId = notificationId;
}

public static NotificationCompat.Builder getNotificationBuilder(Context context, String channelId, int importance) {
    NotificationCompat.Builder builder;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        prepareChannel(context, channelId, importance);
        builder = new NotificationCompat.Builder(context, channelId);
    } else {
        builder = new NotificationCompat.Builder(context);
    }
    return builder;
}

@TargetApi(26)
private static void prepareChannel(Context context, String id, int importance) {
    final String appName = context.getString(R.string.app_name);
    String description = context.getString(R.string.notifications_channel_description);
    final NotificationManager nm = (NotificationManager) context.getSystemService(Activity.NOTIFICATION_SERVICE);

    if(nm != null) {
        NotificationChannel nChannel = nm.getNotificationChannel(id);

        if (nChannel == null) {
            nChannel = new NotificationChannel(id, appName, importance);
            nChannel.setDescription(description);
            nm.createNotificationChannel(nChannel);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请记住,即使您使用不同的频道ID,您的前景通知也会与其他通知具有相同的状态,因此它可能会与其他人一起隐藏.使用不同的组来避免它.

  • 您还可以使用 ContextCompat.startForegroundService(context, intentService) (2认同)

Dre*_*Org 18

问题是我使用的是Android O,它需要更多信息.这是android O的成功代码.

    mNotifyManager = (NotificationManager) mActivity.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannel(mNotifyManager);
    mBuilder = new NotificationCompat.Builder(mActivity, "YOUR_TEXT_HERE").setSmallIcon(android.R.drawable.stat_sys_download).setColor
            (ContextCompat.getColor(mActivity, R.color.colorNotification)).setContentTitle(YOUR_TITLE_HERE).setContentText(YOUR_DESCRIPTION_HERE);
    mNotifyManager.notify(mFile.getId().hashCode(), mBuilder.build());

@TargetApi(26)
private void createChannel(NotificationManager notificationManager) {
    String name = "FileDownload";
    String description = "Notifications for download status";
    int importance = NotificationManager.IMPORTANCE_DEFAULT;

    NotificationChannel mChannel = new NotificationChannel(name, name, importance);
    mChannel.setDescription(description);
    mChannel.enableLights(true);
    mChannel.setLightColor(Color.BLUE);
    notificationManager.createNotificationChannel(mChannel);
}
Run Code Online (Sandbox Code Playgroud)

  • 但是在这个新的代码片段中,我注意到你正在调用`mNotifyManager.notify()`而不是`startForeground()`.在这种情况下,它真的使服务前景? (6认同)
  • 什么是“ mFile”? (2认同)

Dor*_*ean 7

如果以上都没有奏效,您应该检查您的通知 ID 是否为 0 ... 惊喜!!它不能为 0。

非常感谢@Luka Kama 的这篇文章

startForeground(0, notification); // Doesn't work...

startForeground(1, notification); // Works!!!
Run Code Online (Sandbox Code Playgroud)

  • 我们知道为什么在这种情况下通知 ID 不能为零吗? (2认同)
  • https://developer.android.com/guide/components/services 注意:您提供给 startForeground() 的整数 ID 不能为 0。 (2认同)

Han*_*eno 7

对我来说,一切都设置正确(还向清单添加了 FOREGROUND_SERVICE 权限),但我只需要卸载应用程序并重新安装它。


And*_*ndy 5

对于Android API 级别 33+,您需要请求 POST_NOTIFICATIONS 运行时权限。虽然这不会阻止前台服务运行,但仍然必须像我们对< API 33所做的那样进行通知:

注意:应用程序不需要请求 POST_NOTIFICATIONS 权限即可启动前台服务。但是,应用程序在启动前台服务时必须包含通知,就像在以前版本的 Android 上一样。

请参阅Android 文档了解更多信息。