背景
MAUI的出現,賦予了廣大.Net開發者開發多平臺應用的能力,MAUI 是Xamarin.Forms演變而來,但是相比Xamarin性能更好,可擴展性更強,結構更簡單。但是MAUI對于平臺相關的實現并不完整。所以MASA團隊開展了一個實驗性項目,意在對微軟MAUI的補充和擴展
項目地址https://github.com/BlazorComponent/MASA.Blazor/tree/main/src/Masa.Blazor.Maui.Plugin
每個功能都有單獨的demo演示項目,考慮到App安裝文件體積(雖然MAUI已經集成裁剪功能,但是該功能對于代碼本身有影響),屆時每一個功能都會以單獨的nuget包的形式提供,方便測試,現在項目才剛剛開始,但是相信很快就會有可以交付的內容啦。
前言
本系列文章面向移動開發小白,從零開始進行平臺相關功能開發,演示如何參考平臺的官方文檔使用MAUI技術來開發相應功能。
介紹
鑒于現在運營需求的增強,消息推送在Android開發中應用的場景是十分常見,如電商的活動宣傳、資訊類產品進行新聞推送等等,所以關于這個功能我就不過多介紹了。面向海外推送業務MAUI有一些集成Google firebase或其他運營商的可用的示例和綁定庫可用,但是國內用戶無法使用這些,對于國內比較常見的例如極光、個推等,也沒用對應的MAUI或者Xamarin的SDK可用,本人聯系過官方也無法提供任何技術支持。
但是,這樣的困難是無法難倒MASA的開發人員的,所以在各方壓力的鞭策下,有了本文,本文以“國內服務提供商個推(https://www.getui.com)的Android 原生SDK”為例,提供Android原生代碼到MAUI代碼的綁定及實現方式。
思路
Android 的第三方庫生態系統非常龐大。正因為此,使用現有的Android庫通常比創建一個新的庫更合理。其實早在Xamarin的時代,微軟已經提供了Android綁定庫(Xamarin)這個項目,實現原理為:創建一個綁定庫,該庫使用C# 包裝器自動包裝庫,以便通過C# 調用來調用Java 代碼,通過使用托管可調用包裝器 (MCW) 實現綁定。MCW 是一個JNI 橋,在托管代碼需要調用Java代碼時會使用它。托管可調用包裝器還支持對Java類型進行子類化以及覆蓋Java類型的虛擬方法。同樣,每當 Android 運行時 (ART) 代碼需要調用托管代碼時,它都會通過另一個稱為 Android 可調用包裝器 (ACW) 的 JNI 橋來實現。?下圖說明了此體系結構
通常情況下,綁定 Android 庫(.aar 或 .jar)文件絕非易事;通常它需要花費額外的精力來解決 Java 和 .NET 之間的差異導致的問題。這些問題會使 MAUI無法綁定 Android 庫,并在生成日志中顯示為錯誤消息。
推送功能涉及到的內容非常多,接下來我們只開發最基礎的功能,并對此做最精簡配置。
開發步驟
一、下載個推Android SDK
個推賬號的申請及應用的創建請參考官方文檔(個推面向個人開發者,而且我們通過CID發送測試是免費的,無需充值和實名認證)。
這里我們著重介紹集成的方法,個推官網的文檔示例是使用Maven 方式集成,但是這種方式在MAUI當然無法實現,所以我們需要手動下載SDK對應的aar文件進行手動集成。
maven倉庫地址為:http://mvn.getui.com/nexus/content/repositories/releases/com/getui
我們需要gtsdk和gtc,分別下載最新的gtc-3.1.12.0.aar和gtsdk-3.2.13.0.aar
我是怎么知道需要使用這兩個文件呢?因為我下載了官方的Demo然后使用maven集成后在
C:\Users\用戶名\.gradle\caches\modules-2\files-2.1\com.getui 目錄下載了這兩個文件😉
二、創建Android綁定庫
新建一個項目:Masa.Blazor.Maui.Plugin.GeTuiPushBinding,項目模板選擇Android Java 庫綁定
在根目錄創建Jars文件夾,并將下載的兩個aar文件添加進去。添加進去的文件屬性中,生成操作默認選擇的是AndroidLibrary,如果不對請手動更正。
前方高能預警!😎
右鍵生成這個項目,我們會看到很多編譯警告,其中還包含6處錯誤。
我們依次點擊對應錯誤,進入生成的cs文件,這些文件位于obj\Debug\net7.0-android\generated\src
錯誤1和2對應Com.Getui.Gtc.Base.Crypt.CryptTools文件的Decrypt和Encrypt方法。
這里Java.IO.OutputStream和InputStream類型都被轉換為System.IO.Stream,導致本來兩個簽名不一致的方法被弄成了一樣(更正的方法本文不做討論,本Demo沒有使用到這兩個方法)索性將280行和134行的本來應該映射到OutputStream類型的Decrypt和Encrypt方法注釋。
其他錯誤都是類型轉換錯誤導致的沒有實現接口,我們分別修改4個OnArrived方法,將方法的參數global::Org.Json.JSONObject修改為Java.Lang.Object,并將方法的virtual標記更改為override
只有一個參數的OnArrived方法需要將返回值也修改為Java.Lang.Object。
4處全部更正之后,再次生成就不會有報錯了。
注意:不要選重新生成,重新生成會將之前的修改覆蓋掉。
三、創建Demo項目
新建一個MAUI Blazor項目:Masa.Blazor.Maui.Plugin.GeTuiSample,添加對Masa.Blazor.Maui.Plugin.GeTuiPushBinding項目的引用
1、初始化個推SDK
個推SDK的初始化在MainActivity.OnCreate() 或MainApplication.OnCreate()方法中都是可以的,我們這里在MainActivity中初始化。修改Platforms->Android->MainActivity.cs文件,在MainActivity的OnCreate事件中添加我們的初始化方法
public class MainActivity : MauiAppCompatActivity{protected override void OnCreate(Bundle savedInstanceState){base.OnCreate(savedInstanceState);Com.Igexin.Sdk.PushManager.Instance.Initialize(this);var cid = Com.Igexin.Sdk.PushManager.Instance.GetClientid(this);System.Diagnostics.Debug.WriteLine($"cid:{cid}");}}
因為我們完成了綁定,所以這里可以使用個推SDK中的Com.Igexin.Sdk命名空間下的PushManager來完成初始化,
初始化方法Initialize非常簡單,初始化后我們可以通過GetClientid方法拿到客戶端ID,方便我們后續在個推平臺下發推送測試任務,因為向特定CID發送推送是免費的。
2、配置推送服務
繼續在Android目錄下新建推送服務類DemoPushService
using Android.App;namespace Masa.Blazor.Maui.Plugin.GeTuiSample
{[Service(Process = ":pushservice", Exported = false)]public class DemoPushService : Com.Igexin.Sdk.PushService{}
}
我們只要實現一個繼承自Com.Igexin.Sdk.PushService的類即可。
注意:服務必須指定Process = “:pushservice”,設置了這行代碼,系統就會為該服務創建新的進程,DemoPushService 將運行在這個新的獨立的進程,它所在的apk依舊運行在原來進程。這樣就實現了Android使用多進程。
android:exported 是Android中的四大組件 Activity,Service,Provider,Receiver 四大組件中都會有的一個屬性。
主要作用是:是否支持其它應用調用。處于安全考慮我們這里設置為Exported = false,代表不支持其他應用調用。
修改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" android:label="@string/app_name" android:usesCleartextTraffic="true"xmlns:tools="http://schemas.android.com/tools"><serviceandroid:name="Masa.Blazor.Maui.Plugin.GeTuiSample.DemoPushService"android:exported="false"android:label="PushService"android:process=":pushservice"/><meta-data android:name="GETUI_APPID" tools:replace="android:value" android:value="這里填你在個推的APPID" /></application><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" />
</manifest>
我們在application 中添加了xmlns:tools=“http://schemas.android.com/tools”,作用是在下面的meta-data中使用tools:replace,否則會出現Android 組件化集成合并AndroidManifest.xml 的問題,添加android:label="@string/app_name"也是為了避免合并問題。
service表示我們添加的自定義推送類,android:name的值必須寫全命名空間。
GETUI_APPID部分為個推應用對應的APPID
我們啟動應用,并在個推平臺下發一個測試推送
Android推送功能涉及的內容非常多,不同的Android版本、不同手機廠商還有不同的功能和實現方式,例如vivo有特有的角標通知等。我們這里只演示了最基本的推送功能,其他高級操作,例如自定義接收推送服務事件,設置通知圖標及樣式,相應對應通知點擊事件,離線推送功能等,如有需求后續介紹。
如果你對我們的開源項目感興趣,無論是代碼貢獻、使用、提 Issue,歡迎聯系我們