UnityからAndroidのクラスや関数を呼び出す
Unity Advent Calendar 2023 25日目の記事です。
TL;DR
- AndroidJavaObject を利用してAndroidのクラスや関数を利用する方法を紹介します。
- 上記の方法を用いて、Settingsクラス(android.provider.Settings)からアクセスできる機能を字引的に紹介していきます。
AndroidJavaObject
AndroidJavaObjectは、java.lang.ObjectのUnityにおけるジェネリックインスタンス[1]です。
実装については、下記のリポジトリ内のAndroidJava.csを参照ください。
AndroidJavaObjectには、いくつかのPublic関数が用意されています。
本記事では以下の関数を利用します。
また、それぞれの関数にはいくつかのオーバーロード[2]があるので、代表的なものを記載します。
また、AndroidJavaObjetを継承したAndroidJavaClassも同様の関数が利用できます。
関数名 | 引数 | 戻り値 |
---|---|---|
AndroidJavaClass | string(ClassName) | AndroidJavaClass |
AndroidJavaObject | string(className),params object[] args | AndroidJavaObject |
Call | string(methodName),params object[](args) または params T[] args | なし |
CallStatic | 同上 | 同上 |
Get | string(fieldName) | ジェネリクス型(FieldType) |
GetStatic | 同上 | 同上 |
Set | string(FieldName),ジェネリクス型(val) | なし |
SetStatic | 同上 | 同上 |
- CallもしくはCallStaticは、関数を呼び出します。
- GetもしくはGetStaticは、フィールド(メンバー変数)の値を取得します。
- SetもしくはSetStaticは、フィールド(メンバー変数)に値を設定します。
- Staticとつくものは、静的な関数もしくは静的な変数を扱います。
- Staticとつかないものは、静的でない関数もしくは静的でない変数を扱います。
利用手順
- クラス名を指定してAndroidJavaClassをインスタンス化
- 必要に応じてAndroidJavaObjectをインスタンス化
- インスタンス化したAndroidJavaClassの関数を呼び出し
以下はPackageNameを取得するコード例です。
//名前空間の宣言は省略
public class Hoge{
private static AndroidJavaObject GetActivity(){
using (var UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
return UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
}
}
public static string GetPackageName(){
using (var activity = GetActivity())
{
var context = activity.Call<AndroidJavaObject>("getApplicationContext");
return context.Call<string>("getPackageName");
}
}
}
- UnityPlayerクラス(AndroidJavaClass)を取得
- UnityPlayerクラスのcurrentActivity関数を呼び出して現在のアクティビティ(AndroidJavaObject)を取得
- 現在のアクティビティからgetApplicationContext関数を用いて、コンテキスト(AndroidJavaObject)を取得
- コンテキストのgetPackageName関数でアプリケーションのパッケージ名を取得
Settingsクラス
Settingsクラスでは、AndroidOSが提供している設定画面を呼び出すことができます。
用意されている関数ごとにUnity C#でのコード例と実行結果を紹介します。
関数実行時に引数が必要なものについては、必要な引数について紹介します。
インテントを呼び出すコードについては、下記の関数をベースとして実行します。
public static void Request_SettingsIntent(ActionIntent actionIntent){
var action = GetActionConstant(actionIntent); //1.
using (var activity = GetActivity()) //2.
{
using (var intent = new AndroidJavaObject("android.content.Intent", action)) //3.
{
activity.Call("startActivity", intent); //4.
}
}
}
Intentに与える引数は以下の関数を用いて取得します。
private static string GetActionConstant(ActionIntent actionIntent){
using (var setting = new AndroidJavaClass("android.provider.Settings"))
{
return setting.GetStatic<string>(actionIntent.ToString());
}
}
//こんな感じでSettingsの定数名を列挙型にしときます。
//GetActionConstant関数に与えることで、文字列型のactionを取得することができます。
public enum ActionIntent
{
ACTION_ACCESSIBILITY_SETTINGS,
ACTION_ADD_ACCOUNT,
ACTION_ADVANCED_MEMORY_PROTECTION_SETTINGS,
ACTION_AIRPLANE_MODE_SETTINGS,
ACTION_ALL_APPS_NOTIFICATION_SETTINGS,
ACTION_APN_SETTINGS,
ACTION_APPLICATION_DETAILS_SETTINGS,
ACTION_APPLICATION_DEVELOPMENT_SETTINGS,
ACTION_APPLICATION_SETTINGS,
ACTION_APP_LOCALE_SETTINGS,
ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS,
ACTION_APP_NOTIFICATION_SETTINGS,
ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
ACTION_APP_SEARCH_SETTINGS,
ACTION_APP_USAGE_SETTINGS,
ACTION_AUTO_ROTATE_SETTINGS,
ACTION_BATTERY_SAVER_SETTINGS,
ACTION_BIOMETRIC_ENROLL,
ACTION_BLUETOOTH_SETTINGS,
ACTION_CAPTIONING_SETTINGS,
ACTION_CAST_SETTINGS,
ACTION_CHANNEL_NOTIFICATION_SETTINGS,
ACTION_CONDITION_PROVIDER_SETTINGS,
ACTION_DATA_ROAMING_SETTINGS,
ACTION_DATA_USAGE_SETTINGS,
ACTION_DATE_SETTINGS,
ACTION_DEVICE_INFO_SETTINGS,
ACTION_DISPLAY_SETTINGS,
ACTION_DREAM_SETTINGS,
ACTION_FINGERPRINT_ENROLL,
ACTION_HARD_KEYBOARD_SETTINGS,
ACTION_HOME_SETTINGS,
ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS,
ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS,
ACTION_INPUT_METHOD_SETTINGS,
ACTION_INPUT_METHOD_SUBTYPE_SETTINGS,
ACTION_INTERNAL_STORAGE_SETTINGS,
ACTION_LOCALE_SETTINGS,
ACTION_LOCATION_SOURCE_SETTINGS,
ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS,
ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION,
ACTION_MANAGE_ALL_SIM_PROFILES_SETTINGS,
ACTION_MANAGE_APPLICATIONS_SETTINGS,
ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT,
ACTION_MANAGE_DEFAULT_APPS_SETTINGS,
ACTION_MANAGE_OVERLAY_PERMISSION,
ACTION_MANAGE_SUPERVISOR_RESTRICTED_SETTING,
ACTION_MANAGE_UNKNOWN_APP_SOURCES,
ACTION_MANAGE_WRITE_SETTINGS,
ACTION_MEMORY_CARD_SETTINGS,
ACTION_NETWORK_OPERATOR_SETTINGS,
ACTION_NFCSHARING_SETTINGS,
ACTION_NFC_PAYMENT_SETTINGS,
ACTION_NFC_SETTINGS,
ACTION_NIGHT_DISPLAY_SETTINGS,
ACTION_NOTIFICATION_ASSISTANT_SETTINGS,
ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS,
ACTION_NOTIFICATION_LISTENER_SETTINGS,
ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS,
ACTION_PRINT_SETTINGS,
ACTION_PRIVACY_SETTINGS,
ACTION_PROCESS_WIFI_EASY_CONNECT_URI,
ACTION_QUICK_ACCESS_WALLET_SETTINGS,
ACTION_QUICK_LAUNCH_SETTINGS,
ACTION_REGIONAL_PREFERENCES_SETTINGS,
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
ACTION_REQUEST_MANAGE_MEDIA,
ACTION_REQUEST_SCHEDULE_EXACT_ALARM,
ACTION_REQUEST_SET_AUTOFILL_SERVICE,
ACTION_SEARCH_SETTINGS,
ACTION_SECURITY_SETTINGS,
ACTION_SETTINGS,
ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY,
ACTION_SHOW_REGULATORY_INFO,
ACTION_SHOW_WORK_POLICY_INFO,
ACTION_SOUND_SETTINGS,
ACTION_STORAGE_VOLUME_ACCESS_SETTINGS,
ACTION_SYNC_SETTINGS,
ACTION_USAGE_ACCESS_SETTINGS,
ACTION_USER_DICTIONARY_SETTINGS,
ACTION_VOICE_CONTROL_AIRPLANE_MODE,
ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE,
ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE,
ACTION_VOICE_INPUT_SETTINGS,
ACTION_VPN_SETTINGS,
ACTION_VR_LISTENER_SETTINGS,
ACTION_WEBVIEW_SETTINGS,
ACTION_WIFI_ADD_NETWORKS,
ACTION_WIFI_IP_SETTINGS,
ACTION_WIFI_SETTINGS,
ACTION_WIRELESS_SETTINGS,
ACTION_ZEN_MODE_PRIORITY_SETTINGS,
}
-
actionに文字列型の定数を設定します。定数は公式ドキュメントのConstant Valueが設定されます。(ACTION_ACCESSIBILITY_SETTINGSであれば、下図を参照)
※GetActionConstant関数内で定数を取得しています。 -
GetActivity関数からアクティビティを取得します。
-
「android.content.Intent」とactionを引数としたAndroidJavaObjectを取得します。
-
startActivity関数を呼び出します。
引数がなく問題なく結果が確認できたもの
結果については下記リンクのConstantsに記載されている表から確認してください。
- ACTION_ACCESSIBILITY_SETTINGS
- ACTION_ADD_ACCOUNT
- ACTION_AIRPLANE_MODE_SETTINGS
- ACTION_ALL_APPS_NOTIFICATION_SETTINGS
- ACTION_APN_SETTINGS
- ACTION_APPLICATION_DEVELOPMENT_SETTINGS
- ACTION_APPLICATION_SETTINGS
- ACTION_APP_SEARCH_SETTINGS
- ACTION_AUTO_ROTATE_SETTINGS
- ACTION_BATTERY_SAVER_SETTINGS
- ACTION_BLUETOOTH_SETTINGS
- ACTION_CAPTIONING_SETTINGS
- ACTION_CAST_SETTINGS
- ACTION_CONDITION_PROVIDER_SETTINGS
- ACTION_DATA_ROAMING_SETTINGS
- ACTION_DATA_USAGE_SETTINGS
- ACTION_DATE_SETTINGS
- ACTION_DEVICE_INFO_SETTINGS
- ACTION_DISPLAY_SETTINGS
- ACTION_DREAM_SETTINGS
- ACTION_HARD_KEYBOARD_SETTINGS
- ACTION_HOME_SETTINGS
- ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
- ACTION_INPUT_METHOD_SETTINGS
- ACTION_INPUT_METHOD_SUBTYPE_SETTINGS
- ACTION_INTERNAL_STORAGE_SETTINGS
- ACTION_LOCALE_SETTINGS
- ACTION_LOCATION_SOURCE_SETTINGS
- ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS
- ACTION_MANAGE_ALL_SIM_PROFILES_SETTINGS
- ACTION_MANAGE_DEFAULT_APPS_SETTINGS
- ACTION_MANAGE_OVERLAY_PERMISSION
- ACTION_MANAGE_UNKNOWN_APP_SOURCES
- ACTION_MANAGE_WRITE_SETTINGS
- ACTION_REQUEST_MANAGE_MEDIA
- ACTION_REQUEST_SCHEDULE_EXACT_ALARM
- ACTION_MEMORY_CARD_SETTINGS
- ACTION_NETWORK_OPERATOR_SETTINGS
- ACTION_NFC_PAYMENT_SETTINGS
- ACTION_NFC_SETTINGS
- ACTION_SEARCH_SETTINGS
- ACTION_NIGHT_DISPLAY_SETTINGS
- ACTION_NOTIFICATION_ASSISTANT_SETTINGS
- ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS
- ACTION_PRINT_SETTINGS
- ACTION_PRIVACY_SETTINGS
- ACTION_SECURITY_SETTINGS
- ACTION_REQUEST_SET_AUTOFILL_SERVICE
- ACTION_SETTINGS
- ACTION_SHOW_REGULATORY_INFO
- ACTION_SHOW_WORK_POLICY_INFO
- ACTION_SOUND_SETTINGS
- ACTION_SYNC_SETTINGS
- ACTION_USAGE_ACCESS_SETTINGS
- ACTION_USER_DICTIONARY_SETTINGS
- ACTION_VOICE_INPUT_SETTINGS
- ACTION_VPN_SETTINGS
- ACTION_VR_LISTENER_SETTINGS
- ACTION_WEBVIEW_SETTINGS
- ACTION_WIFI_IP_SETTINGS
- ACTION_WIFI_SETTINGS
- ACTION_WIRELESS_SETTINGS
- ACTION_ZEN_MODE_PRIORITY_SETTINGS
- ACTION_MANAGE_APPLICATIONS_SETTINGS
実行時に引数を与えたりパーミッションを設定したり別途準備しないといけないもの
定数:"android.settings.APPLICATION_DETAILS_SETTINGS"
引数:The Intent's data URI specifies the application package name to be shown, with the "package" scheme. That is "package:com.my.app".
結果:パッケージ名で指定したアプリの詳細設定が表示されます(設定→アプリ→n個のアプリをすべて表示→任意のアプリ選択)
public static void Request_SettingsIntent(ActionIntent actionIntent, params string[] value)
{
var action = GetActionConstant(actionIntent);
using (var activity = GetActivity())
{
var uri = new AndroidJavaObject("android.net.Uri"); //1
var uriObject = uri.CallStatic<AndroidJavaObject>("fromParts", "package", value[0], null); //2
using (var intent = new AndroidJavaObject("android.content.Intent", action, uriObject)) //3
{
activity.Call("startActivity", intent);
}
}
}
value[0]からパッケージ名を取得できるものとします。
- android.net.Uriクラス(AndroidJavaObject)を取得します。
- fromParts関数に"package"という文字列、パッケージ名(value[0])を与え、URIオブジェクトをインスタンス化します。
- アクション定数とURIオブジェクトを引数としてIntentを取得します。
- startActivity関数で実行し、設定画面を表示します。
fromParts関数の引数は下記のとおりです(すべてstring型です)
-
scheme
URIのスキームです(今回は"package"を指定しました) -
ssp
スキーム固有の値です(今回はパッケージ名を指定しました) -
fragment
フラグです。今回は未使用です。よくわかりません。
例外エラーなどで意図した実行結果が確認できなかったもの
引数の設定方法がわからなかったもの
使い所
アプリの機能を使う上で、端末の設定を変更する必要があり、それをユーザに促す場面があると思います。そういった場面で、ユーザにアプリの画面から直接端末の設定画面に遷移させることで、スムーズに端末の設定ができると思います。
参考資料
-
++C++; 未確認飛行 C オブジェクト指向 ジェネリック 2019/08/19 ↩︎
-
++C++; 未確認飛行 C オーバオーロード解決 2018/04/15 ↩︎
Discussion