Android -Notification

这里写图片描述
这里写图片描述

1. 创建notification

Notification.Builder builder = new Notification.Builder(this)
        .setSmallIcon(R.id.icon)
        .setContentTitle("标题")
        .setContentText("详细文本");

通过Builder模式创建Notification.Builder实例,有了builder对象,可以给它添加各种属性,例如标题,内容,图标等

2. 定义Action

给点击Notification后要执行的操作增加一个Intent,由于这个Intent不是马上就执行的,而是有用户触发的,所以Android给这样的Intent提供了一个延迟意图PendingIntent来帮助我们完成这样的操作

PendingIntent的使用非常简单,只需要在Intent的基础上包装一层就可以了,代码如下所示

Intent resultIntent = new Intent(this, ResultActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

这样当点击Notification后,就会触发PendingIntent事件,跳转到指定的Activity

3. 设置点击事件

builder.setContentIntent(resultPendingIntent);

注意事项:当点击通知跳转到Activity的时候,Activity会重新走生命周期,想要保持原来的状态,需要给Activity配置一个launchMode = “singleTask”

4. 发送通知

通过NotificationManager通知管理器的notify()方法来发送Notification,并给Notification一个id值,这个id会在更新Notification的时候用到

NotificationManager mNotifyMgr =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int mNotificationId = 001;
mNotifyMgr.notify(mNotificationId, builder.build());

5. 使用BigView样式

Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_notification)
                .setContentTitle(getString(R.string.notification))
                .setContentText(getString(R.string.ping))
                .setDefaults(Notification.DEFAULT_ALL)
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(msg))
                .addAction (R.drawable.ic_stat_dismiss,
                        getString(R.string.dismiss), piDismiss)
                .addAction (R.drawable.ic_stat_snooze,
                        getString(R.string.snooze), piSnooze);

6. 显示Notification进度

int id = 1;
...
NotificationManager mNotifyManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuilder = new Notification.Builder(this);
mBuilder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification);

new Thread(new Runnable() {
            @Override
            public void run() {
                int i;

                for (i = 0; i <= 100; i+=5) {
                    mBuilder.setProgress(100, i, false);
                    mNotifyManager.notify(id, mBuilder.build());
                    Thread.sleep(5*1000);
                }

                mBuilder.setContentText("Download complete")
                        .setProgress(0,0,false);
                mNotifyManager.notify(id, mBuilder.build());
            }
        }
).start();

7. 更新通知

根据id来更新通知

8. 自定义通知布局

Notification的自定义布局通过RemoteViews去实现,调用Notification.Builder的setCustomContentView()方法设置自定义的布局

  //通过RemoteViews来创建自定义的Notification视图
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.tv, "show me when collapsed");

Notification.Builder builder = new Notification.Builder(this)
                .setCustomContentView(contentView);

折叠式Notification

折叠式Notification 也是一种自定义视图的Notification ,常常用于显示长文本。它拥有两个视图状态, 一个是普通状态下的视图状态, 另一个是展开状态下的视图状态。在Notitication中,使用RemoteViews 来帮助我们创建一个自定义的Notification 视图,代码如下所示。

 //通过RemoteViews来创建自定义的Notification视图
        RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.notification);
        contentView.setTextViewText(R.id.tv,"show me when collapsed");

悬挂式Notification

这里写图片描述

触发悬挂式的Notification的条件有

  • Activity处于全屏模式
  • Notification拥有很高的优先级
Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setCategory(Notification.CATEGORY_MESSAGE)
                .setContentTitle("Headsup Notification")
                .setContentText("I am Headsup Notification");

Intent push = new Intent();
push.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
push.setClass(this,MainActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(
        this,0,push,PendingIntent.FLAG_CANCEL_CURRENT);

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

Notification的显示等级

Android 5.x 将Notification分成了三个等级

  • VISIBILITY_PRIVATE:表面只有当没有锁屏的时候才能够显示
  • VISIBILITY_PUBLIC:表明任何情况下都会显示
  • VISIBILITY_SECRET:表明在pin,password等安全锁和没有锁屏的情况下才能够显示

设置Notification的显示等级

Notification.Builder builder = new Notification.Builder(this)
               .setVisibility(Notification.VISIBILITY_PRIVATE);

9. 创建一个常规的activity延迟意图

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>

为Intent创建一个回退栈

...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

10. 创建一个特别的activity延迟意图

<activity
        android:name=".ResultActivity"
    ...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
...

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

Intent notifyIntent = new Intent(this, ResultActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
        | Intent.FLAG_ACTIVITY_CLEAR_TASK);

PendingIntent notifyPendingIntent =
        PendingIntent.getActivity(
                this,
                0,
                notifyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

builder.setContentIntent(notifyPendingIntent);

NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

mNotificationManager.notify(id, builder.build());

11、Android 7.0 通知新特性

在Android N中重新设计了通知,可以达到更容易、更快使用的效果。一些主要的变化包括:

模板更新:更新了通知模板重点内容和头像。开发者将能够利用的新模板的优势,在他们的代码中实现最低限度的调整。

捆绑通知:Android N的通知功能也更加人性化,现在会自动将相同应用的通知捆绑在一起,实现分组显示,并且通过两指滑动实现预览,理论上用户可以在通知界面直接阅读邮件等内容。

直接回复:对于实时通信应用程序,Android系统支持在线回复,使用户可以以短信或短信通知界面内快速、直接响应。

自定义视图:两个新的 API 让用户在通知中使用自定义视图。

这里写图片描述

Android N 开发者预览版的通知系统中还加入了两个全新的 API 接口:Direct Replies 和 Bundling。前者支持为第三方应用的通知加入快速回复和快捷操作,后者则允许同时发出多条通知的应用进行通知拆分。

当一款应用完美的适配了 Android N,当收到一条消息时就可以直接在下拉通知抽屉甚至是锁屏中直接呼出输入框进行回复,或是选择事先设定好的快速处理操作(标记为已读、转发等)。而当用户同时收到来自不同联系人的消息时,可以点击知卡片上的通知拆分按钮对已经合并的通知进行拆分,拆分后的通知可以像其他的独立通知一样进行回复和处理。

当然,现阶段适配了这两个特性的应用屈指可数,除了 Google 的环聊、Messenger 以及 Gmail 等应用以外,目前仅发现第三方 Telegram 客户端 Plus Messenger 支持以上功能。

面对各种应用的通知推送, Android N取以优先级为核心的通知管理方式,而在 Android N中,通知管理也变得更加简单:只需在需要在相应的通知上左右轻扫便能看见一个设置图标,点击该图标就能在通知上方呼出一个简洁的通知优先级设定界面,在这个界面可以将应用通知设定为“静默显示”、“阻拦所有通知”和“默认”三个等级。

这里写图片描述

如果在”系统界面调谐器 - 其它“中打开了”Show full importance settings”功能,这三个等级又将变为”屏蔽 - 低 - 一般 - 高 - 紧急”5 个,设定的方式也由纵列选项变为左右滑动。这个看似新颖的设计实际上是对现有通知管理操作的一次简化,在 Android 6.0 中需要在两个界面来回跳转才能完成的操作,在Android 7.0只用在一个界面就可以搞定。

同时,Google 也将其对通知优先级的定义从”幕后”搬到了”台前”,在进行完整的五层次优先级设定时 Google 还会提醒不同优先级所对应的通知效果。最后,勿扰模式也在 Android N 中得到了完善,加入了自动规则并允许用户在“请勿打扰”模式下屏蔽静音通知的弹窗甚至是手机的通知指示灯。

发送一个通知

private int i = 0;
private NotificationManager mNotificationManager;
private static final String GROUP_NAME = "com.heima.notification_type";

//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
        Context.NOTIFICATION_SERVICE);
//[2]创建一个Notification
//[2.1]需要给这个Notification对象指定icon,标题,内容,
final Notification builder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.mipmap.ic_notification)
        .setContentTitle(getString(R.string.app_name))
        .setContentText("这是一个消息通知")
        .setAutoCancel(true)
        .setGroup(GROUP_NAME)
        .build();
//[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
mNotificationManager.notify(i++, builder);
updateNotificationSummary(); 

多个通知放入到一个组内

//[4]创建一个notification组
String notificationContent = "传智播客" + i;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
        .setSmallIcon(R.mipmap.ic_notification)
        .setStyle(new NotificationCompat.BigTextStyle()
                .setSummaryText(notificationContent))
        .setGroup(GROUP_NAME)
        .setGroupSummary(true);
final Notification notification = builder.build();
//[5]发送这个notification组
mNotificationManager.notify(101, notification); 

可以回复的通知

private NotificationManager mNotificationManager;
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
        Context.NOTIFICATION_SERVICE);
//[2]创建remoteInput对象,这个对象指定了这个notification的标题和一个key
String replyLabel = getResources().getString(R.string.app_name);
RemoteInput remoteInput = new RemoteInput.Builder("heima")
        .setLabel(replyLabel)
        .build();
//[3]创建一个Action对象 可以指定用户一个友好的输入提示,可以指定跳转意图,
Intent deleteIntent = new Intent("");
Notification.Action action =
        new Notification.Action.Builder(R.mipmap.ic_launcher,
                "请输入内容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
                .addRemoteInput(remoteInput)
                .build();

//[3]创建一个Notification对象
Notification notification =
        new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_notification)
                .setContentTitle("传智播客")
                .setContentText("消息通知")
                .addAction(action)
                .build();

//[4]发送这个notification 
mNotificationManager.notify(1, notification);
public class MainActivity extends Activity {
    private int i = 0;
    private NotificationManager mNotificationManager;
    private static final String GROUP_NAME = "com.heima.notification_type";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sendNotification(View v){
        //[1]获取一个NotificationManager
        mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        //[2]创建一个Notification
        //[2.1]需要给这个Notification对象指定icon,标题,内容,
        final Notification builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("这是一个消息通知")
                .setAutoCancel(true)
                .setGroup(GROUP_NAME)
                .build();
        //[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
        mNotificationManager.notify(i++, builder);
    }

    public void sendGroup(View v){

        //[1]获取一个NotificationManager
        mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        //[2]创建一个Notification
        //[2.1]需要给这个Notification对象指定icon,标题,内容,
             final Notification builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_notification)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("这是一个消息通知")
                .setAutoCancel(true)
                .setGroup(GROUP_NAME)
                .build();
        //[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
        mNotificationManager.notify(i++, builder);

        //[4]创建一个notification组
        String notificationContent = "传智播客" + i;
        final NotificationCompat.Builder builder1 = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_notification)
                .setStyle(new NotificationCompat.BigTextStyle()
                        .setSummaryText(notificationContent))
                .setGroup(GROUP_NAME)
                .setGroupSummary(true);
        final Notification notification = builder1.build();
        //[5]发送这个notification组
        mNotificationManager.notify(101, notification);

    }

    public void send(View v){

        //[1]获取一个NotificationManager
        mNotificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        //[2]创建remoteInput对象,这个对象指定了这个notification的标题和一个key
        String replyLabel = getResources().getString(R.string.app_name);
        RemoteInput remoteInput = new RemoteInput.Builder("heima")
                .setLabel(replyLabel)
                .build();
        //[3]创建一个Action对象 可以指定用户一个友好的输入提示,可以指定跳转意图,
        Intent deleteIntent = new Intent(this,MainActivity.class);
        Notification.Action action =
                new Notification.Action.Builder(R.mipmap.ic_launcher,
                        "请输入内容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
                        .addRemoteInput(remoteInput)
                        .build();

        //[3]创建一个Notification对象
        Notification notification =
                new Notification.Builder(this)
                        .setSmallIcon(R.mipmap.ic_notification)
                        .setContentTitle("传智播客")
                        .setContentText("消息通知")
                        .addAction(action)
                        .build();

        //[4]发送这个notification
        mNotificationManager.notify(1, notification);

    }
}

http://android.xsoftlab.net/guide/topics/ui/notifiers/notifications.html#CustomNotification

http://android.xsoftlab.net/design/patterns/notifications.html

自定义Notification

布局文件

<?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="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="自定义的notification" />

    <ProgressBar
        android:id="@+id/progressBar1"
        android:max="100"
        android:progress="50"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

实现代码

public class DemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void click(View view){
        System.out.println("haha");
        //1.创建notification 的管理器
        NotificationManager manager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
        //2 .创建notification的实例
        Notification notification = new Notification();
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.icon = R.drawable.ic_launcher;
        notification.tickerText="自定义notification";
        //notification.contentView;
        //远程的view  我们的view对象 是要显示在另外一个进程里面 另外一个程序里面 所以就需要一个remote  view
        RemoteViews rv = new RemoteViews(getPackageName(), R.layout.custom_notification);
        rv.setTextViewText(R.id.textView1, "textview 自定义notification");
        rv.setProgressBar(R.id.progressBar1, 100, 50, false);

        notification.contentView = rv;
        Intent intent = new Intent(this,DemoActivity.class);
        PendingIntent  pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
        notification.contentIntent = pendingIntent;

        manager.notify(2, notification);

    }
}
源码位置
https://github.com/JiangHaiYang01/NotificationDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容