MAUIで作成したスマホアプリにおいて、アプリ内ブラウザ(WebView)でのカメラの使用方法をAIに教えてもらいながら試してみた。とりあえず成功したので、やったことを忘備録としてまとめておく
※今回がうまくいったというだけで、必要十分ではないかもしれない
概要
以下の4つのステップが必要
- OS設定ファイルへの記述
- WebViewハンドラーの作成
- アプリ内での権限リクエスト
- Webサイト側の条件確認
1. OS設定ファイルへの記述
OSに対してカメラを使用することを宣言する
Android
Platforms/Android/AndroidManifest.xml の manifest タグの直下に以下を追加
<uses-permission android:name="android.permission.CAMERA" />
私の環境ではGUIで設定できた
「必要なアクセス許可」をスクロールして「CAMERA」をチェック
iOS
Platforms/iOS/Info.plist の dict タグの中に以下を追加
<key>NSCameraUsageDescription</key>
<string>撮影機能を使用するためにカメラにアクセスします。</string>
<key>NSMicrophoneUsageDescription</key>
<string>ビデオ撮影のためにマイクにアクセスします。</string>
VisualStudio上でInfo.plistをダブルクリックするとGUIの設定画面が開いてしまう
右クリックで「エクスプローラーで開く」をし、VSCodeで開いて直接追加した
(GUIからもいけるのかもしれないけど、よくわからない。とりあえず直接追加でいけた)
Info.plist を書いたのに クラッシュする / エラーが消えない 場合
解決策
1.実機/シミュレーターからアプリをアンインストールする。
2.プロジェクトの bin と obj フォルダを手動で削除する。
3.Visual Studio で「ソリューションのクリーン」をしてから再ビルドする。
2. WebViewハンドラーの作成
WebView内のWebサイトから届く「カメラ使用リクエスト」をプログラムで承認する
Android
Platforms/Android 内にクラスを追加 MyWebChromeClient.cs
using Android.Webkit;
namespace test10_0.Platforms.Android
{
public class MyWebChromeClient : WebChromeClient
{
// Webページが「カメラを使っていい?」と聞いてきたときに動く
public override void OnPermissionRequest(PermissionRequest? request)
{
if (request != null)
{
// 要求されたリソース(カメラ、マイク等)をすべて許可する
request.Grant(request.GetResources());
}
}
}
}
iOS
Platforms/iOS 内にクラスを追加 MyWKUIDelegate.cs
using WebKit;
using Foundation;
namespace test10_0.Platforms.iOS
{
public class MyWKUIDelegate : WKUIDelegate
{
[Export("webView:requestMediaCapturePermissionForOrigin:initiatedByFrame:type:decisionHandler:")]
public override void RequestMediaCapturePermission(
WKWebView webView,
WKSecurityOrigin origin,
WKFrameInfo frame,
WKMediaCaptureType type,
Action<WKPermissionDecision> decisionHandler)
{
// 「許可(Grant)」をOSに伝える
decisionHandler(WKPermissionDecision.Grant);
}
}
}
共通
ハンドラーの紐付け。MauiProgram.cs 内 にコードの追加
// プラットフォーム固有のクラスを認識させるための using
#if ANDROID
using test10_0.Platforms.Android;
#endif
#if IOS
using test10_0.Platforms.iOS;
#endif
// ... (CreateMauiApp内) ...
.ConfigureMauiHandlers(handlers =>
{
#if ANDROID
handlers.AddHandler(typeof(WebView), typeof(WebViewHandler));
WebViewHandler.Mapper.AppendToMapping("MyAndroidWebViewCustomization", (handler, view) =>
{
handler.PlatformView.SetWebChromeClient(new MyWebChromeClient());
});
#endif
#if IOS
handlers.AddHandler(typeof(WebView), typeof(WebViewHandler));
WebViewHandler.Mapper.AppendToMapping("MyIosWebViewCustomization", (handler, view) =>
{
handler.PlatformView.UIDelegate = new MyWKUIDelegate();
});
#endif
});
3.アプリ内での権限リクエスト
ユーザーにOS標準の許可ダイアログを提する
WebViewのあるページに実装する
protected override async void OnAppearing()
{
base.OnAppearing();
// カメラの権限状態を確認
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
// まだ許可されていない場合、リクエストを出す
if (status != PermissionStatus.Granted)
{
// ここでOS標準の「許可しますか?」ダイアログが表示される
status = await Permissions.RequestAsync<Permissions.Camera>();
}
// 結果の判定
if (status == PermissionStatus.Granted)
{
// 許可された:そのままWebViewを利用可能
}
else
{
// 拒否された:カメラが使えない旨をユーザーに伝える
await DisplayAlertAsync("通知", "カメラの許可がないため利用できません", "OK");
}
}
LLMはDisplayAlertを使わせようとするが.NET10ではDisplayAlertAsync
4.Webサイト側の条件確認
MAUI側ではなく、Webサイト側。もしもWeb側も自分でつくる場合。
- HTTPS: https:// でアクセスされていること(必須)
- HTMLタグ: <input type="file" accept="image/*" capture="camera"> などが使われていること