Android Notification

Android Notification

饮水思源

本文的主要内容是从下列的连接中总结而来。

http://www.cnblogs.com/travellife/p/Android-Notification-xiang-jie.html

http://adchs.github.io/patterns/notifications.html

https://developer.android.google.cn/guide/topics/ui/notifiers/notifications.html

http://www.runoob.com/w3cnote/android-tutorial-notification.html

DESC

通知是您可以在应用的常规UI外部向用户显示的消息。当您告知系统发出通知时,它将先以图标的形式显示在通知区域中。用户可以打开抽屉式通知栏查看通知的详细信息。通知区域和抽屉式通知栏均是由系统控制的区域,用户可以随时查看。

涉及到的知识点

通知的细节

img

一个通知的钢需

  • Icon 小图标 通过 setSmallIcon 方法设置
  • Title 标题 setContentTItle 方法设置
  • Msg 信息 setContentText() 设置

以上三个是一个通知所必须的,而其他的属性都是可选的

发送通知

常用的方法

  • SetContentTitle() 设置标题

  • SetContentText() 设置内容

  • SetSubText() 设置内容下发的小文字

  • SetTicker() 设置收到通知时在顶部显示的文字信息

  • SetWhen() 设置通知时间 通常值为 System.CurrectTimeMillis()

  • SetSmallIcon() 设置小图标

  • SetLargerIcon() 设置大图标

  • SetAutoCancel() 设置点击 Notification面板点击后 是否取消通知的显示 默认值是不取消

  • SetDefaults() 向通知添加闪灯声音,闪灯,震动等效果 最简单的时使用 默认的(defaults)属性 可以组合多种属性

    • Light 默认灯光
    • Sound 默认声音
    • Vibrate 默认震动
    • All 全部
  • SetVibrate 设置震动的方式

  • SetSound 设置通知时候的铃声 可以是系统的也可以是文件

  • SetOngoing() 如果设置为true 表示为一个正在进行或者正在等待处理的通知。通常用来表示一个后台任务,如(播放音乐等),也可能是因为某种原因在等待比如:文件下载,请求联网等

  • SetProgress(int,int,bool) 设置带进度条的通知 参数为 最大值,当前值,进度条是否不确定

    • 如果是不确定进度条 调用 SetProgress(0,0,ture) 两种格式的进度条取消的时候调用SetProgress(0,0,false)
  • SetContentIntent(PendingIntent intent); PendingIntent 和Intent 有所不同 主要用于 远程服务通信,闹铃,通知,启动器,短信中 ,启动Activity中 一般情况下用的比较少

发送一个最简单的通知

public void click(View view) {
    //创建一个notification
    Notification.Builder nBuilder = new Notification.Builder(this).
            setSmallIcon(R.drawable.notification).
            setContentTitle("The is a notification!").
            setContentText("The is notification!The is notification!The is notification!The is notification!");
    //获取通知管理者
    NotificationManager nManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    /*
    * 发送通知
    * id: 用于更新通知
    * notification: 要发送的广播
    * */
    nManager.notify(1, nBuilder.build());
}
设置通知的显示位置

浮动通知

浮动通知,时 Android 5.0 新出的显示方式,以顶部弹框的形式显示出我们的通知。

/*
* 设置显示浮动通知
* 参数:
* PendingIntent
* highPriority 是否是高优先级的
* */
nBuilder.setFullScreenIntent(pi, false);

锁屏通知

Android 5.0 开始,通知可以显示在锁屏上了,我们可以通过setVisibility方法来设置锁频通知所显示的内容

参数:

  • VISIBILITY_PRIVATE : 显示基本信息,如通知的图标,但隐藏通知的全部内容
  • VISIBILITY_PUBLIC : 显示通知的全部内容
  • VISIBILITY_SECRET : 不显示任何内容,包括图标
/*
* 参数:
* visibility 设置锁屏通知显示的内容
* */
nBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
通知的优先级
  • SetPriority() 设置通知的优先级

    • MAX 重要而紧急的消息,继续被用户处理
    • High 高优先级 用途通讯 如短信,或者消息
    • Default 默认
    • Low 可以通知用户但是不紧急
    • Min 后台消息
设置通知的提醒方式
//使用系统默认的通知方式
//不知为何在我的模拟器上没有任何的显示
//设置呼吸灯
builder.setDefaults(Notification.DEFAULT_LIGHTS);
//设置震动
builder.setDefaults(Notification.DEFAULT_VIBRATE);
//设置声音
builder.setDefaults(Notification.DEFAULT_SOUND);
使通知具有导航功能

我们发送的通知,理所应当该有一个动作,点击通知后跳转到某个界面(QQ 点击消息通知后跳转到聊天界面), 而不仅仅只是用来显示消息来的.

最主要的知识是PendingIntent

从字面上来解释就是: 延迟的意图

可以看做是对Intent的一种封装,因为PendingIntent中包含Intent和所需的Context环境,所以,创建PendingIntent的对象被销毁后,也不会影响到PendingIntent的执行。

获取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)

flag 参数

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的 PendingIntent 对象,系统将不会创建该 PendingIntent 对象而是直接返回 null 。

FLAG_ONE_SHOT:该 PendingIntent 只作用一次。

FLAG_UPDATE_CURRENT:如果系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。

public void click(View view) {
    //创建一个notification
    Notification.Builder nBuilder = new Notification.Builder(this).
            setSmallIcon(R.drawable.notification).
            setContentTitle("The is a notification!").
            setContentText("The is notification!The is notification!The is notification!The is notification!");
    //设置导航功能
    Intent intent = new Intent(this, this.getClass());
    REQUEST_CODE = 1;
    PendingIntent pi = PendingIntent.getActivities(this, REQUEST_CODE, new Intent[]{intent}, PendingIntent.FLAG_ONE_SHOT);
    nBuilder.setContentIntent(pi);
    
    //获取通知管理者
    NotificationManager nManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    /*
    * 发送通知
    * id: 用于更新通知
    * notification: 要发送的广播
    * */
    nManager.notify(1, nBuilder.build());
}
保留Activity返回栈

有时候,我们发送了一个通知,我们通过这个通知,跳转到时候Activity中,但是,我们又想,让我们的用户继续停留在我们的应用中。

对比

普通的方式进行导航

保留activity栈的方式

配置xml文件

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<!--Android 4.1 及以上的写法 -->
<activity
    android:name=".SecondActivity"
    android:parentActivityName=".MainActivity">
    <!--&lt;!&ndash;为了兼容 4.0.3版本&ndash;&gt;-->
    <!--<meta-data-->
        <!--android:name="android.support.PARENT_ACTIVITY"-->
        <!--android:value=".MainActivity" />-->
</activity>

程序实现

public void click(View view) {
    //创建一个notification
    nBuilder = new Notification.Builder(this).
            setSmallIcon(R.drawable.notification).
            setContentTitle("The is a notification!").
            setContentText("The is notification!The is notification!The is notification!The is notification!");
    //获取通知管理者
    NotificationManager nManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    Intent intent = new Intent(this, SecondActivity.class);
    //实例化堆栈创建者
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    //添加返回栈
    stackBuilder.addParentStack(SecondActivity.class);
    //将我们的意图添加到返回栈的顶部
    stackBuilder.addNextIntent(intent);
    //获取PendingIntent的对象
    PendingIntent pi = stackBuilder.getPendingIntent(this.REQUEST_CODE, PendingIntent.FLAG_UPDATE_CURRENT);
    
    nBuilder.setContentIntent(pi);
    nManager.notify(this.UPDATE_ID, nBuilder.build());
}

更新通知

更新通知时,我们就需要,上放我们调用nManager.notify(id,notification)方法时传递的ID了,如果该通知存在就更新该通知,如果不存在就创建新的通知。

public class MainActivity extends AppCompatActivity {

    private int REQUEST_CODE = 1;
    private final int UPDATE_ID = 1;
    private Notification.Builder nBuilder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void click(View view) {
        //创建一个notification
        nBuilder = new Notification.Builder(this).
                setSmallIcon(R.drawable.notification).
                setContentTitle("The is a notification!").
                setContentText("The is notification!The is notification!The is notification!The is notification!");
        //获取通知管理者
        NotificationManager nManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        /*
        * 发送通知
        * id: 用于更新通知
        * notification: 要发送的广播
        * */
        nManager.notify(this.UPDATE_ID, nBuilder.build());
    }

    //更新通知
    public void clickUpdate(View view) {
        nBuilder.setContentTitle("更新后的标题");
        NotificationManager nManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        nManager.notify(this.UPDATE_ID, nBuilder.build());
    }

}

删除通知

  1. 点击通知栏的清除按钮,会清除所有可清除的通知
  2. 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,点击该通知时会清除它
  3. 通过 NotificationManager 调用 cancel(int id) 方法清除指定 ID 的通知
  4. 通过 NotificationManager 调用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
  5. 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知

进度条通知

//参数: 最大值,当前值,是否是模糊的
nBuilder.setProgress(100, 50, true);

自定义通知

我们要使用自定义通知来实现下图这样的一个通知。

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF151515"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_Title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dp"
        android:text="您的彩票中奖了"
        android:textColor="@color/notificationTextColor"
        android:textSize="18dp" />

    <TextView
        android:id="@+id/tv_Content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_Title"
        android:layout_marginLeft="6dp"
        android:text="您的彩票xxxx中了500W,请赶快领取!"
        android:textColor="@color/notificationTextColor"
        android:textSize="13dp" />

    <Button
        android:id="@+id/btn_View"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="领取"
        />
</RelativeLayout>

代码实现

//显示自定义通知栏
public void clickCustom(View view) {
    /*
    * 远程视图
    * 从我们预先定义好的布局文件中,加载我们的自定义notification的布局
    * */
    RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.layout_custom_notification_money);

    //设置自定义布局的内容
    views.setTextViewText(R.id.tv_Title, "您的彩票中奖了500w");
    views.setTextViewText(R.id.tv_Content, "领奖暗号是:天王盖地虎!");
    //虽然我们的 btn_View 是按钮,但是他是继承是我们的TextView所以设置Button的text时,也是按照textview的方式来设置
    views.setTextViewText(R.id.btn_View, "暴富");

    //为按钮设置点击事件
    Intent intent = new Intent(this, MoneyActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivities(this, 1, new Intent[]{intent}, PendingIntent.FLAG_UPDATE_CURRENT);
    views.setOnClickPendingIntent(R.id.btn_View, pendingIntent);

    Notification.Builder builder = new Notification.Builder(this);
    builder.setContent(views);
	
    //这行代码一定要保留,我们要用它来显示我们通知的icon,如果不设置就会报错的。
    builder.setSmallIcon(R.drawable.notification);

    NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(1, builder.build());
}

源码下载

http://git.oschina.net/ShareKnowledge/StudyNotification

posted @ 2017-07-12 10:21  鲁迅认识的那只猹  阅读(435)  评论(0编辑  收藏  举报