Android手把手编写儿童手机远程监控App之通知栏消息2

24 阅读5分钟

概述

上节实现消息通知栏并通过点击消息传递数据跳转页面。消息是App 向用户发送的信息通知机制,它的显示位置包括状态栏、通知栏、锁屏。如微信消息、系统消息等。 在这里插入图片描述

上节嘟宝创建的默认消息,是无法像微信上部弹出消息,而是被收录在不重要消息内容里。app发布消息需要分成三步

  • 创建一个通道,名为channel,该通道被系统记录,可在app中设置通道参数
  • 创建多个消息,共享一个通道。消息需指明通道id,消息标题内容
  • 发布消息

封装消息类

右键com.zilong.dubao>New> Java Class 在这里插入图片描述 NotificationMsg源码

package com.zilong.dubao;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import androidx.core.app.NotificationCompat;
public class NotificationMsg {
    private String channelID="DUBAO";
    private String channelName="嘟宝安心守护孩子安全";
    private Context context;
    private NotificationManager manager=null;
    private  int id=1000;

    NotificationMsg(Context context){
        this.context=context;
    }

    private void createNotificationChannel() {
        manager =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
        manager.createNotificationChannel(channel);
    }
    public void sendNotification(String title,String content) {
        if (manager==null){
            createNotificationChannel();
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelID)
                .setSmallIcon(R.drawable.logo)
                .setContentTitle(title)
                .setContentText(content);
        manager.notify(id, builder.build());
        id++;
    }
    public void sendNotification(String title, String content, Intent intent) {
        if (manager==null){
            createNotificationChannel();
        }
        PendingIntent pendingIntent = PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_IMMUTABLE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelID)
                .setSmallIcon(R.drawable.logo)
                .setContentIntent(pendingIntent)
                .setContentTitle(title)
                .setContentText(content);
        manager.notify(id, builder.build());
        id++;
    }
}

MainActivity源码

package com.zilong.dubao;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
    NotificationMsg notificationMsg=new NotificationMsg(this);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();
    }
    private void initBtn(){
        Button button =findViewById(R.id.sendmsg);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MessageActivity.class);
                intent.putExtra("name","嘟妈101");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                notificationMsg.sendNotification("来自嘟妈的消息","快起床出去玩了",intent);
            }
        });
    }
}

运行效果如下: 在这里插入图片描述

点击按钮发送消息,通知栏不提示有消息,也未有声音与震动。这并非发送消息源码有问题。消息等级均为默认设置。消息等级设置有两处

  • 一在创建通道对消息等级统一设置,默认是有声音,无震动(默认行为),普通通知
  • 二在创建消息时设置消息等级,默认是图片通知。 Android app关于消息通知的设置,在应用程序详情中有两处,不同手机略有不同: 路径:应用设置 > 应用管理 > 嘟宝>通知管理
  • 通知过滤规则,有Andorid 系统自动判断消息显示规则
  • 通知类别,专为通道chanel消息设置
Android 通道优先级
重要性级别	值	行为表现	使用场景
IMPORTANCE_NONE	0	完全不显示,被静默拦截	禁用通知
IMPORTANCE_MIN	1	只显示在通知栏底部,无声音、无震动、无弹出	不重要的后台信息
IMPORTANCE_LOW	2	显示在通知栏,无声音、无震动	低优先级信息
IMPORTANCE_DEFAULT	3	有声音,无震动(默认行为)	普通通知
IMPORTANCE_HIGH	4	有声音、有震动,可能弹出横幅	重要消息
IMPORTANCE_MAX	5	最高优先级(已废弃,等同于 HIGH)	紧急通知


NotificationCompat 提供了以下几种优先级:

优先级	常量	说明
最大	PRIORITY_MAX	最高优先级,可能弹出 Heads-up
高	PRIORITY_HIGH	高优先级,声音/横幅提醒
默认	PRIORITY_DEFAULT	普通通知
低	PRIORITY_LOW	不重要,减少打扰
最低	PRIORITY_MIN	几乎隐藏
无	PRIORITY_NONE	不显示提醒

以下为系统默认设置 在这里插入图片描述 在这里插入图片描述 而后,将过滤规则改为全部设为重要,将悬浮通知权限打开。测试结果如下: 在这里插入图片描述

嘟宝接收绑定信令

嘟宝通过mqtt在后台与服务器 长久连接,嘟妈通过信令与嘟宝交互数据,建立音视频通信。

  • 嘟妈与嘟宝的第一次通信,应从扫描二维码开始。两者交互流程如下:
  • 嘟宝app启动,显示二维码,并启动前台服务建立MQTT连接,订阅主题/dubao/dubaoID
  • 嘟妈扫描二维码,向嘟宝发送绑定指令
  • 嘟宝收到绑定指令后,通知栏消息手动确认绑定,发送确认指令给嘟妈
  • 存储绑定信息 当MQTT收到嘟妈的绑定信令时,app发出消息通知栏,引导用户绑定。 嘟宝与嘟妈通信数据格式,选择JSON。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用“键值对”结构来组织数据,具有体积小、可读性强、跨平台等特点,被广泛用于客户端与服务器之间的数据传输。Android、Java、PHP、Python、Web 等开发中都会大量使用 JSON 来存储和交换数据,例如接口返回、配置文件、网络通信等场景。
{"code":"bind","dumaName":"嘟妈","dumaId":"f1122aeb-f2b0-400d-9919-eddd2eaebaa2","dubaoId":"11122aeb-f2b0-400d-9919-eddd2eaeb1f2"}

上述json,code功能指令,dumaName为嘟妈名称,dumaId、dubaoId为嘟宝嘟妈的身份识别码。这是一条嘟妈发送嘟宝请求绑定的信息。嘟宝收到该条信息后,手动确认完成绑定。

json解析

嘟宝通过mqtt接收到是一系列json字符串,然后再将json字符串解析成基本类型数据。Android解析json字符串有两种方式,

  • 一是原生JSONObject
  • 二是通过Gson 解析(实际开发最常用) Gson 是 Google 推出的一个 Java JSON 解析库,用于将Java对象 与 JSON 字符串之间的相互转换。

引入Gson库

入下图: 在这里插入图片描述 点击Sync now,下载同步到工程

Gson解析事例

MainActivity源码

package com.zilong.dubao;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

public class MainActivity extends AppCompatActivity {
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initBtn();
    }

 
    private void initBtn(){
        Button button =findViewById(R.id.sendmsg);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                parseJson();
            }
        });
    }


    class Msg{
        String code;
        String dumaName;
        String dumaId;
        String dubaoId;
    }
    private void parseJson(){
        String json="{\"code\":\"bind\",\"dumaName\":\"嘟妈\",\"dumaId\":\"f1122aeb-f2b0-400d-9919-eddd2eaebaa2\",\"dubaoId\":\"cfb20ccc-8c53-4434-85bb-a171c3ca7c0c\"}";
        Gson gson = new Gson();
        Msg msg = gson.fromJson(json, Msg.class);
        ((TextView)findViewById(R.id.code)).setText(msg.code);
        ((TextView)findViewById(R.id.dumaName)).setText(msg.dumaName);
        ((TextView)findViewById(R.id.dumaId)).setText(msg.dumaId);
        ((TextView)findViewById(R.id.dubaoId)).setText(msg.dubaoId);
    }
}

activity_main源码

<?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:gravity="center_vertical"
    android:orientation="vertical">
    <TextView
        android:id="@+id/code"
        android:text="未有数据"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/dumaName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/dumaId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/dubaoId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/sendmsg"
        android:text="解析"
        android:layout_width="match_parent"
        android:layout_height="100dp"/>

</LinearLayout>

运行结果 在这里插入图片描述