1
Help us understand the problem. What are the problem?

posted at

updated at

【Android】特定のアプリがインストール済みかチェックする【カスタムURLスキーム】

実現したいこと

あるアプリにおいて、他の特定のアプリが端末にインストールされているかどうかを判別し、その結果によって処理を変えたい。

例)特定のアプリがインストールされているかを判別し、

  • されている場合 → そのアプリを起動
  • されていない場合 → 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の部分に設定したい任意の文字列を設定します。できる限り他のアプリと被らない文字列にすることをおすすめします。

AndroidManifest.xml
<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要素と同列)に追加します。

AndroidManifest.xml
<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="your.url.scheme"/>
    </intent>
</queries>

2. 実際に判別する

以下のコードで判別することができます。

.kt
val uri = Uri.parse("your.url.scheme")
val i = Intent(Intent.ACTION_VIEW, uri)
if (i.resolveActivity(activity?.packageManager!!) != null) {
    // インストールされている場合の処理
    startActivity(i) // 該当アプリを開く場合
} else {
    // インストールされていない場合の処理
    // ストアに飛ばす処理など
}

備考

インストールされている場合は起動する、という場合は以下コードでも可。
ただ、推奨はされていないらしいので上記処理をした方が無難。

.kt
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

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?