MAUI Android 關聯檔案型別

2023-05-26 18:00:43

實現效果

開啟某個檔案,字尾是自己想要的型別,在彈出的視窗(用其它應用開啟)的列表中顯示自己的應用圖示

點選後可以獲得檔案資訊以便於後續的操作

實現步驟

以註冊.bin字尾為例,新建一個MAUI專案

調整啟動模式

修改Platforms\Android\MainActivity.cs

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]

調整為

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density, LaunchMode = LaunchMode.SingleTop)]

末尾增加了LaunchMode = LaunchMode.SingleTop

更改啟動模式為棧頂模式,解釋如下

SingleTop模式又稱棧頂模式,每次啟動一個Activity的時候,首先會判斷當前任務棧的棧頂是否存在該Activity範例,
如果存在則重用該Activity範例,並且回撥其onNewIntent()函數,否則就建立一個新範例。

這樣,我們就可以在回撥函數中獲得檔案路徑

註冊關聯型別

還是修改Platforms\Android\MainActivity.cs

Activevity註冊的下一行新增

[IntentFilter(new[] { Intent.ActionSend, Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = @"application/octet-stream")]//.bin檔案關聯

application/octet-streamBin的Mime型別,根據自己的檔案字尾,可以查詢所有官方 MIME 型別的列表

監聽意圖

重寫OnNewIntent拿到意圖,並從中獲取資料,通過 Messenger 進行資料傳遞

也可以通過試圖跳轉進行傳遞,具體參考:MAUI檔案-傳遞資料

新建一個訊息模型

參照 CommunityToolkit.Mvvm NuGet 包

建立訊息模型

namespace ITLDG.Message
{
    public class NewFileMessage : ValueChangedMessage<Android.Net.Uri>
    {
        public NewFileMessage(Android.Net.Uri uri) : base(uri)
        {
        }
    }
}

傳送訊息

using Android.Content;//參照這個

...

	public class MainActivity : MauiAppCompatActivity
    {
	
		...
	
        protected override void OnResume()
        {
            base.OnResume();
            //這裡呼叫下,不然首次啟動沒有意圖
            OnNewIntent(Intent);
        }
        protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);
            if (intent.Action == Intent.ActionView)
            {
                WeakReferenceMessenger.Default.Send(new NewFileMessage(intent.Data));
            }
        }
		
		
		...
		
    }
	
	...
	

接收訊息

ViewModel中接收訊息

WeakReferenceMessenger.Default.Register<NewFileMessage>(this, (r, m) =>
{
    if (m.Value == null) return;
    var intent = m.Value;
    //檔案路徑
    // var path = intent.Path
    //得到檔案流
    var stream = Platform.CurrentActivity.ContentResolver.OpenInputStream(intent);
    var memoryStream = new MemoryStream();
    stream.CopyTo(memoryStream);
    //完整的資料
    var bytes=memoryStream.ToArray()
});

總結

起初,我使用檢視跳轉傳遞引數的方式傳遞獲取到的Intent,嘗試了幾次無法傳遞到MainPage

後加了一個跳轉頁,拿到訊息後傳到到中轉頁,中專頁拿到資料後再將資料回穿回來,但是這樣傳遞,無法傳遞Intent型別和Uri型別,我不得不先將檔案寫到快取目錄,再傳遞快取目錄

這樣的流程始終無法滿意,最終改為使用Messenger 進行資料傳遞,問題解決

另外,起初首次開啟檔案喚醒APP,無法獲取到Intent,APP後臺執行開啟檔案喚醒正常

後來在stackoverflow找到了答案