android消息通知Noticication使用详解

这篇博客主要介绍了Android中Notification的使用,包括系统默认布局和自定义布局的实现方式。讲解了如何获取NotificationManager,创建Notification对象,设置PendingIntent,并区分了Intent和PendingIntent的区别。文中还给出了使用自定义布局的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本人为android的新手,如果有写的不对的地方,希望各路大神多多指教哈。。。

我们经常遇见的Noticication的例子,莫过于使用qq时,手机状态栏会显示有多少条消息处于未读状态。Notification类就是实现这样的功能。

Notification通知的布局有两种:

1.使用系统默认的布局


2.使用自定义的布局


首先使用系统默认布局:

1.首先获取NotificationManager对象。NotificationManager是系统提供的服务


2.创建Notification类对象

Notification notification = new Notification.Builder(MainActivity.this)  //1
        .setAutoCancel(true)                                             //2
        .setTicker("新消息...")                                           //3
        .setSmallIcon(R.drawable.notificationsmall)                      //4                                      //5
        .setContentTitle("笑递消息")                                      //5
        .setContentText("笑递笑递内容")                                    //6
        .setContentIntent(pendingIntent)                                  //7
        .setNumber(i)                                                     //8
        .setLargeIcon(bitmap)                                             //9
        .setWhen(System.currentTimeMillis())                              //10
        .build();                                                         //11
根据上图中的每一行后面的数字匹配

对应上面的3

这里的3是对应设置的数据,注解第八行,3上面的就是第10行的setWhen

相应的解释:

2.设置可以在下拉状态栏中通过滑动取消通知

4.设置小图标一定要有

7.设置在下拉状态栏点击通知后跳转到相应的界面

这里使用的是PendingIntent.

下面解释一下PendingIntent 和Intent的区别

Intent和PendingIntent的区别,PendingIntent可以看做是对Intent的包装,通过名称可以看出PendingIntent用于处理即将发生的意图,而Intent用来处理马上发生的意图。而对于通知来说,它是一个系统级的全局的通知,并不确定这个意图被执行的时间。当在应用外部执行PendingIntent时,因为它保存了触发App的Context,使得外部App可以如果当前App一样执行PendingIntent里的Intent,就算执行时触发通知的App已经不存在了,也能通过存在PendingIntent里的Context照常执行Intent,并且还可以处理Intent所带来的额外的信息。
  PendingIntent提供了多个静态的getXxx()方法,用于获得适用于不同场景的PendingIntent对象。一般需要传递的几个参数都很常规,只介绍一个flag参数,用于标识PendingIntent的构造选择:
FLAG_CANCEL_CURRENT:如果构建的PendingIntent已经存在,则取消前一个,重新构建一个。
FLAG_NO_CREATE:如果前一个PendingIntent已经不存在了,将不再构建它。
FLAG_ONE_SHOT:表明这里构建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果构建的PendingIntent已经存在,则替换它,常用。

下面说明如何构建PendingIntent对象:

Intent intent = new Intent(MainActivity.this,Main2Activity.class);
Intent intent2 = new Intent(MainActivity.this,Main3Activity.class);
/**
 * 表示启动两个,是按照顺序启动的
 *
 */
Intent intentlist[] = new Intent[]{intent,intent2};

PendingIntent pendingIntent = PendingIntent.getActivities(MainActivity.this,0,
        intentlist,PendingIntent.FLAG_UPDATE_CURRENT);
1.首先定义相应的Intent

2.然后定义Intent[]数组,把Intent对象放到数组中。数组中所有Intent在点击通知后都会执行,是按照顺序执行

3.通过PendingIntent的get方法获取PendingIntent对象。

四个参数的意思:



最后一步使用NotificationManager通知我们定义的Notification对象


在这里,大家可能发现有一个大写的常量,这个是我定义的


定义这个的用途主要是唯一的标志这个Notification通知。

当NotificationManager使用同样的标志通知Notification对象时,之前的是这个标志的Notification对象就会被现在这个Notification对象更新。

也就是说同一个标志只能发送一个通知,后发送的会更新之前发送的。

但是使用不同的标志可以再发送另一个通知。

if(i==1)
    nm.notify(111,notification);
else
nm.notify(NOTIFICATION_ID,notification);

使用自定义的布局实现Notification

在开始前,大家要了解一个情况:
  • 通知也可以使用自定义的XML来自定义样式,但是对于通知而言,因为它的全局性,并不能简单的通过inflate膨胀出一个View,因为可能触发通知的时候,响应的App已经关闭,无法获取当指定的XML布局文件。所以需要使用单独的一个RemoteViews类来操作。
      RemoteViews,描述了一个视图层次的结构,可以显示在另一个进程。层次结构也是从布局文件中“膨胀”出一个视图,这个类,提供了一些基本的操作求改其膨胀的内容。
      RemoteViews提供了多个构造函数,一般使用RemoteViews(String packageName,int layoutId)。第一个参数为包的名称,第二个为layout资源的Id。当获取到RemoteViews对象之后,可以使用它的一系列setXxx()方法通过控件的Id设置控件的属性。最后使用NotificationCompat.Builder.setContent(RemoteViews)方法设置它到一个Notification中。
    • 例子代码:
RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout);
remoteViews.setImageViewResource(R.id.id_image_view,R.drawable.notification);
remoteViews.setTextViewText(R.id.id_txt1,"文本1");
remoteViews.setTextViewText(R.id.id_txt2,"文本2");
remoteViews.setTextViewText(R.id.id_txt3,"文本3");

Intent intent = new Intent(MainActivity.this,Main2Activity.class);
//Intent额外绑定的数据
intent.putExtra("data","shuju1");
Intent intent2 = new Intent(MainActivity.this,Main3Activity.class);
intent2.putExtra("data","shuju2");
Intent intentlist[] = new Intent[]{intent,intent2};

PendingIntent pendingIntent = PendingIntent.getActivities(MainActivity.this,0,
        intentlist,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(MainActivity.this)
        .setAutoCancel(true)
        .setTicker("新消息...")
        .setSmallIcon(R.drawable.notificationsmall)//就算是自定义的视图也必须要
        .setContent(remoteViews)
        .setContentIntent(pendingIntent).build();
if(i==1)
    nm.notify(111,notification);
else
    nm.notify(NOTIFICATION_ID,notification);
i++;
从上面的代码可以看出,使用自定义布局时
可以不设置一下内容
.setContentTitle("笑递消息")                                      
.setContentText("笑递笑递内容")                                    
.setNumber(i)                                                     
.setLargeIcon(bitmap)                                             
.setWhen(System.currentTimeMillis())  
点击通知后看到的内容:
也就是最先显示的就是intentlist数组中的最后一个,当点击返回键后:

回到的intentlist数组的第一个intent中封装的activity。这里也验证的上面的说法。会将intentlist中的intent所包含的activity依次打开。

下面上整个程序的代码:

主程序类:

package com.example.notificationtest;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private final int NOTIFICATION_ID=0x123;

    private NotificationManager nm;

    private Button btn1;
    private Button btn2;
    private Button btn3;

    private Bitmap bitmap = null;

    private int i = 0;

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

        nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        initView();

        initEvent();
    }

    private void initEvent() {
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent(MainActivity.this,Main2Activity.class);
                Intent intent2 = new Intent(MainActivity.this,Main3Activity.class);
                /**
                 * 表示启动两个,是按照顺序启动的
                 *
                 */
                Intent intentlist[] = new Intent[]{intent,intent2};

                PendingIntent pendingIntent = PendingIntent.getActivities(MainActivity.this,0,
                        intentlist,PendingIntent.FLAG_UPDATE_CURRENT);


                Notification notification = new Notification.Builder(MainActivity.this)
                        .setAutoCancel(true)
                        .setTicker("新消息...")
                        .setSmallIcon(R.drawable.notificationsmall)                                                            //5
                        .setContentTitle("笑递消息")
                        .setContentText("笑递笑递内容")
                        .setNumber(i)
                        .setLargeIcon(bitmap)
                        .setWhen(System.currentTimeMillis())
                        .setContentIntent(pendingIntent)
                        .build();
                if(i==1)
                    nm.notify(111,notification);
                else
                nm.notify(NOTIFICATION_ID,notification);

                i++;
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout);
                remoteViews.setImageViewResource(R.id.id_image_view,R.drawable.notification);
                remoteViews.setTextViewText(R.id.id_txt1,"文本1");
                remoteViews.setTextViewText(R.id.id_txt2,"文本2");
                remoteViews.setTextViewText(R.id.id_txt3,"文本3");

                Intent intent = new Intent(MainActivity.this,Main2Activity.class);

                intent.putExtra("data","shuju1");
                Intent intent2 = new Intent(MainActivity.this,Main3Activity.class);
                intent2.putExtra("data","shuju2");
                Intent intentlist[] = new Intent[]{intent,intent2};

                PendingIntent pendingIntent = PendingIntent.getActivities(MainActivity.this,0,
                        intentlist,PendingIntent.FLAG_UPDATE_CURRENT);
                Notification notification = new Notification.Builder(MainActivity.this)
                        .setAutoCancel(true)
                        .setTicker("新消息...")
                        .setSmallIcon(R.drawable.notificationsmall)//就算是自定义的视图也必须要
                        .setContent(remoteViews)
                        .setContentIntent(pendingIntent).build();
                if(i==1)
                    nm.notify(111,notification);
                else
                    nm.notify(NOTIFICATION_ID,notification);
                i++;
            }
        });

        btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                nm.cancel(NOTIFICATION_ID);
                nm.cancel(111);
                Toast.makeText(MainActivity.this,""+NOTIFICATION_ID,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initView() {
        btn1 = (Button) findViewById(R.id.id_btn1);
        btn2 = (Button) findViewById(R.id.id_btn2);
        btn3 = (Button) findViewById(R.id.id_btn3);

        bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.notification);


    }
}
第二个activity

package com.example.notificationtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextPaint;
import android.widget.TextView;

public class Main2Activity extends AppCompatActivity {

    private TextView textView;

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

        textView = (TextView) findViewById(R.id.id_shuju1);

        textView.setText(getIntent().getStringExtra("data"));
    }
}


第三个activity

package com.example.notificationtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class Main3Activity extends AppCompatActivity {

    private TextView textView;

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

        textView = (TextView) findViewById(R.id.id_shuju2);

        textView.setText(getIntent().getStringExtra("data"));
    }
}
主布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

    <Button
        android:id="@+id/id_btn1"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="简单通知"/>

    <Button
        android:id="@+id/id_btn2"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="自定义通知"/>

    <Button
        android:id="@+id/id_btn3"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="取消通知"/>
</LinearLayout>
第二个activity布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
    <TextView
        android:id="@+id/id_shuju1"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="diergejiemian"/>

</LinearLayout>
第三个activity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
    <TextView
        android:id="@+id/id_shuju2"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="第三个界面"/>

</LinearLayout>
自定义通知的布局文件layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/id_image_view"
        android:layout_width="64dp"
        android:layout_height="64dp" />
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="64dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:layout_marginRight="10dp">

        <TextView
            android:id="@+id/id_txt1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
        <TextView
            android:id="@+id/id_txt2"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
        <TextView
            android:id="@+id/id_txt3"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

源码


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值