【问题标题】:Notification not showing in Oreo奥利奥中未显示通知
【发布时间】:2017-08-22 22:13:54
【问题描述】:

普通通知生成器不会在 Android O 上显示通知。

如何在 Android 8 Oreo 上显示通知?

是否有任何新代码要添加以在 Android O 上显示通知?

【问题讨论】:

  • 我忘记将“.setChannelId”设置为 NotificationCompat.Builder,现在它在 oreo(8.0) 中工作

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


【解决方案1】:

在 Android O 中,必须在通知生成器中使用频道

以下是示例代码:

// Sets an ID for the notification, so it can be updated.
int notifyID = 1; 
String CHANNEL_ID = "my_channel_01";// The id of the channel. 
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
            .setContentTitle("New Message")
            .setContentText("You've received new messages.")
            .setSmallIcon(R.drawable.ic_notify_status)
            .setChannelId(CHANNEL_ID)
            .build();

或通过以下方式处理兼容性:

NotificationCompat notification =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setChannelId(CHANNEL_ID).build();

现在让它通知

NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 mNotificationManager.createNotificationChannel(mChannel);

// Issue the notification.
mNotificationManager.notify(notifyID , notification);

或者,如果您想要一个简单的修复,请使用以下代码:

NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       mNotificationManager.createNotificationChannel(mChannel);
    }

更新: NotificationCompat.Builder reference

NotificationCompat.Builder(Context context)

此构造函数在 API 级别 26.0.0 中已弃用 所以你应该使用

Builder(Context context, String channelId)

所以不需要setChannelId 使用新的构造函数。

你应该使用目前最新的 AppCompat 库 26.0.2

compile "com.android.support:appcompat-v7:26.0.+"

来源Android Developers Channel on Youtube

另外,您可以查看official Android Docs

【讨论】:

  • 您还必须创建一个频道才能使用它。见developer.android.com/reference/android/app/…
  • setChannel 已弃用,取而代之的是 setChannelId
  • 不,如果您没有在应用安装生命周期内至少创建一次频道,则会收到错误消息。
  • @amorenew 显然我的频道名称有误。它现在工作。谢谢,但您的回答不完整...您必须先使用 mNotificationManager.createNotificationChannel(mChannel); 创建一个频道; (我在我的应用程序类中这样做了)......请参阅谷歌文档。也许将此添加到您的答案中。
  • 我应该针对哪些依赖项/版本来获取新的 NotificationCompat.Builder(Context, String) 构造函数?我正在使用(除其他外):-compileSdkVersion 26-buildToolsVersion '26.0.2'-compile 'com.android.support:appcompat-v7:26.0.0-beta2',但它仍然不接受使用上下文和字符串的构造函数。有什么想法吗?
【解决方案2】:

在这里我发布了一些带有意图处理的快速解决方案功能

public void showNotification(Context context, String title, String body, Intent intent) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    int notificationId = 1;
    String channelId = "channel-01";
    String channelName = "Channel Name";
    int importance = NotificationManager.IMPORTANCE_HIGH;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(
                channelId, channelName, importance);
        notificationManager.createNotificationChannel(mChannel);
    }

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setContentText(body);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addNextIntent(intent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
    );
    mBuilder.setContentIntent(resultPendingIntent);

    notificationManager.notify(notificationId, mBuilder.build());
}

【讨论】:

  • 这里也一样。只有一个为 FCM 和 Android >= 8 工作了 4 个我。
  • 快速简单
  • 非常感谢。我花了几个小时排查为什么通知不显示。因此,如果您只想弹出一个,只需确保您已使用 NotificationManager for Android Oreo+ 创建了 NotificationChannel。
  • 这段代码最容易实现和理解,甚至在 2019 年 12 月都是最新的。谢谢。
  • Android中notificationManager.notify和startForeground有什么区别?
【解决方案3】:

除了this answer,还需要创建通知通道才能使用。

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

      /* Create or update. */
      NotificationChannel channel = new NotificationChannel("my_channel_01",
          "Channel human readable title", 
          NotificationManager.IMPORTANCE_DEFAULT);
      mNotificationManager.createNotificationChannel(channel);
  }

此外,仅当您的 targetSdkVersion 为 26 或更高时,您才需要使用通道。

如果您使用的是 NotificationCompat.Builder,您还需要更新到支持库的测试版:https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0-beta2(以便能够在兼容构建器上调用setChannelId)。

请小心,因为此库更新将 minSdkLevel 提高到 14。

【讨论】:

  • 如果 min api 低于 26,这将引发警告。在创建通道之前添加 @TargetApi(26) 以抑制警告。
  • 如果您在代码示例中有类似 if 它不会产生警告,快速修复有不同的建议,其中之一是通过 if 版本检查包围代码。如果您调整 if 版本检查,Android Studio 可能会感到困惑并且可能无法检测到它。
【解决方案4】:
public class MyFirebaseMessagingServices extends FirebaseMessagingService {
    private NotificationChannel mChannel;
    private NotificationManager notifManager;
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (remoteMessage.getData().size() > 0) {
            try {
                JSONObject jsonObject = new JSONObject(remoteMessage.getData());
                displayCustomNotificationForOrders(jsonObject.getString("title"), jsonObject.getString("description"));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    private void displayCustomNotificationForOrders(String title, String description) {
        if (notifManager == null) {
            notifManager = (NotificationManager) getSystemService
                    (Context.NOTIFICATION_SERVICE);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationCompat.Builder builder;
            Intent intent = new Intent(this, Dashboard.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent;
            int importance = NotificationManager.IMPORTANCE_HIGH;
            if (mChannel == null) {
                mChannel = new NotificationChannel
                        ("0", title, importance);
                mChannel.setDescription(description);
                mChannel.enableVibration(true);
                notifManager.createNotificationChannel(mChannel);
            }
            builder = new NotificationCompat.Builder(this, "0");

            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                    Intent.FLAG_ACTIVITY_SINGLE_TOP);
            pendingIntent = PendingIntent.getActivity(this, 1251, intent, PendingIntent.FLAG_ONE_SHOT);
            builder.setContentTitle(title)  
                    .setSmallIcon(getNotificationIcon()) // required
                    .setContentText(description)  // required
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setAutoCancel(true)
                    .setLargeIcon(BitmapFactory.decodeResource
                            (getResources(), R.mipmap.logo))
                    .setBadgeIconType(R.mipmap.logo)
                    .setContentIntent(pendingIntent)
                    .setSound(RingtoneManager.getDefaultUri
                            (RingtoneManager.TYPE_NOTIFICATION));
            Notification notification = builder.build();
            notifManager.notify(0, notification);
        } else {

            Intent intent = new Intent(this, Dashboard.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = null;

            pendingIntent = PendingIntent.getActivity(this, 1251, intent, PendingIntent.FLAG_ONE_SHOT);

            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                    .setContentTitle(title)
                    .setContentText(description)
                    .setAutoCancel(true)
                    .setColor(ContextCompat.getColor(getBaseContext(), R.color.colorPrimary))
                    .setSound(defaultSoundUri)
                    .setSmallIcon(getNotificationIcon())
                    .setContentIntent(pendingIntent)
                    .setStyle(new NotificationCompat.BigTextStyle().setBigContentTitle(title).bigText(description));

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(1251, notificationBuilder.build());
        }
    }

    private int getNotificationIcon() {
        boolean useWhiteIcon = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
        return useWhiteIcon ? R.mipmap.logo : R.mipmap.logo;
    }
}

【讨论】:

  • 不显示 NotificationCompat.Builder 通知上的 setChannelId(CHANNEL_ID)。
【解决方案5】:

如果26+ SDK版本收不到推送?

您的解决方案在这里:

public static void showNotification(Context context, String title, String messageBody) {

        boolean isLoggedIn = SessionManager.getInstance().isLoggedIn();
        Log.e(TAG, "User logged in state: " + isLoggedIn);

        Intent intent = null;
        if (isLoggedIn) {
            //goto notification screen
            intent = new Intent(context, MainActivity.class);
            intent.putExtra(Extras.EXTRA_JUMP_TO, DrawerItems.ITEM_NOTIFICATION);
        } else {
            //goto login screen
            intent = new Intent(context, LandingActivity.class);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);

        //Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        //Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_app_notification_icon);

        String channel_id = createNotificationChannel(context);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channel_id)
                .setContentTitle(title)
                .setContentText(messageBody)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(messageBody))
                /*.setLargeIcon(largeIcon)*/
                .setSmallIcon(R.drawable.app_logo_color) //needs white icon with transparent BG (For all platforms)
                .setColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))
                .setVibrate(new long[]{1000, 1000})
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setContentIntent(pendingIntent)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true);

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify((int) ((new Date(System.currentTimeMillis()).getTime() / 1000L) % Integer.MAX_VALUE) /* ID of notification */, notificationBuilder.build());
    }

public static String createNotificationChannel(Context context) {

        // NotificationChannels are required for Notifications on O (API 26) and above.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            // The id of the channel.
            String channelId = "Channel_id";

            // The user-visible name of the channel.
            CharSequence channelName = "Application_name";
            // The user-visible description of the channel.
            String channelDescription = "Application_name Alert";
            int channelImportance = NotificationManager.IMPORTANCE_DEFAULT;
            boolean channelEnableVibrate = true;
//            int channelLockscreenVisibility = Notification.;

            // Initializes NotificationChannel.
            NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, channelImportance);
            notificationChannel.setDescription(channelDescription);
            notificationChannel.enableVibration(channelEnableVibrate);
//            notificationChannel.setLockscreenVisibility(channelLockscreenVisibility);

            // Adds NotificationChannel to system. Attempting to create an existing notification
            // channel with its original values performs no operation, so it's safe to perform the
            // below sequence.
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            assert notificationManager != null;
            notificationManager.createNotificationChannel(notificationChannel);

            return channelId;
        } else {
            // Returns null for pre-O (26) devices.
            return null;
        }
    }

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channel_id)

-> 在这里,您将在包含 26+ SDK 版本的设备中使用 channel_id 收到推送通知。

-> 因为,NotificationCompat.Builder(context) 已被弃用,现在您将使用具有两个参数的更新版本,一个是 context,另一个是 channel_id。

-> NotificationCompat.Builder(context, channel_id) 更新了方法。试试看。

-> 在 26+ SDK 版本的设备中,您每次都会创建 channel_id。

【讨论】:

  • 谢谢我使用静态notifcation_id来通知
【解决方案6】:

将此类用于 Android 8 通知

public class NotificationHelper {

private Context mContext;
private NotificationManager mNotificationManager;
private NotificationCompat.Builder mBuilder;
public static final String NOTIFICATION_CHANNEL_ID = "10001";

public NotificationHelper(Context context) {
    mContext = context;
}

/**
 * Create and push the notification 
 */
public void createNotification(String title, String message)
{    
    /**Creates an explicit intent for an Activity in your app**/
    Intent resultIntent = new Intent(mContext , SomeOtherActivity.class);
    resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext,
            0 /* Request code */, resultIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    mBuilder = new NotificationCompat.Builder(mContext);
    mBuilder.setSmallIcon(R.mipmap.ic_launcher);
    mBuilder.setContentTitle(title)
            .setContentText(message)
            .setAutoCancel(false)
            .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
            .setContentIntent(resultPendingIntent);

    mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
    {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.enableVibration(true);
        notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        assert mNotificationManager != null;
        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        mNotificationManager.createNotificationChannel(notificationChannel);
    }
    assert mNotificationManager != null;
    mNotificationManager.notify(0 /* Request Code */, mBuilder.build());
  }
}

【讨论】:

    【解决方案7】:

    首先,如果您不知道,从 Android Oreo(即 API 级别 26)开始,通知必须通过频道重新发送。

    在这种情况下,许多教程可能会让您感到困惑,因为它们在 oreo 上方和下方显示了不同的通知示例。

    所以这是一个在 oreo 上下运行的通用代码:

    String CHANNEL_ID = "MESSAGE";
    String CHANNEL_NAME = "MESSAGE";
    
    NotificationManagerCompat manager = NotificationManagerCompat.from(MainActivity.this);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
        NotificationManager.IMPORTANCE_DEFAULT);
        manager.createNotificationChannel(channel);
    }
    
    Notification notification = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_android_black_24dp)
            .setContentTitle(TitleTB.getText().toString())
            .setContentText(MessageTB.getText().toString())
            .build();
    manager.notify(getRandomNumber(), notification); // In case you pass a number instead of getRandoNumber() then the new notification will override old one and you wont have more then one notification so to do so u need to pass unique number every time so here is how we can do it by "getRandoNumber()"
    
    private static int getRandomNumber() {
        Date dd= new Date();
        SimpleDateFormat ft =new SimpleDateFormat ("mmssSS");
        String s=ft.format(dd);
        return Integer.parseInt(s);
    }
    

    视频教程:YOUTUBE VIDEO

    如果你想下载这个演示:GitHub Link

    【讨论】:

      【解决方案8】:

      适用于 Android O 以及较低 API 版本的 Android 通知演示应用程序。 这是GitHub-Demo 1GitHub-Demo 2 上的最佳演示应用程序。

      【讨论】:

      • 请考虑发布应用程序如何工作的最小代码 sn-p,而不是提供指向外部源的链接,而不注明来源/从属关系。 (这些来源也可能随时关闭,没有其他方法可以访问它们。)
      【解决方案9】:

      试试这个代码:

      public class FirebaseMessagingServices extends com.google.firebase.messaging.FirebaseMessagingService {
          private static final String TAG = "MY Channel";
          Bitmap bitmap;
      
          @Override
          public void onMessageReceived(RemoteMessage remoteMessage) {
              super.onMessageReceived(remoteMessage);
              Utility.printMessage(remoteMessage.getNotification().getBody());
      
              // Check if message contains a data payload.
              if (remoteMessage.getData().size() > 0) {
                  Log.d(TAG, "Message data payload: " + remoteMessage.getData());
      
                  String title = remoteMessage.getData().get("title");
                  String body = remoteMessage.getData().get("body");
                  String message = remoteMessage.getData().get("message");
                  String imageUri = remoteMessage.getData().get("image");
                  String msg_id = remoteMessage.getData().get("msg-id");
                
      
                  Log.d(TAG, "1: " + title);
                  Log.d(TAG, "2: " + body);
                  Log.d(TAG, "3: " + message);
                  Log.d(TAG, "4: " + imageUri);
                
      
                  if (imageUri != null)
                      bitmap = getBitmapfromUrl(imageUri);
      
                  }
      
                  sendNotification(message, bitmap, title, msg_id);
                          
              }
      
      
          }
      
          private void sendNotification(String message, Bitmap image, String title,String msg_id) {
              int notifyID = 0;
              try {
                  notifyID = Integer.parseInt(msg_id);
              } catch (NumberFormatException e) {
                  e.printStackTrace();
              }
      
              String CHANNEL_ID = "my_channel_01";            // The id of the channel.
              Intent intent = new Intent(this, HomeActivity.class);
              intent.putExtra("title", title);
              intent.putExtra("message", message);
              intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      
      
              PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                      PendingIntent.FLAG_ONE_SHOT);
      
              Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
              NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "01")
                      .setContentTitle(title)
                      .setSmallIcon(R.mipmap.ic_notification)
                      .setStyle(new NotificationCompat.BigTextStyle()
                              .bigText(message))
                      .setContentText(message)
                      .setAutoCancel(true)
                      .setSound(defaultSoundUri)
                      .setChannelId(CHANNEL_ID)
                      .setContentIntent(pendingIntent);
      
              if (image != null) {
                  notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle()   //Set the Image in Big picture Style with text.
                          .bigPicture(image)
                          .setSummaryText(message)
                          .bigLargeIcon(null));
              }
      
      
              NotificationManager notificationManager =
                      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {       // For Oreo and greater than it, we required Notification Channel.
                 CharSequence name = "My New Channel";                   // The user-visible name of the channel.
                  int importance = NotificationManager.IMPORTANCE_HIGH;
      
                  NotificationChannel channel = new NotificationChannel(CHANNEL_ID,name, importance); //Create Notification Channel
                  notificationManager.createNotificationChannel(channel);
              }
      
              notificationManager.notify(notifyID /* ID of notification */, notificationBuilder.build());
          }
      
          public Bitmap getBitmapfromUrl(String imageUrl) {     //This method returns the Bitmap from Url;
              try {
                  URL url = new URL(imageUrl);
                  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                  connection.setDoInput(true);
                  connection.connect();
                  InputStream input = connection.getInputStream();
                  Bitmap bitmap = BitmapFactory.decodeStream(input);
                  return bitmap;
      
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                  return null;
      
              }
      
          }
      
      }

      【讨论】:

      • 我使用了这段代码,但是当应用程序在后台时,带有图像的亲爱的通知是不可见的,你有什么解决方案请帮忙。
      • 这取决于一些因素,例如:- 1.您是否连接到网络..??? 2. 图片 url 是否正确(通过在浏览器上点击 imageurl 来检查 imageurl)
      【解决方案10】:

      这是 firebase api 版本 11.8.0 中的错误,因此如果您降低 API 版本,您将不会遇到此问题。

      【讨论】:

      • 其实我已经查过了。如果您正在使用 Android 模拟器 - 检查您在物理设备上的应用。新的模拟器不知何故不显示通知。
      • 不,实际上这实际上是 firebase 11.8.0 版本中的一个错误,现在它已在较新的版本 12.0.0 中修复。参考官方发布说明:firebase.google.com/support/release-notes/android
      【解决方案11】:

      我在 Oreo 上遇到了同样的问题,发现如果您首先使用 NotificationManager.IMPORTANCE_NONE 创建您的频道,然后再更新它,该频道将保留原来的重要性级别。

      这得到了Google Notification training documentation 的支持,其中指出:

      创建通知通道后,您无法更改通知行为——用户此时拥有完全控制权。

      删除并重新安装该应用后,您可以重置频道行为。

      最好避免使用 IMPORTANCE_NONE,除非您想禁止该频道的通知,即使用静默通知。

      【讨论】:

        【解决方案12】:

        这就是你的做法

        private fun sendNotification() {
            val notificationId = 100
            val chanelid = "chanelid"
            val intent = Intent(this, MainActivity::class.java)
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
            val pendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // you must create a notification channel for API 26 and Above
                val name = "my channel"
                val description = "channel description"
                val importance = NotificationManager.IMPORTANCE_DEFAULT
                val channel = NotificationChannel(chanelid, name, importance);
                channel.setDescription(description);
                // Register the channel with the system; you can't change the importance
                // or other notification behaviors after this
                val notificationManager = getSystemService(NotificationManager::class.java)
                notificationManager.createNotificationChannel(channel)
            }
        
            val mBuilder = NotificationCompat.Builder(this, chanelid)
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle("Want to Open My App?")
                    .setContentText("Open my app and see good things")
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(true) // cancel the notification when clicked
                    .addAction(R.drawable.ic_check, "YES", pendingIntent) //add a btn to the Notification with a corresponding intent
        
            val notificationManager = NotificationManagerCompat.from(this);
            notificationManager.notify(notificationId, mBuilder.build());
        }
        

        阅读完整教程 => https://developer.android.com/training/notify-user/build-notification

        【讨论】:

          【解决方案13】:

          以下方法将显示通知,启用大文本和冻结(即使在用户滑动后通知也不会被删除)。我们需要 NotificationManager 服务

          public static void showNotificationOngoing(Context context,String title) {
                  NotificationManager notificationManager =
                          (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
          
                  PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                          new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
          
                  Notification.Builder notificationBuilder = new Notification.Builder(context)
                          .setContentTitle(title + DateFormat.getDateTimeInstance().format(new Date()) + ":" + accuracy)
                          .setContentText(addressFragments.toString())
                          .setSmallIcon(R.mipmap.ic_launcher)
                          .setContentIntent(contentIntent)
                          .setOngoing(true)
                          .setStyle(new Notification.BigTextStyle().bigText(addressFragments.toString()))
                          .setAutoCancel(true);
                  notificationManager.notify(3, notificationBuilder.build());
          }
          

          删除通知的方法

          public static void removeNotification(Context context){
              NotificationManager notificationManager =
                      (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
              notificationManager.cancelAll();
          }
          

          来源Link

          【讨论】:

            【解决方案14】:

            CHANNEL_ID in NotificationChannelNotification.Builder 必须相同,试试这个代码:

            String CHANNEL_ID = "my_channel_01";
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Solveta Unread", NotificationManager.IMPORTANCE_DEFAULT);
            
            
            Notification.Builder notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID);
            

            【讨论】:

              【解决方案15】:

              嗯,就我而言,我有 Android 8.1.0 和型号 vivo1811,我已经尝试了上述所有解决方案,但没有任何效果。

              所以最后,我写信给 Firebase 支持,然后在进一步调试时,我得到了这个 - “向停止的应用广播失败”:确保应用没有被强制停止”

              这是 Firebase 团队的回复 ->

              这是一个由电池优化引起的已知问题 由一些 OEM 实施。当一个应用在应用中被刷掉时 切换器,应用程序被视为被强制停止,这 不是默认的 Android 行为。不幸的副作用 这是因为它可能导致您的应用程序的 FCM 服务停止 跑步。我们正在努力从头开始改善这种行为,但是 实际修复必须来自 OEM 方面。

              这里的 OEM 代表 原始设备制造商

              【讨论】:

                【解决方案16】:

                您需要为 API 级别高于 26(oreo) 创建一个通知通道。

                `NotificationChannel channel = new NotificationChannel(STRING_ID,CHANNEL_NAME,NotificationManager.IMPORTANCE_HIGH);
                

                STRING_ID = string notification channelid 和 Notification.Builder 中的一样

                `Notification notification = new Notification.Builder(this,STRING_ID)
                            .setSmallIcon(android.R.drawable.ic_menu_help)
                            .setContentTitle("Hello Notification")
                            .setContentText("It is Working")
                            .setContentIntent(pendingIntent)
                            .build();`
                

                通知和通知中的频道 id 应该相同 整个代码是这样的.. `

                @RequiresApi(api = Build.VERSION_CODES.O)
                  private void callNotification2() {
                
                    Intent intent = new Intent(getApplicationContext(),MainActivity.class);
                    PendingIntent pendingIntent = PendingIntent.getActivity(this,11, 
                    intent,PendingIntent.FLAG_UPDATE_CURRENT);
                    Notification notification = new Notification.Builder(this,"22")
                            .setSmallIcon(android.R.drawable.ic_menu_help)
                            .setContentTitle("Hello Notification")
                            .setContentText("It is Working")
                            .setContentIntent(pendingIntent)
                            .build();
                    NotificationChannel channel = new 
                    NotificationChannel("22","newName",NotificationManager.IMPORTANCE_HIGH);
                    NotificationManager manager = (NotificationManager) 
                    getSystemService(NOTIFICATION_SERVICE);
                    manager.createNotificationChannel(channel);
                    manager.notify(11,notification);
                
                    }'
                

                【讨论】:

                  【解决方案17】:

                  对于在尝试上述解决方案后遇到此问题的任何人,请确保创建通知通道时使用的通道 ID 与您在通知构建器中设置的通道 ID相同

                  const val CHANNEL_ID = "EXAMPLE_CHANNEL_ID"
                  
                  // create notification channel
                  val notificationChannel = NotificationChannel(CHANNEL_ID, 
                  NOTIFICATION_NAME, NotificationManager.IMPORTANCE_HIGH)
                  
                  // building notification
                  NotificationCompat.Builder(context)
                                      .setSmallIcon(android.R.drawable.ic_input_add)
                                      .setContentTitle("Title")
                                      .setContentText("Subtitle")   
                                      .setPriority(NotificationCompat.PRIORITY_MAX)
                                      .setChannelId(CHANNEL_ID)
                  

                  【讨论】:

                    【解决方案18】:
                    private void addNotification() {
                                    NotificationCompat.Builder builder =
                                    new NotificationCompat.Builder(this)
                                    .setSmallIcon(R.drawable.ic_launcher_background)
                                    .setContentTitle("Notifications Example")
                                    .setContentText("This is a test notification");
                                    Intent notificationIntent = new Intent(this, MainActivity.class);
                                    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
                                    PendingIntent.FLAG_UPDATE_CURRENT);
                                    builder.setContentIntent(contentIntent);
                                    // Add as notification
                                    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
                                    {
                                    NotificationChannel nChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", NotificationManager.IMPORTANCE_HIGH);
                                    nChannel.enableLights(true);
                                    assert manager != null;
                                    builder.setChannelId(NOTIFICATION_CHANNEL_ID);
                                    manager.createNotificationChannel(nChannel);
                                    }
                                    assert manager != null;
                                    manager.notify(0, builder.build());
                        }
                    

                    【讨论】:

                      【解决方案19】:
                      NotificationCompat.Builder(Context context)
                      

                      对于大于或等于 android Oreo 的版本已弃用。您可以将实现更改为使用

                      NotificationCompat.Builder(Context context, String channelId)
                      

                      【讨论】:

                        【解决方案20】:
                        fun pushNotification(message: String?, clickAtion: String?) {
                                val ii = Intent(clickAtion)
                                ii.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                                val pendingIntent = PendingIntent.getActivity(this, REQUEST_CODE, ii, PendingIntent.FLAG_ONE_SHOT)
                        
                                val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
                        
                                val largIcon = BitmapFactory.decodeResource(applicationContext.resources,
                                        R.mipmap.ic_launcher)
                        
                        
                                val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                        
                                val channelId = "default_channel_id"
                                val channelDescription = "Default Channel"
                        // Since android Oreo notification channel is needed.
                        //Check if notification channel exists and if not create one
                                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                                    var notificationChannel = notificationManager.getNotificationChannel(channelId)
                                    if (notificationChannel != null) {
                                        val importance = NotificationManager.IMPORTANCE_HIGH //Set the importance level
                                        notificationChannel = NotificationChannel(channelId, channelDescription, importance)
                                       // notificationChannel.lightColor = Color.GREEN //Set if it is necesssary
                                        notificationChannel.enableVibration(true) //Set if it is necesssary
                                        notificationManager.createNotificationChannel(notificationChannel)
                        
                        
                                        val noti_builder = NotificationCompat.Builder(this)
                                                .setContentTitle("MMH")
                                                .setContentText(message)
                                                .setSmallIcon(R.drawable.ic_launcher_background)
                                                .setChannelId(channelId)
                                                .build()
                                        val random = Random()
                                        val id = random.nextInt()
                                        notificationManager.notify(id,noti_builder)
                        
                                    }
                        
                                }
                                else
                                {
                                    val notificationBuilder = NotificationCompat.Builder(this)
                                            .setSmallIcon(R.mipmap.ic_launcher).setColor(resources.getColor(R.color.colorPrimary))
                                            .setVibrate(longArrayOf(200, 200, 0, 0, 0))
                                            .setContentTitle(getString(R.string.app_name))
                        
                                            .setLargeIcon(largIcon)
                                            .setContentText(message)
                                            .setAutoCancel(true)
                                            .setStyle(NotificationCompat.BigTextStyle().bigText(message))
                                            .setSound(soundUri)
                                            .setContentIntent(pendingIntent)
                        
                        
                                    val random = Random()
                                    val id = random.nextInt()
                                    notificationManager.notify(id, notificationBuilder.build())
                        
                                }
                        
                        
                        
                            }
                        

                        【讨论】:

                        • 虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。您可以使用edit 按钮改进此答案以获得更多选票和声誉!
                        【解决方案21】:

                        下面的代码在 Oreo 中对我有用,你可以试试这个。希望它对你有用

                        private void sendNotification(Context ctx, String title, int notificationNumber, String message, String subtext, Intent intent) {
                        试试 {

                                    PendingIntent pendingIntent = PendingIntent.getActivity(ctx, notificationNumber, intent,
                                            PendingIntent.FLAG_UPDATE_CURRENT);
                                    Uri url = null;           
                                    NotificationCompat.Builder notificationBuilder = null;
                                    try {
                                        if (Build.VERSION.SDK_INT >= 26) {
                        
                                            try{
                                                NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
                                                notificationManager.deleteNotificationChannel(CHANNEL_ID_1);
                                                notificationManager.deleteNotificationChannel(CHANNEL_ID_2);
                        
                                                if(!intent.getStringExtra("type").equalsIgnoreCase(""+TYPE_REQUEST)){
                                                    NotificationChannel breaking = new NotificationChannel(CHANNEL_ID_1, CHANNEL_ID_1_NAME, NotificationManager.IMPORTANCE_HIGH);
                                                    breaking.setShowBadge(false);
                                                    breaking.enableLights(true);
                                                    breaking.enableVibration(true);
                                                    breaking.setLightColor(Color.WHITE);
                                                    breaking.setVibrationPattern(new long[]{100, 200, 100, 200, 100, 200, 100});
                                                    breaking.setSound(url,new AudioAttributes.Builder().build());
                        
                                                    notificationBuilder = new NotificationCompat.Builder(this,CHANNEL_ID_1)
                                                            .setSmallIcon(R.mipmap.ic_launcher);
                                                    notificationManager.createNotificationChannel(breaking);
                        
                                                }else{
                        
                                                    NotificationChannel politics = new NotificationChannel(CHANNEL_ID_2,CHANNEL_ID_2_NAME, NotificationManager.IMPORTANCE_DEFAULT);
                                                    politics.setShowBadge(false);
                                                    politics.enableLights(true);
                                                    politics.enableVibration(true);
                                                    politics.setLightColor(Color.BLUE);
                                                    politics.setVibrationPattern(new long[]{100, 200, 100, 200, 100});
                                                    politics.setSound(url,new AudioAttributes.Builder().build());
                        
                                                    notificationBuilder = new NotificationCompat.Builder(this,CHANNEL_ID_2)
                                                            .setSmallIcon(R.mipmap.ic_launcher);
                                                    notificationManager.createNotificationChannel(politics);
                                                }
                                            }catch (Exception e){
                                                e.printStackTrace();
                                            }
                        
                                        } else {
                                            notificationBuilder = new NotificationCompat.Builder(ctx)
                                                    .setSmallIcon(R.mipmap.ic_launcher);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                        
                                    if (notificationBuilder == null) {
                                        notificationBuilder = new NotificationCompat.Builder(ctx)
                                                .setSmallIcon(R.mipmap.ic_launcher);
                                    }
                        
                        
                                    notificationBuilder.setContentTitle(title);          
                                    notificationBuilder.setSubText(subtext);
                                    notificationBuilder.setAutoCancel(true);
                        
                                    notificationBuilder.setContentIntent(pendingIntent);
                                    notificationBuilder.setNumber(notificationNumber);
                                    NotificationManager notificationManager =
                                            (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
                        
                                    notificationManager.notify(notificationNumber, notificationBuilder.build());
                        
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                        
                            }
                        

                        【讨论】:

                          【解决方案22】:

                          在 android Oreo 中,通知应用是通过使用通道和 NotificationHelper 类完成的。它应该有一个通道 id 和通道名称。

                          首先你必须创建一个 NotificationHelper 类

                          public class NotificationHelper extends ContextWrapper {
                          
                          private static final String EDMT_CHANNEL_ID="com.example.safna.notifier1.EDMTDEV";
                          private static final String EDMT_CHANNEL_NAME="EDMTDEV Channel";
                          private NotificationManager manager;
                          
                          public  NotificationHelper(Context base)
                          {
                              super(base);
                              createChannels();
                          }
                          private void createChannels()
                          {
                              NotificationChannel edmtChannel=new NotificationChannel(EDMT_CHANNEL_ID,EDMT_CHANNEL_NAME,NotificationManager.IMPORTANCE_DEFAULT);
                              edmtChannel.enableLights(true);
                              edmtChannel.enableVibration(true);
                              edmtChannel.setLightColor(Color.GREEN);
                              edmtChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                          
                              getManager().createNotificationChannel(edmtChannel);
                          
                          }
                          public NotificationManager getManager()
                          {
                             if (manager==null)
                                 manager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
                             return manager;
                          
                          }
                          public NotificationCompat.Builder getEDMTChannelNotification(String title,String body)
                          {
                              return new NotificationCompat.Builder(getApplicationContext(),EDMT_CHANNEL_ID)
                                      .setContentText(body)
                                      .setContentTitle(title)
                                      .setSmallIcon(R.mipmap.ic_launcher_round)
                                      .setAutoCancel(true);
                              }
                          }
                          

                          在活动xml文件中创建一个按钮,然后在主活动中

                          protected void onCreate(Bundle savedInstanceState) {
                          
                              super.onCreate(savedInstanceState);
                              setContentView(R.layout.activity_main);
                          
                              helper=new NotificationHelper(this);
                          
                              btnSend=(Button)findViewById(R.id.btnSend);
                          
                              btnSend.setOnClickListener(new View.OnClickListener() {
                                  @Override
                                  public void onClick(View v) {
                                      String title="Title";
                                      String content="Content";
                                      Notification.Builder builder=helper.getEDMTChannelNotification(title,content);
                                      helper.getManager().notify(new Random().nextInt(),builder.build());
                                  }
                              });
                          
                          }
                          

                          然后运行你的项目

                          【讨论】:

                            【解决方案23】:

                            我遇到了这个问题,但找到了一个独特的解决方案。
                            对我来说这是旧代码

                            String NOTIFICATION_CHANNEL_ID = "com.codedevtech.emplitrack";
                            

                            工作代码是

                            String NOTIFICATION_CHANNEL_ID = "emplitrack_channel";
                            

                            可能是频道 ID 不应包含点 '.'

                            【讨论】:

                              【解决方案24】:
                                  NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "CHANNEL_ID")
                                          ........
                              
                                  NotificationManager mNotificationManager =
                                          (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                              
                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                      CharSequence name = "Hello";// The user-visible name of the channel.
                                      int importance = NotificationManager.IMPORTANCE_HIGH;
                                      NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
                                      mNotificationManager.createNotificationChannel(mChannel);
                                  }
                                  mNotificationManager.notify(notificationId, notificationBuilder.build());
                              

                              【讨论】: