この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Xamarin.Essentials 1.6で「App Actions」が追加されました。何かというと、アプリアイコンを長押しすると出てくるメニューを押せるアレです。
本記事では、このApp Actionsを実装してみました。
まずは基本となるアプリを作成する
プロジェクトを新規作成する
適当なプロジェクトを新規作成します。
アプリのテンプレートはポップアップを選択します。
ビルドしてアプリを起動する
ポップアップのサンプルアプリが起動しました。このサンプルアプリに対して、App Actionsを実装します。
Androidアプリ
iOSアプリ
App Actionsを実装する
Xamarin.Essentialsの更新
Xamarin.Essentialsを1.6.0
以上に更新します。
共通処理
App.xaml.cs
にアクションの一覧と選択された際の処理を追加します。
App.xaml.cs
using AppActionsSample.Services;
using System.Diagnostics;
using Xamarin.Forms;
using Xamarin.Essentials;
namespace AppActionsSample
{
public partial class App : Application
{
public App()
{
InitializeComponent();
AppActions.OnAppAction += AppActions_OnAppAction;
DependencyService.Register<MockDataStore>();
MainPage = new AppShell();
}
protected override async void OnStart()
{
try
{
await AppActions.SetAsync(
new AppAction("abount", "About", icon: "icon_about"),
new AppAction("browse", "Browse", icon: "icon_feed"),
new AppAction("add", "Add"));
}
catch (FeatureNotSupportedException ex)
{
Debug.WriteLine("App Actions not supported");
}
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
void AppActions_OnAppAction(object sender, AppActionEventArgs e)
{
if (Application.Current != this && Application.Current is App app)
{
AppActions.OnAppAction -= app.AppActions_OnAppAction;
return;
}
Device.BeginInvokeOnMainThread(async () =>
{
if (e.AppAction.Id == "about")
{
await Shell.Current.GoToAsync("//AboutPage");
}
if (e.AppAction.Id == "browse")
{
await Shell.Current.GoToAsync("//ItemsPage");
}
if (e.AppAction.Id == "add")
{
await Shell.Current.GoToAsync("//ItemsPage/NewItemPage");
}
});
}
}
}
ドキュメントのサンプルコードでは、Navigation
の下記遷移メソッドでしたが、Browseの場合に「Root→About→Browse」という画面スタックになっていたため、Shell
を用いる方法にしています。
- Application.Current.MainPage.Navigation.PopToRootAsync();
- Application.Current.MainPage.Navigation.PushAsync(page);
他に良い方法があるのかもしれません。
Androidアプリの場合
MainActivity.cs
にIntentフィルターとOnResume()
とOnNewIntent()
を追加します。
MainActivity.cs
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Content;
namespace AppActionsSample.Droid
{
[IntentFilter(new[] { Xamarin.Essentials.Platform.Intent.ActionAppAction }, Categories = new[] { Android.Content.Intent.CategoryDefault })]
[Activity(Label = "AppActionsSample", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
...
}
protected override void OnResume()
{
base.OnResume();
Xamarin.Essentials.Platform.OnResume(this);
}
protected override void OnNewIntent(Android.Content.Intent intent)
{
base.OnNewIntent(intent);
Xamarin.Essentials.Platform.OnNewIntent(intent);
}
}
}
iOSアプリの場合
AppDelegate.cs
にPerformActionForShortcutItem()
メソッドを追加します。
AppDelegate.cs
using Foundation;
using UIKit;
namespace AppActionsSample.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
...
}
public override void PerformActionForShortcutItem(UIApplication application, UIApplicationShortcutItem shortcutItem, UIOperationHandler completionHandler)
{
Xamarin.Essentials.Platform.PerformActionForShortcutItem(application, shortcutItem, completionHandler);
}
}
}
実際のアプリアイコンメニューの様子
冒頭でもあったとおり、無事に実装できました。