4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

STYLYAdvent Calendar 2024

Day 6

【Unity】Meta Questで権限周りの設定画面を開く

Posted at

背景

権限確認ダイアログから、アプリに必要な権限を許可するか問われた際、二度と権限に関して問わないように設定が可能です。

その設定をユーザーが行った場合、権限要求をScriptから行ったとしても権限確認ダイアログが出てくることはありません。つまり、アプリを体験するうえで必要な権限があるのに、その許可を促すことができなくなってしまいます。

その対策として、以下のようなフローを考えました。

  1. アプリ開始時に権限要求を行う
  2. 1の処理の後、権限の状態をチェックする
  3. 権限が拒否されていた場合、権限周りの設定画面を開く

デモ

最初の権限確認ダイアログが録画には映っていませんが、権限を拒否しています。その後、権限が許可されていない状態を検知し、アプリの権限設定を変更する画面に遷移しています。

QuestSettingsOpen.gif

この機能を拡張すれば、モバイルアプリでよくある"権限設定を変更してください"的なモーダルと組み合わせて使えます。

バージョン情報

ソフトウェア/ツール バージョン
Quest3内のバージョン詳細 72.2.2.530.347.670816297
Unity 2022.3.46f1

※Questのバージョン変更で頻繁に挙動がおかしくなりがちな機能です

サンプルコード

UniTask使っています

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;

public class CheckPermission : MonoBehaviour
{
    private readonly List<OVRPermissionsRequester.Permission> _permissionList = new()
    {
        OVRPermissionsRequester.Permission.RecordAudio, OVRPermissionsRequester.Permission.Scene
    };

    private bool _isFocus;

    private void Awake()
    {
        if (Application.isEditor) return;
        RequestPermissionsAsync(this.GetCancellationTokenOnDestroy()).Forget();
    }

    private async UniTask RequestPermissionsAsync(CancellationToken ct)
    {
        // パーミッションが許可されていないものを抽出。
        var notGrantedPermissionList = _permissionList
            .Where(permission => !OVRPermissionsRequester.IsPermissionGranted(permission))
            .ToList();

        // すべてのパーミッションが許可されている場合は何もしない。
        if (notGrantedPermissionList.Count == 0) return;

        // パーミッションが許可されていない場合はリクエストする。
        // もし一度拒否され、その設定が保存されていた場合、このリクエストはスルーされる。
        OVRPermissionsRequester.Request(notGrantedPermissionList);

        // パーミッションリクエストが表示されるまで安全のため0.5秒待ち、アプリにフォーカスが返ってくるまで待機する。
        await UniTask.Delay(TimeSpan.FromSeconds(0.5), cancellationToken: ct);
        await UniTask.WaitUntil(() => _isFocus, cancellationToken: ct);

        // 再度、パーミッションが許可されていないものを抽出。
        var notGrantedPermissionReCheckList = _permissionList
            .Where(permission => !OVRPermissionsRequester.IsPermissionGranted(permission))
            .ToList();

        // パーミッションに許可されていないものがある場合は設定画面を開く。
        if (notGrantedPermissionReCheckList.Count > 0)
        {
            RequestDetailSettings();
        }
    }
    
    private void RequestDetailSettings()
    {
        using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        using var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        var packageName = activity.Call<string>("getPackageName");
        using var uriClass = new AndroidJavaClass("android.net.Uri");
        using var uriObject = uriClass.CallStatic<AndroidJavaObject>("fromParts", "package", packageName, null);
        using var intentObject = new AndroidJavaObject("android.content.Intent",
            "android.settings.APPLICATION_DETAILS_SETTINGS", uriObject);
        intentObject.Call<AndroidJavaObject>("addCategory", "android.intent.category.DEFAULT");
        intentObject.Call<AndroidJavaObject>("setFlags", 0x10000000);
        activity.Call("startActivity", intentObject);
    }

    private void OnApplicationPause(bool pauseStatus)
    {
        _isFocus = !pauseStatus;
    }
}

参考リンク

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?