Android自定义通知栏显示

Android自定义通知栏显示_第1张图片

概述

本文主要想说一下android项目开发中经常会使用到通知机制中的通知栏框架(Notificaiton)。通知栏位于设备的顶层,可以展开的通知列表。通知栏的主要作用大概可以分为三大块:

  • 显示未读的消息(短信消息、QQ、微信等消息)
  • 显示客户端的PushMessage(推送消息),如系统更新、新闻、广告推送
  • 显示正在进行的后台程序,如各类型的音乐播放器等。

关键类介绍

  • NotificationManager
    主要负责通知的管理(通知的发送、通知的删除、通知的清空等操作),同时也含有对通知的类型、规则判断等。经常使用的内部方法主要有以下几个:
    /***
     * NotificationManager类的实例化
     * @param context
     * @return
     */
    public static NotificationManager from(Context context) {
        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    /**
     * 通知的发布
     * @param id
     * @param notification
     */
    public void notify(int id, Notification notification) {
        notify(null, id, notification);
    }

    /**
     * 通知的发布  (含标签)
     * @param tag
     * @param id
     * @param notification
     */
    public void notify(String tag, int id, Notification notification) {
        notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
    }

    /**
     * 之前发布通知的取消
     * @param id
     */
    public void cancel(int id) {
        cancel(null, id);
    }

    /**
     * 之前发布通知的取消  (含标签)
     * @param tag
     * @param id
     */
    public void cancel(String tag, int id) {
        cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
    }

    /**
     * 之前发布通知的取消  (所有当前 应用所发布的通知)
     */
    public void cancelAll() {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
        try {
            service.cancelAllNotifications(pkg, UserHandle.myUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
  • Notification
    具体的状态栏通知对象,它是一个序列化的庞大的类,可以设置icon、文字、提示声音、振动等等参数。
    给Notification设置PendingIntent

  • PendingIntent
    点击通知栏中的某个View想跳转一个Activity或者开启一个service时,可以通过设置PendingIntent完成。
    PendingIntent 是 Android 系统管理并持有的用于描述和获取原始数据的对象的标志(引用),即便创建该PendingIntent对象的进程被杀死了,这个PendingItent对象在其他进程中还是可用的,比如闹钟功能就用到了 PendingIntent。它的获取方式主要有:

//方式一:获取一个用于启动 Activity 的 PendingIntent 对象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);

//方式二: 获取一个用于启动 Service 的 PendingIntent 对象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);

//方式三: 获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)

PendingIntent 几种重要的flag标志:

1) FLAG_CANCEL_CURRENT
当前系统中已经存在一个相同的 PendingIntent 对象时,先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。
2) FLAG_NO_CREATE
当前系统中不存在相同的 PendingIntent 对象时,将不会创建该 PendingIntent 对象而是直接返回 null 。
3)FLAG_ONE_SHOT
该 PendingIntent 只作用一次。
4)FLAG_UPDATE_CURRENT
系统中已存在该 PendingIntent 对象时,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。

  • RemoteViews
    远程视图,从名字就可以看出RemoteViews不是当前进程的View。实际上它是属于SystemServer进程.应用程序与RemoteViews之间依赖Binder实现了进程间通信。Android项目开发中,RemoteViews使用最多的场合是通知栏和桌面小插件。介绍RemoteViews主要是为了引入后面的举例。

应用举例

Android系统使用RemoteViews来自定义通知。视图通知高度限制为64dp,大视图通知高度限制为256dp。同时,建议自定义通知尽量简单,以提高兼容性。 自定义通知需要做如下操作:

  • 创建自定义通知布局
  • 使用RemoteViews定义通知组件,如图标、文字等
  • 调用setContent()将RemoteViews对象绑定到NotificationCompat.Builder对象上
  • 发送通知

自定义通知栏的布局 layout_float_window.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fl_window_layout"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:background="#f4f2f3"
    android:paddingLeft="@dimen/margin_20"
    android:paddingRight="@dimen/margin_20">

    <ImageView
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_gravity="center_vertical"
        android:background="@drawable/ic_microphone_white" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="70dp"
        android:layout_marginRight="50dp"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lineSpacingExtra="0sp"
            android:text="咪咕家语音播报"
            android:textColor="#282e33"
            android:textSize="17sp" />

        <TextView
            android:id="@+id/percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="7dp"
            android:lineSpacingExtra="0sp"
            android:text="IM消息"
            android:textColor="#66737f"
            android:textSize="14sp" />
    LinearLayout>

    <ImageView
        android:id="@+id/iv_close_notify"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center_vertical|right"
        android:scaleType="center"
        android:src="@drawable/ic_close_grey1" />
FrameLayout>

通知栏创建的关键代码

@SuppressLint("NewApi")
    private void createNotification() {
        remoteViews = new RemoteViews(getPackageName(), R.layout.layout_float_window);//通知栏布局
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(this);
        // 点击跳转到播报界面
        if (mMessenger != null) {
            Intent intent_main = new Intent(this, VoiceBroadcastActivity.class);
            PendingIntent pending_intent_go = PendingIntent.getActivity(this, 1, intent_main, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.fl_window_layout, pending_intent_go);
        }
        //关闭播报
        Intent intent_cancel = new Intent();
        intent_cancel.setAction(BroadcastConstants.ACTION_CLOSE);
        PendingIntent pending_intent_close = PendingIntent.getBroadcast(this, 2, intent_cancel, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.iv_close_notify, pending_intent_close);

        mBuilder.setSmallIcon(R.drawable.ic_close_grey1); // 设置顶部图标(状态栏)
        mBuilder.setContent(remoteViews);
        mBuilder.setOngoing(true);
        mNotificationManager.notify(BroadcastConstants.NOTIFICATION_CEDE, mBuilder.build());
    }

你可能感兴趣的:(Android应用开发)