実現したいこと
あるアプリにおいて、他の特定のアプリが端末にインストールされているかどうかを判別し、その結果によって処理を変えたい。
例)特定のアプリがインストールされているかを判別し、
- されている場合 → そのアプリを起動
- されていない場合 → Google Play Storeに飛ばしてダウンロードを促す
自分の環境
- macOS BigSur 11.6.6
- Android Studio Arctic Fox | 2020.3.1 Patch 4
- Kotlin version 1.4.20
前提
カスタムURLスキーム(Custom URL Scheme)を利用した場合の解説をします。
そのため、インストール済みかどうかチェックをされる側のアプリがカスタムURLスキームを設定している必要があります。
例)
- YouTubeのURLスキーム →
vnd.youtube
- Google MapのURLスキーム →
geo
以前はバンドルID(Bundle ID)を用いてインストール済み判定ができたようですが、現在のAndroidではセキュリティの観点からこれはできなくなっているようです。(公式のソース未発見のため見つけた人は教えていただけるとありがたいです。)
自分で作成したアプリであれば自由にURLスキームを以下の方法で設定できます。
Custom URL Scheme の設定の仕方
※インストールされているかチェックされる側のアプリで設定します。
既存のアプリでインストール済み判定をする場合は必要ありませんので飛ばしてください。
AndroidManifest.xmlのmanifest -> application -> activity
要素の中に以下のintent-filter
要素を追加します。
your.url.scheme
の部分に設定したい任意の文字列を設定します。できる限り他のアプリと被らない文字列にすることをおすすめします。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="your.url.scheme" />
</intent-filter>
特定のアプリがインストールされているかを判別する
1. AndroidManifest.xmlに追加
このアプリを検出しますよというのをAndroidManifest.xmlに宣言します。
これがないと以降で書くコードは正常に動きません。
以下のqueries
要素をmanifest
要素の下(application
要素と同列)に追加します。
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="your.url.scheme"/>
</intent>
</queries>
2. 実際に判別する
以下のコードで判別することができます。
val uri = Uri.parse("your.url.scheme")
val i = Intent(Intent.ACTION_VIEW, uri)
if (i.resolveActivity(activity?.packageManager!!) != null) {
// インストールされている場合の処理
startActivity(i) // 該当アプリを開く場合
} else {
// インストールされていない場合の処理
// ストアに飛ばす処理など
}
備考
インストールされている場合は起動する、という場合は以下コードでも可。
ただ、推奨はされていないらしいので上記処理をした方が無難。
val uri = Uri.parse("your.url.scheme")
val i = Intent(Intent.ACTION_VIEW, uri)
try {
// アプリの起動
startActiviry(i)
} catch (e: ActivityNotFoundException)) {
// インストールされていない場合の処理
// ストアに飛ばす処理など
}
参考文献
https://developer.android.com/training/app-links/deep-linking?hl=ja
https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent)
https://developer.android.com/reference/android/content/pm/PackageManager#resolveActivity(android.content.Intent,%20android.content.pm.PackageManager.ResolveInfoFlags)
https://blog.asial.co.jp/1415