Unity Androidのアプリから、別アプリのインストール状況を調べる方法です。
アプリ間連携等の際に、アプリがインストールされていればアプリを開き、インストールされていなければストアへ飛ばす等の挙動をさせたいときに使用できます。
実装時のバージョンはUnity4.1.2。
対象のアプリがインストールされているかの判定には、
インストールされているアプリのパッケージ名をリストで取得して比較を行います。
今回はAndroidのJavaクラスやメソッドを呼び出すAndroidJavaObjectを使用して、
AndroidのPackageManagerから情報を取ってきます。
参考:
Unity Script Reference AndroidJavaObject
AndroidDevelopers PackageManager
以下、指定パッケージのアプリがインストールされているか確認するCheckInstalledPackageメソッド
CheckInstalledPackage
ネイティブ側からのプリミティブ型以外の戻り値(ActivityやPackageManagerやList等)はAndroidJavaObject型で受け取る事が可能です。
GetPackageNameを別メソッドに切り出しているのは、アプリが大量にインストールされている端末でのJNI ERRORを発生させないためです。
参考:[Fixed]: JNI local reference table summary (512 entries)
既存のアクティビティ内のメソッドを使うだけなら、Unity側の記述だけで使えるので便利です。
※Unity Android Player以外ではビルドが通らないので、メソッド全体を
#if UNITY_ANDROID
#endif
で括る。 また、エディタで実行するとエラーになるので、実機で確認しましょう。
アプリ間連携等の際に、アプリがインストールされていればアプリを開き、インストールされていなければストアへ飛ばす等の挙動をさせたいときに使用できます。
実装時のバージョンはUnity4.1.2。
対象のアプリがインストールされているかの判定には、
インストールされているアプリのパッケージ名をリストで取得して比較を行います。
今回はAndroidのJavaクラスやメソッドを呼び出すAndroidJavaObjectを使用して、
AndroidのPackageManagerから情報を取ってきます。
参考:
Unity Script Reference AndroidJavaObject
AndroidDevelopers PackageManager
以下、指定パッケージのアプリがインストールされているか確認するCheckInstalledPackageメソッド
CheckInstalledPackage
////// 指定パッケージのアプリがインストールされているか確認する /// private bool CheckInstalledPackage( string packageName ) { // 結果 bool result = false; AndroidJNI.AttachCurrentThread(); AndroidJNI.PushLocalFrame(0); try { // UnityPlayerActivityを取得 using( AndroidJavaClass jcUnityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) ) using( AndroidJavaObject joCurrentActivity = jcUnityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" ) ) // PackageManagerを取得 using( AndroidJavaObject joPackageManager = joCurrentActivity.Call<AndroidJavaObject>( "getPackageManager" ) ) //インストールアプリ情報リストを取得 using( AndroidJavaObject joApplicationInfoList = joPackageManager.Call<AndroidJavaObject>( "getInstalledApplications", 0 ) ) { // リストの要素数取得 int listSize = joApplicationInfoList.Call<int>( "size" ); // 対象のパッケージ名があるか探す for( int i = 0; i < listSize; i++ ) { // パッケージ名を取得 string pName = GetPackageName( joApplicationInfoList, i ); // パッケージ名を比較 if( !string.IsNullOrEmpty( pName ) && packageName.Equals( pName ) ) { // インストールされている result = true; break; } } } } catch (System.Exception ex) { Debug.Log( ex.Message ); } finally { AndroidJNI.PopLocalFrame(System.IntPtr.Zero); } return result; } ////// インストールアプリ情報リストから指定インデックスのパッケージ名を取得する /// private string GetPackageName( AndroidJavaObject joApplicationInfoList, int index ) { string pName = ""; AndroidJNI.AttachCurrentThread(); AndroidJNI.PushLocalFrame(0); try { // アプリ情報取得 using ( AndroidJavaObject joApplicationInfo = joApplicationInfoList.Call<AndroidJavaObject>( "get", index ) ) { // パッケージ名を取得 pName = joApplicationInfo.Get<string>( "packageName" ); } } catch (System.Exception ex) { return string.Empty; } finally { AndroidJNI.PopLocalFrame(System.IntPtr.Zero); } return pName; }
ネイティブ側からのプリミティブ型以外の戻り値(ActivityやPackageManagerやList等)はAndroidJavaObject型で受け取る事が可能です。
GetPackageNameを別メソッドに切り出しているのは、アプリが大量にインストールされている端末でのJNI ERRORを発生させないためです。
参考:[Fixed]: JNI local reference table summary (512 entries)
既存のアクティビティ内のメソッドを使うだけなら、Unity側の記述だけで使えるので便利です。
※Unity Android Player以外ではビルドが通らないので、メソッド全体を
#if UNITY_ANDROID
#endif
で括る。 また、エディタで実行するとエラーになるので、実機で確認しましょう。