美文网首页Android基础知识Android开发Android开发
【Android】23.0 手机多媒体(一)——通知(Notif

【Android】23.0 手机多媒体(一)——通知(Notif

作者: bobokaka | 来源:发表于2019-02-21 20:05 被阅读5次
1.0 通知(Notification),这个内容网上可以找到很多介绍,但是:
  • 要么都没有更新到Android O(API 26,Android 8)系统以上.
  • 要么篇幅太短,打油诗级别的介绍
  • 要么一篇博文全部怼完,乱七八糟不说,理解起来不知道从哪捋思路。
  • 也因为Android版本更新的原因,一些方法被弃用,导致现如今网上的很多关于 通知(Notification)的代码无法顺利编译,或者用Android studio编写时,方法上已经划横线了。
  • 事实上面对国内各种深度定制的Android系统,通知(Notification)可能存在其他乱七八糟的缺陷
    备注:所以,本篇更新至今天,最新版本(2019-02-21)
2.0 本篇主要是通过一个简单的项目实现顺利地发出一条状态栏通知,会尽量在项目中精简代码,将系统性的理论知识放最后分类补充。

可参考文章:
链接:Android Notification 详解
链接:# Android 通知栏Notification的整合全面学习
链接:Android通知栏(Notification)介绍及使用

3.0 新建一个项目,Notificationtest,目录如下:
2019-02-21_165013.png

备注:为什么不把源代码上传到Gittub?因为Android编程的尿性,更新换代很快,今天能运行的代码,明天不一定能跑得起来(而且配置文件超多)。所以习惯性展示目录和代码,可以避免某些参考时可能存在的版本兼容问题。

4.0 布局文件中就一个控件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/send_notice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="发送通知"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.05" />

</android.support.constraint.ConstraintLayout>
5.0 划线的重点来了,需要解决新版本的兼容问题

由于升级到Android O(安卓欧,不是安卓零)版本后,一些方法被弃用,而且Android O引入了通知渠道Notification Channels),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道(就是要new NotificationChannel()),以向用户显示通知。比如聊天软件,为每个聊天组设置一个通知渠道,指定特定声音、灯光等配置。

6.0 先解决状态栏通知显示需要干什么,再解决考虑到Android O版本还需要做什么。
6.1 通知显示需要3步走
  • 1.第1步:获取状态通知栏管理:
  • 2.第2步:实例化通知栏构造器NotificationCompat.Builder
  • 3第3步:对Builder进行配置:
    (第3步和第2步之间本来还有1步的,但是不是必要,放下一章讲解——通知栏点击事件处理

6.1.1 状态栏通知的管理类 NotificationManager,负责发通知、清除通知等操作。

注意:NotificationManager是一个系统Service,
所以必须通过 getSystemService (NOTIFICATION_SERVICE)方法来获取。

6.1.2 实例化通知栏构造器通过声明Notification

一个 Notification 的必要属性有三项,如果不设置则在运行时会抛出异常:

  • 小图标,通过 setSmallIcon()方法设置
  • 标题,通过 setContentTitle()方法设置
  • 内容,通过 setContentText()方法设置

除了这3种还有:

  • setWhen() 通知产生的时间。会在通知信息里显示,通常是系统获取到的时间:setWhen( System.currentTimeMillis() )
  • setLargeIcon() 设置通知大ICON
  • setPriority 设置通知优先级
  • setOngoing(false) 设置它为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
  • setNumber( ) 设置通知集合的数量
  • setStyle( ) 设置
  • setAutoCancel(true) 设置这个标志当用户单击面板就可以让通知将自动取消(手机QQ就是设置成false,所以你在通知栏总是取消不掉它)
  • setTicker( ) 设置通知首次出现在通知栏,带上升动画效果的
  • setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL)) 设置设置通知栏点击意图
  • setDefaults(int defualts) 为了精简学习难度,Notification 的通知效果知识点本章不写。(通过setDefaults(int defualts)方法来设置。一旦设置了Default 效果,自定义的效果就会失效。Default 效果可以相互组合)

    6.1.3 第3步,只需要调用NotificationManagernotify()方法就可以让通知显示出来。

notify()方法接收2个参数:

  • 第一个参数是id,保证每个通知的id都是不一样的。
  • 第二个参数是指Notification对象,将第二步建好的Notification对象传入即可。这样显示一个通知就可以写成:
 NotificationManager manager =
                        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification notification = null;
...
manager.notify(1, notification);

OK,理论讲完,继续往下走

7.0 综合上面理论知识,下面MainActivity.java中的代码,看懂就没什么大问题了。
package com.example.notificationtest;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private String id = "channel_001";
    private String name = "name";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button sendNotice = (Button) findViewById(R.id.send_notice);
        sendNotice.setOnClickListener(this);
    }

    @RequiresApi(api =26)
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.send_notice:

                //第一步:获取状态通知栏管理:

                NotificationManager manager =
                        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification notification = null;
                //第二步:实例化通知栏构造器NotificationCompat.Builder:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断API
                    NotificationChannel mChannel = new NotificationChannel(id, name,
                            NotificationManager.IMPORTANCE_LOW);
                    manager.createNotificationChannel(mChannel);

                    notification = new NotificationCompat.Builder(this, id)

                            .setContentTitle("这是一个内容标题")//设置通知栏标题
                            .setContentText("这是一个内容文本") //设置通知栏显示内容
                            .setWhen(System.currentTimeMillis())//通知产生的时间。
                            // 会在通知信息里显示,通常是系统获取到的时间
                            .setSmallIcon(R.mipmap.ic_launcher)//设置通知小ICON
                            .setLargeIcon(BitmapFactory.decodeResource(getResources()
                                    , R.mipmap.ic_launcher))//设置通知大ICON
                            .build();
                } else {
                    NotificationCompat.Builder notificationBuilder =
                            new NotificationCompat.Builder(this, id)
                                    .setContentTitle("这是一个内容标题")
                                    .setContentText("这是一个内容文本")
                                    .setSmallIcon(R.mipmap.ic_launcher)
                                    .setLargeIcon(BitmapFactory.decodeResource(getResources()
                                            , R.mipmap.ic_launcher));
//                                    .setOngoing(true);
                    notification = notificationBuilder.build();
                }
                //第三步:对Builder进行配置:
                manager.notify(1, notification);
                break;
            default:
                break;
        }
    }
}

需要注意的两个方面:

  • 用的实现implements关键字实现监控的接口,这是因为在经常用的内部类中,用NotificationCompat.Builder(Context context, String channelId)报错……
  • 网上代码基本都是用NotificationCompat.Builder(Context context)方法,但这个方法已经弃用,最新版本NotificationCompat.Builder(Context context, String channelId)channelId在一开始就随便申明一个就好……
  • 关于解决Android O兼容性问题,看9.0
8.0 解决Android O版本兼容性问题(好吧,本来想放在6.2的):在Android 8版本及以上按网上大部分的代码来写,是不会显示状态栏通知的。

需要用到如上代码中if语句来处理,记得声明@RequiresApi(api =26)
下面开始解释下这个逻辑,把上面MainActivity.javaif语句代码抄下来如下所示:

  //如果当前Android的版本相比Android O,一样或者版本更高,就建通知渠道(Notification Channels )
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断API
                    //1.0 建渠道
                    NotificationChannel mChannel = new NotificationChannel(id, name,
                            NotificationManager.IMPORTANCE_LOW);
                    //2.0 把通知渠道通过createNotificationChannel( )方法给-
                    //      -状态栏通知的管理类 NotificationManager 
                    manager.createNotificationChannel(mChannel);
                   //3.0 Notification这时候可以正常工作了 
                    notification = new NotificationCompat.Builder(this, id)
                            .setContentTitle("这是一个内容标题")//设置通知栏标题
                            .setContentText("这是一个内容文本") //设置通知栏显示内容
                            .setWhen(System.currentTimeMillis())//通知产生的时间。
                            // 会在通知信息里显示,通常是系统获取到的时间
                            .setSmallIcon(R.mipmap.ic_launcher)//设置通知小ICON
                            .setLargeIcon(BitmapFactory.decodeResource(getResources()
                                    , R.mipmap.ic_launcher))//设置通知大ICON
                            .build();
                } else {
                    //如果当前Android的版本比Android O(API 26)版本要低
                    //直接开始上面的3.0步骤——Notification这时候就可以正常工作了 
                    NotificationCompat.Builder notificationBuilder =
                            new NotificationCompat.Builder(this, id)
                                    .setContentTitle("这是一个内容标题")
                                    .setContentText("这是一个内容文本")
                                    .setSmallIcon(R.mipmap.ic_launcher)
                                    .setLargeIcon(BitmapFactory.decodeResource(getResources()
                                            , R.mipmap.ic_launcher));
//                                    .setOngoing(true);
                    notification = notificationBuilder.build();
                     //为什么if语句里面两个3.0不一样
                     // notification =
                     //       new NotificationCompat.Builder(this, id)
                     //               .setContentTitle("这是一个内容标题")
                     //               .setContentText("这是一个内容文本")
                     //               .setSmallIcon(R.mipmap.ic_launcher)
                     //               .setLargeIcon(BitmapFactory.decodeResource(getResources()
                     //                       , R.mipmap.ic_launcher)).build();
                    //这几行代码就一样了。
                }

如上。

9.0 执行项目(如果你的手机系统版本是Android 8.0.0版本及以上,建议用真机测试,真机测试更自信):

现在Android 9.0.0(API 28)模拟器运行:

2019-02-21_195725.png

点击“发送通知”按钮,最上方标题栏出现一个小白点

2019-02-21_195731.png

下拉状态栏,查看:


2019-02-21_195737.png

接下来在Android 7.0.0(API 24)模拟器运行:

2019-02-21_195831.png

点击“发送通知”按钮,最上方标题栏出现一个小白点

2019-02-21_195837.png

下拉状态栏,查看:


2019-02-21_195844.png
10.0 如果你使用的是Android手机,此时应该会下意识地认为这条通知是可以点击的。

但你去点击的时候,你会发现没有任何效果。它是不会因为你可能是中国人就给你面子的……
可以参考我的下一篇:(未完待续)

END

相关文章

网友评论

    本文标题:【Android】23.0 手机多媒体(一)——通知(Notif

    本文链接:https://www.haomeiwen.com/subject/nthdyqtx.html