Android Studio App开发之通知渠道NotificationChannel及给华为、小米手机桌面应用添加消息数量角标实战(包括消息重要级别的设置 附源码)

简介: Android Studio App开发之通知渠道NotificationChannel及给华为、小米手机桌面应用添加消息数量角标实战(包括消息重要级别的设置 附源码)

需要全部源码或运行有问题请点赞关注收藏后评论区留言~~~

一、通知渠道NtoificationChannel

为了分清消息通知的轻重缓急,Android8.0新增了通知渠道,并且必须指定通知渠道才能正常推送消息,一个应用允许拥有多个通知渠道,每个渠道的重要性各不相同,有的渠道消息在通知栏被折叠成小行,有的渠道消息在通知栏展示完整的大行,有的会发出铃声甚至震动等等

效果如下 可以输入标题和内容,然后下拉框里面选择消息的重要级别,根据重要级别的不同消息会有不同的通知方式(这里要连接真机才能具体展示 读者可自行连接 或者参考我之前的博客连接步骤)

代码如下

Java类

package com.example.chapter11;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter11.util.NotifyUtil;
import com.example.chapter11.util.ViewUtil;
public class NotifyChannelActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText et_title;
    private EditText et_message;
    private String mChannelId = "0"; // 通知渠道的编号
    private String mChannelName; // 通知渠道的名称
    private int mImportance; // 通知渠道的级别
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notify_channel);
        et_title = findViewById(R.id.et_title);
        et_message = findViewById(R.id.et_message);
        findViewById(R.id.btn_send_channel).setOnClickListener(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            initImportanceSpinner(); // 初始化渠道级别的下拉框
        }
    }
    // 初始化渠道级别的下拉框
    private void initImportanceSpinner() {
        findViewById(R.id.ll_channel).setVisibility(View.VISIBLE);
        ArrayAdapter<String> importanceAdapter = new ArrayAdapter<String>(this,
                R.layout.item_select, importanceDescArray);
        Spinner sp_importance = findViewById(R.id.sp_importance);
        sp_importance.setPrompt("请选择渠道级别");
        sp_importance.setAdapter(importanceAdapter);
        sp_importance.setSelection(3);
        sp_importance.setOnItemSelectedListener(new TypeSelectedListener());
    }
    private int[] importanceTypeArray = {NotificationManager.IMPORTANCE_NONE,
            NotificationManager.IMPORTANCE_MIN,
            NotificationManager.IMPORTANCE_LOW,
            NotificationManager.IMPORTANCE_DEFAULT,
            NotificationManager.IMPORTANCE_HIGH,
            NotificationManager.IMPORTANCE_MAX};
    private String[] importanceDescArray = {"不重要", // 无通知
            "最小级别", // 通知栏折叠,无提示声音,无锁屏通知
            "有点重要", // 通知栏展开,无提示声音,有锁屏通知
            "一般重要", // 通知栏展开,有提示声音,有锁屏通知
            "非常重要", // 通知栏展开,有提示声音,有锁屏通知,在屏幕顶部短暂悬浮(有的手机需要在设置页面开启横幅)
            "最高级别" // 通知栏展开,有提示声音,有锁屏通知,在屏幕顶部短暂悬浮(有的手机需要在设置页面开启横幅)
    };
    class TypeSelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            mImportance = importanceTypeArray[arg2];
            mChannelId = "" + arg2;
            mChannelName = importanceDescArray[arg2];
        }
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    }
    // 发送指定渠道的通知消息(包括消息标题和消息内容)
    private void sendChannelNotify(String title, String message) {
        // 创建一个跳转到活动页面的意图
        Intent clickIntent = new Intent(this, MainActivity.class);
        // 创建一个用于页面跳转的延迟意图
        PendingIntent contentIntent = PendingIntent.getActivity(this,
                R.string.app_name, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        // 创建一个通知消息的建造器
        Notification.Builder builder = new Notification.Builder(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0开始必须给每个通知分配对应的渠道
            builder = new Notification.Builder(this, mChannelId);
        }
        builder.setContentIntent(contentIntent) // 设置内容的点击意图
                .setAutoCancel(true) // 点击通知栏后是否自动清除该通知
                .setSmallIcon(R.mipmap.ic_launcher) // 设置应用名称左边的小图标
                .setContentTitle(title) // 设置通知栏里面的标题文本
                .setContentText(message); // 设置通知栏里面的内容文本
        Notification notify = builder.build(); // 根据通知建造器构建一个通知对象
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotifyUtil.createNotifyChannel(this, mChannelId, mChannelName, mImportance);
        }
        // 从系统服务中获取通知管理器
        NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 使用通知管理器推送通知,然后在手机的通知栏就会看到该消息,多条通知需要指定不同的通知编号
        notifyMgr.notify(Integer.parseInt(mChannelId), notify);
        if (mImportance != NotificationManager.IMPORTANCE_NONE) {
            Toast.makeText(this, "已发送渠道消息", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_send_channel) {
            ViewUtil.hideOneInputMethod(this, et_message); // 隐藏输入法软键盘
            if (TextUtils.isEmpty(et_title.getText())) {
                Toast.makeText(this, "请填写消息标题", Toast.LENGTH_SHORT).show();
                return;
            }
            if (TextUtils.isEmpty(et_message.getText())) {
                Toast.makeText(this, "请填写消息内容", Toast.LENGTH_SHORT).show();
                return;
            }
            // 发送指定渠道的通知消息(包括消息标题和消息内容)
            sendChannelNotify(et_title.getText().toString(), et_message.getText().toString());
        }
    }
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="消息标题:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_title"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_margin="5dp"
            android:background="@drawable/editext_selector"
            android:hint="请填写消息标题"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="消息内容:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_message"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="top"
            android:layout_margin="5dp"
            android:background="@drawable/editext_selector"
            android:hint="请填写消息内容"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/ll_channel"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:visibility="gone">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="渠道级别:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <Spinner
            android:id="@+id/sp_importance"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_margin="5dp"
            android:gravity="center"
            android:spinnerMode="dialog" />
    </LinearLayout>
    <Button
        android:id="@+id/btn_send_channel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="发送渠道消息"
        android:textColor="@color/black"
        android:textSize="17sp" />
</LinearLayout>

二、给桌面应用添加信息角标(以华为和小米为例)

每个应用都可以给用户发送很多消息,通知栏显然有时候不够容纳如此之多的消息,于是各应用希望向用户展现未读消息的数量,好让用户知晓有没有未读消息或者是有几条未读消息。例如微信的99+,几个小红点好有申请之类。

因为各手机厂商对消息角标的实现方案各不相同,因此只能给它们的手机分别适配处理,

下面依次介绍华为和小米系手机的适配编码

华为的消息角标不依赖通知推送,允许单独设置红点的展示情况

小米的消息角标方案则依赖于通知推送,必须在发送通知之时一起传送消息数量参数

效果如下 可自行设置

代码如下

Java类

package com.example.chapter11;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter11.util.NotifyUtil;
import com.example.chapter11.util.ViewUtil;
public class NotifyMarkerActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText et_title;
    private EditText et_message;
    private EditText et_count;
    private static String mChannelId = "3"; // 通知渠道的编号
    private static String mChannelName = "一般重要"; // 通知渠道的名称
    private static int mImportance = NotificationManager.IMPORTANCE_DEFAULT; // 通知渠道的级别
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notify_marker);
        et_title = findViewById(R.id.et_title);
        et_message = findViewById(R.id.et_message);
        et_count = findViewById(R.id.et_count);
        findViewById(R.id.btn_show_marker).setOnClickListener(this);
        findViewById(R.id.btn_clear_marker).setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        ViewUtil.hideOneInputMethod(this, et_message); // 隐藏输入法软键盘
        if (TextUtils.isEmpty(et_title.getText())) {
            Toast.makeText(this, "请填写消息标题", Toast.LENGTH_SHORT).show();
            return;
        }
        if (TextUtils.isEmpty(et_message.getText())) {
            Toast.makeText(this, "请填写消息内容", Toast.LENGTH_SHORT).show();
            return;
        }
        if (TextUtils.isEmpty(et_count.getText())) {
            Toast.makeText(this, "请填写消息数量", Toast.LENGTH_SHORT).show();
            return;
        }
        String title = et_title.getText().toString();
        String message = et_message.getText().toString();
        int count = Integer.parseInt(et_count.getText().toString());
        if (v.getId() == R.id.btn_show_marker) {
            sendChannelNotify(title, message, count); // 发送指定渠道的通知消息
            Toast.makeText(this, "已显示消息角标,请回到桌面查看", Toast.LENGTH_SHORT).show();
        } else if (v.getId() == R.id.btn_clear_marker) {
            sendChannelNotify(title, message, 0); // 发送指定渠道的通知消息
            Toast.makeText(this, "已清除消息角标,请回到桌面查看", Toast.LENGTH_SHORT).show();
        }
    }
    // 发送指定渠道的通知消息(包括消息标题和消息内容)
    private void sendChannelNotify(String title, String message, int count) {
        // 创建一个跳转到活动页面的意图
        Intent clickIntent = new Intent(this, MainActivity.class);
        // 创建一个用于页面跳转的延迟意图
        PendingIntent contentIntent = PendingIntent.getActivity(this,
                R.string.app_name, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        // 创建一个通知消息的建造器
        Notification.Builder builder = new Notification.Builder(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0开始必须给每个通知分配对应的渠道
            builder = new Notification.Builder(this, mChannelId);
        }
        builder.setContentIntent(contentIntent) // 设置内容的点击意图
                .setAutoCancel(true) // 点击通知栏后是否自动清除该通知
                .setSmallIcon(R.mipmap.ic_launcher) // 设置应用名称左边的小图标
                .setContentTitle(title) // 设置通知栏里面的标题文本
                .setContentText(message); // 设置通知栏里面的内容文本
        Notification notify = builder.build(); // 根据通知建造器构建一个通知对象
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotifyUtil.createNotifyChannel(this, mChannelId, mChannelName, mImportance);
        }
        NotifyUtil.showMarkerCount(this, count, notify); // 在桌面的应用图标右上方显示指定数字的消息角标
        // 从系统服务中获取通知管理器
        NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 使用通知管理器推送通知,然后在手机的通知栏就会看到该消息,多条通知需要指定不同的通知编号
        notifyMgr.notify(Integer.parseInt(mChannelId), notify);
    }
}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="本页面的消息角标仅支持华为与小米手机"
        android:textColor="@color/black"
        android:textSize="17sp" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="消息标题:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_title"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:layout_margin="5dp"
            android:background="@drawable/editext_selector"
            android:hint="请填写消息标题"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="消息内容:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_message"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="top"
            android:layout_margin="5dp"
            android:background="@drawable/editext_selector"
            android:hint="请填写消息内容"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="消息数量:"
            android:textColor="@color/black"
            android:textSize="17sp" />
        <EditText
            android:id="@+id/et_count"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:background="@drawable/editext_selector"
            android:gravity="left|center"
            android:inputType="number"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </LinearLayout>
    <Button
        android:id="@+id/btn_show_marker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="发送消息同时显示桌面角标"
        android:textColor="@color/black"
        android:textSize="17sp" />
    <Button
        android:id="@+id/btn_clear_marker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="清除应用的消息角标"
        android:textColor="@color/black"
        android:textSize="17sp" />
</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏

相关文章
|
3天前
|
人工智能 JSON 小程序
【一步步开发AI运动APP】七、自定义姿态动作识别检测——之规则配置检测
本文介绍了如何通过【一步步开发AI运动APP】系列博文,利用自定义姿态识别检测技术开发高性能的AI运动应用。核心内容包括:1) 自定义姿态识别检测,满足人像入镜、动作开始/停止等需求;2) Pose-Calc引擎详解,支持角度匹配、逻辑运算等多种人体分析规则;3) 姿态检测规则编写与执行方法;4) 完整示例展示左右手平举姿态检测。通过这些技术,开发者可轻松实现定制化运动分析功能。
|
1月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
143 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
1月前
|
安全 API Swift
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
115 15
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
|
29天前
|
Web App开发 编解码 算法
布谷一对一直播源码开发:阿里云视频语音通话社交交友App的必备功能
在当今移动社交领域,一对一视频和语音通话功能已成为用户期待的基础配置。从熟人社交到陌生人交友,从专业咨询到情感陪伴,实时音视频互动能力直接决定了社交App的用户留存和市场竞争力。山东布谷科技将深入探讨一对一直播源码开发高质量一对一视频和语音通话功能的关键要素和技术实现方案。
布谷一对一直播源码开发:阿里云视频语音通话社交交友App的必备功能
|
22天前
|
人工智能 小程序 API
【一步步开发AI运动APP】四、使用相机组件抽帧
本文介绍了如何使用`ai-camera`组件开发AI运动APP,助力开发者深耕AI运动领域。`ai-camera`是专为AI运动场景设计的相机组件,支持多平台,提供更强的抽帧处理能力和API。文章详细讲解了获取相机上下文、执行抽帧操作以及将帧保存到相册的功能实现,并附有代码示例。无论是AI运动APP还是其他场景,该组件都能满足预览、拍照、抽帧等需求。下篇将聚焦人体识别检测,敬请期待!
|
15天前
|
人工智能 开发框架 小程序
工会成立100周年纪念,开发职工健身AI运动小程序、APP方案推荐
为庆祝中华全国总工会成立100周年,特推出基于AI技术的智能健身系统,以小程序和APP形式呈现,助力职工健康生活。方案包括:1) 小程序插件,支持多种运动识别,开箱即用;2) APP插件,提供更高精度的运动检测;3) 成熟的「AI乐运动」系统,支持赛事活动管理。这些方案满足不同需求,推动全民健身体验升级,彰显工会对职工健康的关怀。
|
18天前
|
人工智能 小程序 开发者
【一步步开发AI运动APP】六、运动计时计数能调用
本文章介绍了如何通过【一步步开发AI运动APP】系列博文,利用uniAPP插件开发高性能的AI运动应用。文中详细说明了创建运动分析器、进行运动分析、监听计数变化以及停止/重置分析等功能实现步骤。插件内置多种常见运动(如跳绳、俯卧撑等),支持自定义扩展,满足健身、体测等场景需求。示例代码展示了人体检测、运动计时计数及UI更新的完整流程,帮助开发者快速上手并深耕AI运动领域。
|
14天前
|
缓存 开发工具 开发者
鸿蒙NEXT开发App相关工具类(ArkTs)
这段代码展示了一个名为鸿蒙NEXT开发 `AppUtil` 的工具类,主要用于管理鸿蒙应用的上下文、窗口、状态栏、导航栏等配置。它提供了多种功能,例如设置灰阶模式、颜色模式、字体类型、屏幕亮度、窗口属性等,并支持获取应用包信息(如版本号、包名等)。该工具类需在 UIAbility 的 `onWindowStageCreate` 方法中初始化,以便缓存全局变量。代码由鸿蒙布道师编写,适用于鸿蒙系统应用开发,帮助开发者更便捷地管理和配置应用界面及系统属性。
|
22天前
|
人工智能 小程序 API
【一步步开发AI运动APP】五、人体检测能力调用
本文介绍如何开发性能更强、体验更优的AI运动APP,涵盖人体检测、实例创建、检测识别、骨骼图绘制及完整代码实现。通过API `createHumanDetector`,可灵活配置高性能、高精度或多人检测模式,省去模型部署麻烦。检测结果可通过`yz-pose-grapher`组件高效渲染骨骼图。最后提醒使用完毕需调用`destroy()`释放资源,下篇将聚焦运动检测分析,敬请期待!
|
23天前
|
人工智能 开发框架 小程序
【一步步开发AI运动APP】二、跨平台APP AI运动识别方案介绍
本系列博文旨在帮助开发者从【AI运动小程序】迈向性能更优的【AI运动APP】开发。通过「云智AI运动识别」uni-app版插件,提供本地原生极速识别、精准姿态检测及运动计时计数功能,支持健身系统、线上赛事、学生体测、康复锻炼等多场景应用。插件无需云端依赖,一次付费永久使用,成本低且扩展性强。同时兼容uni-app与uni-app x框架,适合不同技术背景的开发者快速上手,助力抢占AI辅助运动市场。下篇将介绍插件引入,敬请期待!

热门文章

最新文章

下一篇
oss创建bucket