SDK 进阶教程
最近更新:2021-12-15
展开全部

SDK 进阶教程

自定义通知栏样式教程

关于自定义通知栏样式

JPush 通知推送到客户端时,默认使用手机的默认设置来显示通知栏,包括铃声、震动等效果。

如果开发者想要达到如下的效果,则需要使用“自定义通知栏样式”功能:

  • 通知栏样式使用与默认不一样的设置,比如想要控制:
    • 铃声、震动
    • 显示图标
    • 替换默认的通知栏样式。

推送消息指定通知栏样式编号

通知栏样式在服务器端向下推送时,只体现为一个编号(数字)。

推送通知的样式编号,应该是在客户端做了自定义通知栏样式设置的。


如果通知上的样式编号,在客户端检查不存在,则使用默认的通知栏样式。


不使用自定义通知栏样式时,此编号默认为 0。如需使用自定义的通知栏样式,编号应大于 0 小于 1000。先在客户端调 API 设置通知栏样式,推送设置 Builder ID 值即可在收到消息时得到对应的样式效果。

调 API 进行推送时,在 Notification - Android 属性下设置 builder_id 值

在 Portal 上发送通知时,首先选择推送平台为 Android,然后展开“可选设置”,开发者可指定当前要推送的通知的样式编号。如下图所示:

客户端设置通知栏样式

自定义的通知栏样式,是在客户端进行设置的。请参考 通知栏样式定制 API 来看所支持的功能。

自定义通知栏样式设计

  • 有个 PushNotificationBuilder 概念,开发者使用 setPushNotificationBuilder 方法为某种类型的 PushNotificationBuilder 指定编号。
  • setPushNotificationBuilder 可以在 JPushInterface.init() 之后任何地方调用,可以是开发者应用的逻辑来触发调用,或者初始化时调用。
  • 只需要设置一次,JPush SDK 会记住这个设置。在下次收到推送通知时,就根据通知里指定的编号来找到 PushNotificationBuilder 来展现、执行。

API - setDefaultPushNotificationBuilder 设置默认

此 API 改变默认的编号为 0 的通知栏样式。

API - setPushNotificationBuilder 指定编号

此 API 为开发者指定的编号,设置一个自定义的 PushNotificationBuilder(通知样式构建器)。

Example - 基础的 PushNotificationBuilder

定制声音、震动、闪灯等 Notification 样式。

BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(MainActivity.this); builder.statusBarDrawable = R.drawable.jpush_notification_icon; builder.notificationFlags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;  //设置为自动消失和呼吸灯闪烁 builder.notificationDefaults = Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS;  // 设置为铃声、震动、呼吸灯闪烁都要 JPushInterface.setPushNotificationBuilder(1, builder);
          BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(MainActivity.this);
builder.statusBarDrawable = R.drawable.jpush_notification_icon;
builder.notificationFlags = Notification.FLAG_AUTO_CANCEL
        | Notification.FLAG_SHOW_LIGHTS;  //设置为自动消失和呼吸灯闪烁
builder.notificationDefaults = Notification.DEFAULT_SOUND
        | Notification.DEFAULT_VIBRATE
        | Notification.DEFAULT_LIGHTS;  // 设置为铃声、震动、呼吸灯闪烁都要
JPushInterface.setPushNotificationBuilder(1, builder);

        
此代码块在浮窗中显示

定制带按钮的 Notification 样式(3.0.0 及以上版本 sdk 才支持该样式,且该样式在某些与 Android 原生系统有差异的机型上无法正常显示)。

MultiActionsNotificationBuilder builder = new MultiActionsNotificationBuilder(PushSetActivity.this); //添加按钮,参数(按钮图片、按钮文字、扩展数据) builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "first", "my_extra1"); builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "second", "my_extra2"); builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "third", "my_extra3"); JPushInterface.setPushNotificationBuilder(2, builder);
          MultiActionsNotificationBuilder builder = new MultiActionsNotificationBuilder(PushSetActivity.this);
//添加按钮,参数(按钮图片、按钮文字、扩展数据)
builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "first", "my_extra1");
builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "second", "my_extra2");
builder.addJPushAction(R.drawable.jpush_ic_richpush_actionbar_back, "third", "my_extra3");
JPushInterface.setPushNotificationBuilder(2, builder);

        
此代码块在浮窗中显示

Example - 高级自定义的 PushNotificationBuilder

基于基础的 PushNotificationBuilder,可进一步地定制 Notification 的 Layout。

这里作为 example 的 customer_notitfication_layout 在我们的 example 项目的 /res/layout/ 下可以找到。你完全可以用自己的 layout。


CustomPushNotificationBuilder builder = new CustomPushNotificationBuilder(MainActivity.this,      R.layout.customer_notitfication_layout,      R.id.icon,      R.id.title,      R.id.text,      R.id.time);      // 指定定制的 Notification Layout builder.statusBarDrawable = R.drawable.your_notification_icon;      // 指定最顶层状态栏小图标 builder.layoutIconDrawable = R.drawable.your_2_notification_icon;   // 指定下拉状态栏时显示的通知图标 JPushInterface.setPushNotificationBuilder(2, builder);
              CustomPushNotificationBuilder builder = new
    CustomPushNotificationBuilder(MainActivity.this,
                              R.layout.customer_notitfication_layout,
                              R.id.icon,
                              R.id.title,
                              R.id.text,
                              R.id.time); 
                             // 指定定制的 Notification Layout
    builder.statusBarDrawable = R.drawable.your_notification_icon;     
    // 指定最顶层状态栏小图标
    builder.layoutIconDrawable = R.drawable.your_2_notification_icon;  
    // 指定下拉状态栏时显示的通知图标
    JPushInterface.setPushNotificationBuilder(2, builder);

        
此代码块在浮窗中显示

通知栏样式定义不符合要求?

以上提供的自定义通知栏样式的功能是有限的。比如:Android SDK 4.0 以后的 Notification 支持指定 Style ,而这种复杂的通知样式定义 JPush SDK 还未有支持。

或者你想要自定义的复杂的通知样式,但不愿意使用上述高级的自定义通知栏定制功能。

建议不要使用 JPush 提供的通知功能,而使用自定义消息功能。

即:推送自定义消息到客户端后,App 取到自定义消息全部内容,然后 App 自己来写代码做通知的展示。请参考文档:通知 vs. 自定义消息。

通知 vs 自定义消息

极光推送包含有通知与自定义消息两种类型的推送。本文描述他们的区别,以及建议的应用场景。

两者的区别 - 功能角度

通知

通知(Notification),指在手机的通知栏(状态栏)上会显示的一条通知信息。这是 Android / iOS 的基本功能。

通知主要用于提示用户。一条通知,简单的填写纯文本的通知内容即可。

应用加上通知功能,有利于提高应用的活跃度。

自定义消息

自定义消息不是通知,默认不会被 SDK 展示到通知栏上,极光推送仅负责透传给 SDK。其内容和展示形式完全由开发者自己定义。

自定义消息主要用于应用的内部业务逻辑和特殊展示需求。

两者的区别 - 开发者使用角度

通知

简单场景下的通知,用户可以不写一行代码,而完全由 SDK 来负责默认的效果展示,以及默认用户点击时打开应用的主界面。

JPush Android SDK 提供了 API 让开发者来定制通知栏的效果,请参考:自定义通知栏样式教程;也提供了接收推送消息 Receiver 让你来定制在收到通知时与用户点击通知时的不同行为。

自定义消息

SDK 不会把自定义消息展示到通知栏。所以调试时,需要到日志里才可以看到服务器端推送的自定义消息。

自定义消息一定要由开发者写 接收推送消息 Receiver 来处理收到的消息。

注意:

当自定义消息内容 msg_content 为空时,SDK 不会对消息进行广播,使得 App 无法接收到推送的消息,因此建议在使用自定义消息推送时添加内容。

使用通知

请参考以下示例代码。

public class MyReceiver extends BroadcastReceiver {     private static final String TAG = "MyReceiver";           private NotificationManager nm;           @Override     public void onReceive(Context context, Intent intent) {         if (null == nm) {             nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);         }                   Bundle bundle = intent.getExtras();         Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));                   if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {             Logger.d(TAG, "JPush 用户注册成功");                       } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {             Logger.d(TAG, "接受到推送下来的自定义消息");                               } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {             Logger.d(TAG, "接受到推送下来的通知");                   receivingNotification(context,bundle);           } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {             Logger.d(TAG, "用户点击打开了通知");                     openNotification(context,bundle);           } else {             Logger.d(TAG, "Unhandled intent - " + intent.getAction());         }     }      private void receivingNotification(Context context, Bundle bundle){         String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);         Logger.d(TAG, " title : " + title);         String message = bundle.getString(JPushInterface.EXTRA_ALERT);         Logger.d(TAG, "message : " + message);         String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);         Logger.d(TAG, "extras : " + extras);     }      private void openNotification(Context context, Bundle bundle){         String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);         String myValue = "";         try {             JSONObject extrasJson = new JSONObject(extras);             myValue = extrasJson.optString("myKey");         } catch (Exception e) {             Logger.w(TAG, "Unexpected: extras is not a valid json", e);             return;         }         if (TYPE_THIS.equals(myValue)) {             Intent mIntent = new Intent(context, ThisActivity.class);             mIntent.putExtras(bundle);             mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);             context.startActivity(mIntent);         } else if (TYPE_ANOTHER.equals(myValue)){             Intent mIntent = new Intent(context, AnotherActivity.class);             mIntent.putExtras(bundle);             mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);             context.startActivity(mIntent);         }     } }
          public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "MyReceiver";
     
    private NotificationManager nm;
     
    @Override
    public void onReceive(Context context, Intent intent) {
        if (null == nm) {
            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        }
         
        Bundle bundle = intent.getExtras();
        Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));
         
        if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
            Logger.d(TAG, "JPush 用户注册成功");
             
        } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
            Logger.d(TAG, "接受到推送下来的自定义消息");
                     
        } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
            Logger.d(TAG, "接受到推送下来的通知");
     
            receivingNotification(context,bundle);
 
        } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
            Logger.d(TAG, "用户点击打开了通知");
        
           openNotification(context,bundle);
 
        } else {
            Logger.d(TAG, "Unhandled intent - " + intent.getAction());
        }
    }
 
   private void receivingNotification(Context context, Bundle bundle){
        String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
        Logger.d(TAG, " title : " + title);
        String message = bundle.getString(JPushInterface.EXTRA_ALERT);
        Logger.d(TAG, "message : " + message);
        String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
        Logger.d(TAG, "extras : " + extras);
    }
 
   private void openNotification(Context context, Bundle bundle){
        String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
        String myValue = "";
        try {
            JSONObject extrasJson = new JSONObject(extras);
            myValue = extrasJson.optString("myKey");
        } catch (Exception e) {
            Logger.w(TAG, "Unexpected: extras is not a valid json", e);
            return;
        }
        if (TYPE_THIS.equals(myValue)) {
            Intent mIntent = new Intent(context, ThisActivity.class);
            mIntent.putExtras(bundle);
            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(mIntent);
        } else if (TYPE_ANOTHER.equals(myValue)){
            Intent mIntent = new Intent(context, AnotherActivity.class);
            mIntent.putExtras(bundle);
            mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(mIntent);
        }
    }
}

        
此代码块在浮窗中显示

使用自定义消息

使用自定义消息,在客户端 App 里一定要写代码,去接受 JPush SDK 的广播,从而取得推送下来的消息内容。具体请参考文档:接收推送消息 Receiver

以下代码来自于推聊。

public class TalkReceiver extends BroadcastReceiver {     private static final String TAG = "TalkReceiver";           private NotificationManager nm;           @Override     public void onReceive(Context context, Intent intent) {         if (null == nm) {             nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);         }                   Bundle bundle = intent.getExtras();         Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));                   if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {             Logger.d(TAG, "JPush 用户注册成功");                       } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {             Logger.d(TAG, "接受到推送下来的自定义消息");                           // Push Talk messages are push down by custom message format             processCustomMessage(context, bundle);                   } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {             Logger.d(TAG, "接受到推送下来的通知");                   receivingNotification(context,bundle);           } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {             Logger.d(TAG, "用户点击打开了通知");                     openNotification(context,bundle);           } else {             Logger.d(TAG, "Unhandled intent - " + intent.getAction());         }     }           private void processCustomMessage(Context context, Bundle bundle) {         String title = bundle.getString(JPushInterface.EXTRA_TITLE);         String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);         if (StringUtils.isEmpty(title)) {             Logger.w(TAG, "Unexpected: empty title (friend). Give up");             return;         }                   boolean needIncreaseUnread = true;                   if (title.equalsIgnoreCase(Config.myName)) {             Logger.d(TAG, "Message from myself. Give up");             needIncreaseUnread = false;             if (!Config.IS_TEST_MODE) {                 return;             }         }                   String channel = null;         String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);         try {             JSONObject extrasJson = new JSONObject(extras);             channel = extrasJson.optString(Constants.KEY_CHANNEL);         } catch (Exception e) {             Logger.w(TAG, "Unexpected: extras is not a valid json", e);         }                   // Send message to UI (Webview) only when UI is up         if (!Config.isBackground) {             Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);             msgIntent.putExtra(Constants.KEY_MESSAGE, message);             msgIntent.putExtra(Constants.KEY_TITLE, title);             if (null != channel) {                 msgIntent.putExtra(Constants.KEY_CHANNEL, channel);             }                           JSONObject all = new JSONObject();             try {                 all.put(Constants.KEY_TITLE, title);                 all.put(Constants.KEY_MESSAGE, message);                 all.put(Constants.KEY_EXTRAS, new JSONObject(extras));             } catch (JSONException e) {             }             msgIntent.putExtra("all", all.toString());                           context.sendBroadcast(msgIntent);         }                   String chatting = title;         if (!StringUtils.isEmpty(channel)) {             chatting = channel;         }                   String currentChatting = MyPreferenceManager.getString(Constants.PREF_CURRENT_CHATTING, null);         if (chatting.equalsIgnoreCase(currentChatting)) {             Logger.d(TAG, "Is now chatting with - " + chatting + ". Dont show notificaiton.");             needIncreaseUnread = false;             if (!Config.IS_TEST_MODE) {                 return;             }         }                   if (needIncreaseUnread) {             unreadMessage(title, channel);         }                   NotificationHelper.showMessageNotification(context, nm, title, message, channel);     }           // When received message, increase unread number for Recent Chat     private void unreadMessage(final String friend, final String channel) {         new Thread() {             public void run() {                 String chattingFriend = null;                 if (StringUtils.isEmpty(channel)) {                     chattingFriend = friend;                 }                                   Map<String, String> params = new HashMap<String, String>();                 params.put("udid", Config.udid);                 params.put("friend", chattingFriend);                 params.put("channel_name", channel);                                   try {                     HttpHelper.post(Constants.PATH_UNREAD, params);                 } catch (Exception e) {                     Logger.e(TAG, "Call pushtalk api to report unread error", e);                 }             }         }.start();     } }
          public class TalkReceiver extends BroadcastReceiver {
    private static final String TAG = "TalkReceiver";
     
    private NotificationManager nm;
     
    @Override
    public void onReceive(Context context, Intent intent) {
        if (null == nm) {
            nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        }
         
        Bundle bundle = intent.getExtras();
        Logger.d(TAG, "onReceive - " + intent.getAction() + ", extras: " + AndroidUtil.printBundle(bundle));
         
        if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
            Logger.d(TAG, "JPush 用户注册成功");
             
        } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
            Logger.d(TAG, "接受到推送下来的自定义消息");
             
            // Push Talk messages are push down by custom message format
            processCustomMessage(context, bundle);
         
        } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
            Logger.d(TAG, "接受到推送下来的通知");
     
            receivingNotification(context,bundle);
 
        } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
            Logger.d(TAG, "用户点击打开了通知");
        
           openNotification(context,bundle);
 
        } else {
            Logger.d(TAG, "Unhandled intent - " + intent.getAction());
        }
    }
     
    private void processCustomMessage(Context context, Bundle bundle) {
        String title = bundle.getString(JPushInterface.EXTRA_TITLE);
        String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
        if (StringUtils.isEmpty(title)) {
            Logger.w(TAG, "Unexpected: empty title (friend). Give up");
            return;
        }
         
        boolean needIncreaseUnread = true;
         
        if (title.equalsIgnoreCase(Config.myName)) {
            Logger.d(TAG, "Message from myself. Give up");
            needIncreaseUnread = false;
            if (!Config.IS_TEST_MODE) {
                return;
            }
        }
         
        String channel = null;
        String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
        try {
            JSONObject extrasJson = new JSONObject(extras);
            channel = extrasJson.optString(Constants.KEY_CHANNEL);
        } catch (Exception e) {
            Logger.w(TAG, "Unexpected: extras is not a valid json", e);
        }
         
        // Send message to UI (Webview) only when UI is up
        if (!Config.isBackground) {
            Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
            msgIntent.putExtra(Constants.KEY_MESSAGE, message);
            msgIntent.putExtra(Constants.KEY_TITLE, title);
            if (null != channel) {
                msgIntent.putExtra(Constants.KEY_CHANNEL, channel);
            }
             
            JSONObject all = new JSONObject();
            try {
                all.put(Constants.KEY_TITLE, title);
                all.put(Constants.KEY_MESSAGE, message);
                all.put(Constants.KEY_EXTRAS, new JSONObject(extras));
            } catch (JSONException e) {
            }
            msgIntent.putExtra("all", all.toString());
             
            context.sendBroadcast(msgIntent);
        }
         
        String chatting = title;
        if (!StringUtils.isEmpty(channel)) {
            chatting = channel;
        }
         
        String currentChatting = MyPreferenceManager.getString(Constants.PREF_CURRENT_CHATTING, null);
        if (chatting.equalsIgnoreCase(currentChatting)) {
            Logger.d(TAG, "Is now chatting with - " + chatting + ". Dont show notificaiton.");
            needIncreaseUnread = false;
            if (!Config.IS_TEST_MODE) {
                return;
            }
        }
         
        if (needIncreaseUnread) {
            unreadMessage(title, channel);
        }
         
        NotificationHelper.showMessageNotification(context, nm, title, message, channel);
    }
     
    // When received message, increase unread number for Recent Chat
    private void unreadMessage(final String friend, final String channel) {
        new Thread() {
            public void run() {
                String chattingFriend = null;
                if (StringUtils.isEmpty(channel)) {
                    chattingFriend = friend;
                }
                 
                Map<String, String> params = new HashMap<String, String>();
                params.put("udid", Config.udid);
                params.put("friend", chattingFriend);
                params.put("channel_name", channel);
                 
                try {
                    HttpHelper.post(Constants.PATH_UNREAD, params);
                } catch (Exception e) {
                    Logger.e(TAG, "Call pushtalk api to report unread error", e);
                }
            }
        }.start();
    }
}

        
此代码块在浮窗中显示

文档内容是否对您有帮助?

Copyright 2011-2022, jiguang.cn, All Rights Reserved. 粤ICP备12056275号-13 深圳市和讯华谷信息技术有限公司

在文档中心打开