Android O - Notification Channels and NotificationCompat

前端 未结 6 1356
忘了有多久
忘了有多久 2021-02-05 03:57

I cannot change this feeling: again, the Android developers came up with something new and leave everybody in the dark about how they would think the feature is used.

I

相关标签:
6条回答
  • 2021-02-05 04:09

    This is my solution to generate notifications on Android O and maintain backward compatibility:

            String idChannel = "my_channel_01";
            Intent mainIntent;
    
            mainIntent = new Intent(context, LauncherActivity.class);
    
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mainIntent, 0);
    
            NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    
            NotificationChannel mChannel = null;
            // The id of the channel.
    
            int importance = NotificationManager.IMPORTANCE_HIGH;
    
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null);
            builder.setContentTitle(context.getString(R.string.app_name))
                    .setSmallIcon(getNotificationIcon())
                    .setContentIntent(pendingIntent)
                    .setContentText(context.getString(R.string.alarm_notification) + ManagementDate.getIstance().hourFormat.format(getAlarm(context, 0)));
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mChannel = new NotificationChannel(idChannel, context.getString(R.string.app_name), importance);
                // Configure the notification channel.
                mChannel.setDescription(context.getString(R.string.alarm_notification));
                mChannel.enableLights(true);
                mChannel.setLightColor(Color.RED);
                mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
                mNotificationManager.createNotificationChannel(mChannel);
            } else {
                builder.setContentTitle(context.getString(R.string.app_name))
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setColor(ContextCompat.getColor(context, R.color.transparent))
                        .setVibrate(new long[]{100, 250})
                        .setLights(Color.YELLOW, 500, 5000)
                        .setAutoCancel(true);
            }
            mNotificationManager.notify(1, builder.build());
    
    0 讨论(0)
  • 2021-02-05 04:09

    It's not as expensive as you think! All you need to do is creating a notification channel and bind it to notification.

    You can solve this in two ways but for both of them you need to create a notification channel with a specific channel id.

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    String id = "my_channel_01";
    int importance = NotificationManager.IMPORTANCE_LOW;
    NotificationChannel mChannel = new NotificationChannel(id, name,importance);
    mChannel.enableLights(true);
    mNotificationManager.createNotificationChannel(mChannel);
    

    First way is to set channel for notification in constructor:

    Notification notification = new Notification.Builder(MainActivity.this , id).setContentTitle("Title");
    mNotificationManager.notify("your_notification_id", notification);
    

    Second way is to set the channel by Notificiation.Builder.setChannelId()

    Notification notification = new Notification.Builder(MainActivity.this).setContentTitle("Title").
    setChannelId(id);
    mNotificationManager.notify("your_notification_id", notification);
    

    Hope this helps

    0 讨论(0)
  • 2021-02-05 04:09

    Here is an alternative solution that uses reflection to create the Notification Channel so you can set a compileSdkVersion of lower than 26.

       private void createNotificationChannel(NotificationManager notificationManager) {
            // Channel details
            String channelId = "myChannelId";
            String channelName = "Notifications";
    
            // Channel importance (3 means default importance)
            int channelImportance = 3;
    
            try {
                // Get NotificationChannel class via reflection (only available on devices running Android O or newer)
                Class notificationChannelClass = Class.forName("android.app.NotificationChannel");
    
                // Get NotificationChannel constructor
                Constructor<?> notificationChannelConstructor = notificationChannelClass.getDeclaredConstructor(String.class, CharSequence.class, int.class);
    
                // Instantiate new notification channel
                Object notificationChannel = notificationChannelConstructor.newInstance(channelId, channelName, channelImportance);
    
                // Get notification channel creation method via reflection
                Method createNotificationChannelMethod =  notificationManager.getClass().getDeclaredMethod("createNotificationChannel", notificationChannelClass);
    
                // Invoke method on NotificationManager, passing in the channel object
                createNotificationChannelMethod.invoke(notificationManager, notificationChannel);
    
                // Log success to console
                Log.d("MyApp", "Notification channel created successfully");
            }
            catch (Exception exc) {
                // Log exception to console
                Log.e("MyApp", "Creating notification channel failed", exc);
            }
        }
    

    Then, when you're building your notifications, simply call the .setChannelId() method of NotificationCompat.Builder:

    builder.setChannelId("myChannelId");
    

    Note: You need to update your appcompat-v7 library to version 26.x.x in build.gradle:

    compile 'com.android.support:appcompat-v7:26.1.0'
    
    0 讨论(0)
  • 2021-02-05 04:10

    If you want to support previous versions of Android (< Oreo). We may wrap the NotificationManager to create and build Notification.Builder instance in a NotificationHelper like this:

    /**
     * Helper class to manage notification channels, and create notifications.
     * <p>
     * Created by teocci.
     *
     * @author teocci@yandex.com on 2018-Oct-02
     */
    public class NotificationHelper extends ContextWrapper
    {
        public static final String NOTIFICATION_CHANNEL_PRIMARY = "notification_channel_primary";
        public static final int NOTIFICATION_ID_PRIMARY = 1100;
    
        private NotificationManager manager;
    
        /**
         * Registers notification channels, which can be used later by individual notifications.
         *
         * @param ctx The application context
         */
        public NotificationHelper(Context ctx)
        {
            super(ctx);
    
            // For API 26+ create notification channels
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_PRIMARY,
                        getString(R.string.channel_name),
                        NotificationManager.IMPORTANCE_DEFAULT
                );
                channel.setLightColor(Color.BLUE);
                channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                channel.setDescription(getString(R.string.channel_description));
                getManager().createNotificationChannel(channel);
            }
        }
        /**
         * Cancel a previously shown notification.  If it's transient, the view
         * will be hidden.  If it's persistent, it will be removed from the status
         * bar.
         *
         * @param id    The ID of the notification
         */
        public void remove(int id){
            manager.cancel(id);
        }
    
        /**
         * Get a notification of type 1
         * <p>
         * Provide the builder rather than the notification it's self as useful for making notification
         * changes.
         *
         * @return the builder as it keeps a reference to the notification (since API 24)
         */
        public Notification getNotification()
        {
            return getNotification(getTitle(), getBody()).build();
        }
    
        /**
         * Get a notification of type 1
         * <p>
         * Provide the builder rather than the notification it's self as useful for making notification
         * changes.
         *
         * @param title the title of the notification
         * @param body  the body text for the notification
         * @return the builder as it keeps a reference to the notification (since API 24)
         */
        public Notification.Builder getNotification(String title, String body)
        {
            Notification.Builder builder = new Notification.Builder(getApplicationContext())
                    .setOngoing(true)  // Persistent notification!
                    .setAutoCancel(true)
                    .setTicker(title)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setSmallIcon(getSmallIcon());
    
            // Set the Channel ID for Android O.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                builder.setChannelId(NOTIFICATION_CHANNEL_PRIMARY); // Channel ID
            }
    
            return builder;
        }
    
        /**
         * Send a notification.
         *
         * @param id           The ID of the notification
         * @param notification The notification object
         */
        public void notify(int id, Notification.Builder notification)
        {
            getManager().notify(id, notification.build());
        }
    
        /**
         * Get the notification manager.
         * <p>
         * Utility method as this helper works with it a lot.
         *
         * @return The system service NotificationManager
         */
        private NotificationManager getManager()
        {
            if (manager == null) {
                manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            }
    
            return manager;
        }
    
        /**
         * Get the small icon for this app
         *
         * @return The small icon resource id
         */
        private int getSmallIcon()
        {
            return R.drawable.ic_smart_audio_noti_icon;
        }
    
        /**
         * Get the notification title for this app
         *
         * @return The notification title as string
         */
        private String getTitle()
        {
            return getString(R.string.notification_title);
        }
    
        /**
         * Get the notification content for this app
         *
         * @return The notification content as string
         */
        private String getBody()
        {
            return getString(R.string.notification_content);
        }
    }
    

    Then we can use it easily like this:

    @Override
    public void onCreate()
    {
        ...
        notificationHelper = new NotificationHelper(this);
        notificationHelper.notify(NotificationHelper.NOTIFICATION_ID_PRIMARY, "App is running");
        ...
    }
    
    @Override
    public void onDestroy()
    {
        notificationHelper.remove(NotificationHelper.NOTIFICATION_ID_PRIMARY)
    }
    
    0 讨论(0)
  • 2021-02-05 04:22

    If your notification code has the same structure every time so you should create a static method and pass all what you want and put the code which check the API Level inside this method.

    0 讨论(0)
  • 2021-02-05 04:25

    Its pretty simple to work with NotificationChannnel.

    NotificationChannel actually group multiple notifications into channels. It basically gives more control of the notification behavior to the user. You can read more about Notification Channel and its implementation at Working with Notification Channel | With Example

    Creating Notification Channel

     // This is the Notification Channel ID. More about this in the next section
    public static final String NOTIFICATION_CHANNEL_ID="channel_id";
    
    //User visible Channel Name
    public static final String CHANNEL_NAME="Notification Channel";
    
    // Importance applicable to all the notifications in this Channel
    int importance=NotificationManager.IMPORTANCE_DEFAULT;
    
    //Notification channel should only be created for devices running Android 26
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
          NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CHANNEL_NAME, importance);
    
          //Boolean value to set if lights are enabled for Notifications from this Channel
          notificationChannel.enableLights(true);
    
          //Boolean value to set if vibration is enabled for Notifications from this Channel
          notificationChannel.enableVibration(true);
    
          //Sets the color of Notification Light
          notificationChannel.setLightColor(Color.GREEN);
    
          //Set the vibration pattern for notifications. Pattern is in milliseconds with the format {delay,play,sleep,play,sleep...}
          notificationChannel.setVibrationPattern(new long[]{500,500,500,500,500});
    
          //Sets whether notifications from these Channel should be visible on Lockscreen or not
          notificationChannel.setLockscreenVisibility( 
     Notification.VISIBILITY_PUBLIC);
    }
    // Creating the Channel
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    notificationManager.createNotificationChannel(notificationChannel);
    

    Now while creating the Notification just pass the Channel ID to the Notification Builder constructor as shown below

    //We pass the unique channel id as the second parameter in the constructor
    NotificationCompat.Builder notificationCompatBuilder=new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID);
    
    //Title for your notification
    notificationCompatBuilder.setContentTitle("This is title");
    
    //Subtext for your notification
    notificationCompatBuilder.setContentText("This is subtext");
    
    //Small Icon for your notificatiom
    notificationCompatBuilder.setSmallIcon(R.id.icon);
    
    //Large Icon for your notification 
    notificationCompatBuilder.setLargeIcon(  BitmapFactory.decodeResource(getResources(),R.id.icon));
    
    notificationManager.notify( NOTIFICATION_ID,notificationCompatBuilder.build());
    

    WIth this above notification becomes a part of the Notification Channel created in the first step and its behavior will now be with respect to the Channel Settings

    0 讨论(0)
提交回复
热议问题