背景
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方法獲取請求用戶本地和遠程的通知權限。
開發步驟
我們新建一個目錄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
在根目錄創建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+
iOS 演示:演示機:iPhone 14 iOS16 模擬器
如果你對我們的開源項目感興趣,無論是代碼貢獻、使用、提 Issue,歡迎聯系我們