MASA MAUI Plugin (七)应用通知角标(小红点)Android+iOS

背景

MAUI的出现,赋予了广大Net开发者开发多平台应用的能力,MAUI 是Xamarin.Forms演变而来,但是相比Xamarin性能更好,可扩展性更强,结构更简单。但是MAUI对于平台相关的实现并不完整。所以MASA团队开展了一个实验性项目,意在对微软MAUI的补充和扩展

项目地址https://github.com/BlazorComponent/MASA.Blazor/tree/feature/Maui/src/Masa.Blazor.Maui.Plugin

每个功能都有单独的demo演示项目,考虑到app安装文件体积(虽然MAUI已经集成裁剪功能,但是该功能对于代码本身有影响),届时每一个功能都会以单独的nuget包的形式提供,方便测试,现在项目才刚刚开始,但是相信很快就会有可以交付的内容啦。

前言

本系列文章面向移动开发小白,从零开始进行平台相关功能开发,演示如何参考平台的官方文档使用MAUI技术来开发相应功能。

介绍

上一篇文章我们集成了个推的消息通知,那么消息到达移动端之后,除了会在通知栏显示之外,在应用的角标也会显示未读消息的数量(小红点),然后用户点击查看消息之后,这些数字角标也可以自动消除,这个功能在MAUI中如何实现呢?

一、iOS部分

思路

https://developer.apple.com/documentation/uikit/uiapplication/1622918-applicationiconbadgenumber

我们参考一下官方文档,UIApplication下有一个applicationIconBadgeNumber的属性

var applicationIconBadgeNumber: Int { get set }

我们只需要给这个属性赋值具体的整数即可

https://developer.apple.com/documentation/uikit/uiapplication/1622975-shared

我们可以通过shared获取当前UIApplication的实例,然后就可以给applicationIconBadgeNumber赋值了,但是如果你直接这样做,你会发现并没有效果,因为 iOS 8 以后,需要注册用户通知,以获得用户的授权。

https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/1649527-requestauthorization

我们可以通过UNUserNotificationCenter的RequestAuthorization方法获取请求用户本地和远程的通知权限。

878c7aee3757f16bd1d5efea440fcb3a.jpeg

开发步骤

我们新建一个目录Badger,并在下面新建MAUI类库项目Masa.Blazor.Maui.Plugin.Badger,在Platforms下的iOS文件夹新建MasaMauiBadgerService部分类

using UIKit;
using UserNotifications;
namespace Masa.Blazor.Maui.Plugin.Badger
{public static partial class MasaMauiBadgerService{private static void PlatformSetNotificationCount(int count){// Requests the user’s authorization to allow local and remote notifications for your app.UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Badge, (r, e) =>{});// The number currently set as the badge of the app icon on the Home screen// Set to 0 (zero) to hide the badge number. The default value of this property is 0.UIApplication.SharedApplication.ApplicationIconBadgeNumber = count;}}
}

RequestAuthorization方法有两个参数

1、UNAuthorizationOptions 代表应用请求的授权选项,这里我们使用Badge
2、completionHandle 这是一个Action,有两个参数,第一个参数是一个bool值,代表是否已授予授权,第二个参数是一个NSError类型,表示包含错误信息或未发生错误的对象。我们这里暂不处理出错的情况

我们通过UIApplication.SharedApplication获取当前的UIApplication实例,然后直接给ApplicationIconBadgeNumber 赋值,这里如果我们想清除角标,就直接赋值0即可。

我们继续在项目根目录新建MasaMauiBadgerService类,通过SetNotificationCount来调用不同平台的PlatformSetNotificationCount方法。

namespace Masa.Blazor.Maui.Plugin.Badger
{// All the code in this file is included in all platforms.public static partial class MasaMauiBadgerService{public static void SetNotificationCount(int count){PlatformSetNotificationCount(count);}}
}

二、安卓部分

思路

安卓部分比iOS相对复杂,我们本着不造轮子的思想,找了一个现成的aar包,ShortcutBadger

项目maven地址:https://repo1.maven.org/maven2/me/leolin/ShortcutBadger

开发步骤

1、我们下载最新的ShortcutBadger-1.1.22.aar包,并新建Android Java 库绑定项目Masa.Blazor.Maui.Plugin.BadgerBinding

d811bc84c1b744284be038ce27c2fe38.png

在根目录创建Jars文件夹,并将下载的aar文件添加进去。添加进去的文件属性中,生成操作默认选择的是AndroidLibrary,如果不对请手动更正。
右键生成这个项目,这里很顺利没有任何报错。

2、我们在Masa.Blazor.Maui.Plugin.Badger项目中引用Masa.Blazor.Maui.Plugin.BadgerBinding项目,由于我们只有在安卓平台需要项目引用,所以我们手动修改一下项目文件中的引用部分,添加Android平台的判断。

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'"><ProjectReference Include="..\Masa.Blazor.Maui.Plugin.BadgerBinding\Masa.Blazor.Maui.Plugin.BadgerBinding.csproj" /></ItemGroup>

3、从 Android 8.0(API 级别 26)开始,所有通知都必须分配到相应的渠道,关于通知通道的信息,可以参考以下官方文档

https://developer.android.google.cn/training/notify-user/channels?hl=zh-cn

Java 代码private void createNotificationChannel() {// Create the NotificationChannel, but only on API 26+ because// the NotificationChannel class is new and not in the support libraryif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {CharSequence name = getString(R.string.channel_name);String description = getString(R.string.channel_description);int importance = NotificationManager.IMPORTANCE_DEFAULT;NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);channel.setDescription(description);// Register the channel with the system; you can't change the importance// or other notification behaviors after thisNotificationManager notificationManager = getSystemService(NotificationManager.class);notificationManager.createNotificationChannel(channel);}}

我们参照以上写法,在Masa.Blazor.Maui.Plugin.Badger项目的Android平台目录下新建MasaMauiBadgerService 类,添加一个CreateNotificationChannel方法

using Android.App;
using AndroidX.Core.App;namespace Masa.Blazor.Maui.Plugin.Badger
{// All the code in this file is included in all platforms.public static partial class MasaMauiBadgerService{private static void CreateNotificationChannel(){if (OperatingSystem.IsAndroidVersionAtLeast(26)){using var channel = new NotificationChannel($"{Android.App.Application.Context.PackageName}.channel", "Notification channel", NotificationImportance.Default){Description = "Masa notification channel"};var notificationManager = NotificationManager.FromContext(Android.App.Application.Context);notificationManager?.CreateNotificationChannel(channel);}}}
}

1、通过OperatingSystem.IsAndroidVersionAtLeast来判断当前的Android版本。
2、NotificationChannel的创建方式与Java一致,三个参数分别为ChannelID,name、Importance,这里注意第三个参数代表重要性级别,我们这里使用了NotificationImportance.Default。

用户可见的重要性级别重要性(Android 8.0 及更高版本)
紧急:发出提示音,并以浮动通知的形式显示IMPORTANCE_HIG
高:发出提示音IMPORTANCE_DEFAULT
中:无提示音IMPORTANCE_LOW
低:无提示音,且不会在状态栏中显示IMPORTANCE_MIN

3、Description 指定用户在系统设置中看到的说明。
4、通过NotificationManager.FromContext 创建 notificationManager,然后调用CreateNotificationChannel来创建通知通道。

我们继续添加SetNotificationCount方法

private static void PlatformSetNotificationCount(int count){ME.Leolin.Shortcutbadger.ShortcutBadger.ApplyCount(Android.App.Application.Context, count);NotificationCompat.Builder builder = new(Android.App.Application.Context, $"{Android.App.Application.Context.PackageName}.channel");builder.SetNumber(count);builder.SetContentTitle(" ");builder.SetContentText("");builder.SetSmallIcon(Android.Resource.Drawable.SymDefAppIcon);var notification = builder.Build();var notificationManager = NotificationManager.FromContext(Android.App.Application.Context);CreateNotificationChannel();notificationManager?.Notify((int)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), notification);}

1、调用ShortcutBadger的ApplyCount方法来添加角标
2、创建NotificationCompat.Builder示例,并以此设置角标显示数量(SetNumber),通知的标题(SetContentTitle)和内容(SetContentText),以及通知图标(SetSmallIcon)。
3、调用我们刚写好的方法创建通知通道。
4、通过NotificationManager.Notify方法在状态栏发布一条通知。
该方法有两个参数,第一个参数是一个int类型id,这个id是通知的标识符,在应用程序中应该唯一。这里需要注意:如果你发布了相同id的通知,并且前一个并没有取消,那么该id对应的通知会被更新。第二个参数是一个notification 对象,是通过NotificationCompat.Builder创建出来的。

三、创建Demo项目

1、新建一个MAUI Blazor项目:BadgerSample,添加对Masa.Blazor.Maui.Plugin.Badger项目的引用
2、添加Android权限:修改Android平台目录中的AndroidManifest.xml文件,添加必要的权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.POST_NOTIFICATIONS"/><uses-permission android:name="android.permission.READ_APP_BADGE" /><uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/><uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS"/><uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /><uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
</manifest>

注意:国内不同手机厂家可能需要额外的权限配置,需要参考具体厂家的配置说明。

3、修改Index.razor文件

实际的使用场景应该是移动端接收消息推送,在处理消息推送的方法内修改角标,我们这里为了简化,在页面直接通过按钮触发修改角标显示的数量。

@page "/"
@using Masa.Blazor.Maui.Plugin.Badger;<h1>Masa blazor badger sample</h1>Masa blazor badger sample.<button @onclick="OnIncrementClicked">Add</button>
<button @onclick="OnClearClicked">Clear</button>
@code{int count;private void OnIncrementClicked(){count++;MasaMauiBadgerService.SetNotificationCount(count);}private void OnClearClicked(){count = 0;MasaMauiBadgerService.SetNotificationCount(count);}
}

Android 演示:演示机:vivo x70 pro+

da9511c0e3f22883e2347146de6c6134.gif
iOS 演示:演示机:iPhone 14 iOS16 模拟器

efccf624f48dceca0c80627704bb77fd.gif


如果你对我们的开源项目感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

194146ff9516e2f036fa022e29f58901.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP如何查看会计凭证

比如SAP中已经存在着很多会计凭证&#xff0c;你想要进入SAP随便看看会计凭证的列表&#xff0c;怎么操作呢&#xff1f;事务码 IDCNDOC运行结果看到了凭证们&#xff0c;和每个凭证的行项目们上图看到的结果比较凌乱实际上我们重新进入IDCNDOC可以通过输入的勾选&#xff0c;选…

C# 温故而知新:Stream篇(五)

MemoryStream 目录&#xff1a; 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析MemorySteam最常见的OutOfMemory异常 5 MemoryStream 的构造 6 MemoryStream 的属性 7 MemoryStream 的方法 8 MemoryStream 简单示例…

dosbox 自动运行_如何使用DOSBox运行DOS游戏和旧应用

dosbox 自动运行New versions of Windows don’t fully support classic DOS games and other old applications — this is where DOSBox comes in. It provides a full DOS environment that runs ancient DOS apps on modern operating systems. Windows的新版本不完全支持经…

WPF 自定义放大镜控件

控件名&#xff1a;Magnifier作 者&#xff1a;WPFDevelopersOrg - 驚鏵原文链接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40&#xff1b;Visual Studio 2019;实现此功能需要用到 VisualBrush &#xff0c;放大镜展现使用 Canvas ->…

.NET实现之(WebBrowser数据采集—续篇)

我们继续“.NET实现之(WebBrowser数据采集)“系列篇之最后一篇&#xff0c;这篇本人打算主要讲解怎么用WebBrowser控件来实现“虚拟”的交互性程序&#xff1b;比如我们用Winform做为宿主容器&#xff0c;用Asp.net做相关收集程序页面&#xff0c;我们需要通过客户端填写相关数…

ipad和iphone切图_如何在iPhone,iPad和Mac上使消息静音

ipad和iphone切图If you use Messages on your iPhone, iPad, or Mac, then you probably know how quickly you can become overrun with message notifications, especially if you’re part of a group message. Thankfully, there’s an easy way to mute specific message…

Pipy 实现 SOCKS 代理

上篇我们介绍了服务网格 osm-edge 出口网关使用的 HTTP 隧道&#xff0c;其处理方式与另一种代理有点类似&#xff0c;就是今天要介绍的 SOCKS 代理。二者的主要差别简单来说就是前者使用 HTTP CONNECT 告知代理目的地址&#xff0c;而后者则是通过 SOCKS 协议。值得一提的是&a…

python拓展7(Celery消息队列配置定时任务)

介绍 celery 定时器是一个调度器&#xff08;scheduler&#xff09;&#xff1b;它会定时地开启&#xff08;kicks off&#xff09;任务&#xff0c;然后由集群中可用的工人&#xff08;worker&#xff09;来执行。 定时任务记录&#xff08;entries&#xff09;默认 从 beat_s…

chrome连接已重置_如何重置(或调整)Chrome的下载设置

chrome连接已重置By default, Chrome saves all downloaded files to the same location—a dedicated “Downloads” folder. The thing is, this isn’t always practical for all types of download files. The good news is you can easily tweak this setting. 默认情况下…

.Net 7 团队把国内的龙芯确实当做一等公民和弃用的项目

楔子&#xff1a;国内龙芯据说是用的自己的指令集&#xff0c;在研究ILC的时候&#xff0c;发现了龙芯在微软那边确实是一等公民的存在。同X64,ARM,X86一同并列交叉编译和二进制提取。龙芯官网龙芯平台.NET&#xff0c;是龙芯公司基于开源社区.NET独立研发适配的龙芯版本&#…

戴尔押宝iSCSI,由低到高组合成型

戴尔&#xff08;Dell&#xff09;是较早接受SAS技术的主流存储厂商之一&#xff0c;2006年已推出采用SAS硬盘驱动器的SAS直连存储&#xff08;DAS&#xff09;系统PowerVault MD3000。一年之后&#xff0c;主机连接改用iSCSI的PowerVault MD3000i问世。2008年1月&#xff0c;E…

word中插入公式的快捷键_如何使用插入键在Word中插入复制的内容

word中插入公式的快捷键In Word, the “Insert” key on the keyboard can be used to switch between Insert and Overtype modes. However, it can also be used as a shortcut key for inserting copied or cut content at the current cursor position. 在Word中&#xff0…

微软终于为 Visual Studio 添加了内置的 Markdown 编辑器

微软终于为 Visual Studio 添加了内置的 Markdown 编辑器。根据官方博客的介绍&#xff0c;由于收到许多用户的反馈&#xff0c;微软决定为 Visual Studio 添加 Markdown 编辑器。开发者下载最新的 Visual Studio 17.5 第 2 个预览版就能够使用 Markdown 编辑功能&#xff0c;无…

【经验分享】Hydra(爆破神器)使用方法

这个也是backtrack下面很受欢迎的一个工具 参数详解&#xff1a;-R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密码字典(文件)-e 空密码探测和指定用户密码探测(ns)-C 用户名可以用:分割(username:passw…

【东软实训】SQL多表链接

如果一个查询同时涉及两个以上的表&#xff0c;则称之为链接查询&#xff0c;链接查询是关系数据库中最主要的查询&#xff0c;主要包括等值链接查询、非等值链接查询、自身链接查询、外链接查询和复合条件链接查询。 这篇博文我们来对多表链接进行学习。 Outline 链接的基本概…

博鳌“‘AI+时代’来了吗”分论坛,嘉宾们有何重要观点?...

雷锋网(公众号&#xff1a;雷锋网)3月27日消息&#xff0c;正在进行中的博鳌亚洲论坛2019年年会&#xff0c;于2019年3月26日至29日在中国海南博鳌举办。今年博鳌论坛的主题为“共同命运 共同行动 共同发展”。今天&#xff0c;在主题为《“AI时代”来了吗&#xff1f;》分论坛…

一款统计摸鱼时长的开源项目

对于我们程序员&#xff0c;在工作中一天8小时&#xff0c;不可能完全在写代码了&#xff0c;累了刷刷论坛、群里吹吹牛&#xff0c;这都是非常正常的。虽然一天下来&#xff0c;可能我们都可以按时完成工作&#xff0c;但是我们不知道&#xff0c;时间都花在哪里了&#xff0c…

saltstack 主题说明

转载于:https://www.cnblogs.com/40kuai/p/9335869.html

基于spring boot 的ssm项目的简单配置

2019独角兽企业重金招聘Python工程师标准>>> 我前面的帖子有介绍spring boot的简单搭建&#xff0c;现在我再讲讲spring boot的简单配置 首先&#xff0c;项目结构 启动类 RestController 注解相当于ResponseBody &#xff0b; Controller合在一起的作用。 Sprin…

nest 架构_如何与其他人分享您的Nest Cam Feed

nest 架构Your Nest Cam can help you keep an eye on your home from anywhere you are, but more eyes you trust to watch your stuff is more comforting. If you want someone else to check in once in a while, you can share your Nest Cam feed with a simple, passwo…