やりたいこと
外部アプリを起動したい。
Android11からpackage-visibilityが導入され、外部アプリを起動するためのお作法が変更となった
とりあえず、起動させるためのお作法を記載
AndroidManifest.xml
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.BROWSABLE" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
MainActivity.java
String packageName = "hogehoge.co.jp";
String appUrl = "https://fugafuga.co.jp";
try {
// パッケージ起動
Intent intent = PackageManager.getLaunchIntentForPackage(packageName);
context.startActivity(intent);
} catch (Exception e1) {
try {
// パッケージ起動
Intent intent = PackageManager.getLeanbackLaunchIntentForPackage(packageName);
context.startActivity(intent);
} catch (Exception e2) {
try {
// URI起動
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(packageName);
intent.setData(Uri.parse(appUrl));
context.startActivity(intent);
} catch (Exception e3) {
Toast.makeText(context, "アプリを起動できません", Toast.LENGTH_SHORT).show();
}
}
}
解説
- AndroidManifest.xml:外部アプリと連携するためのQueries定義。対象アプリによりけりだが、この辺りを設定すれば、ほぼ対応できていると思われる
- MainActivity.java:getLaunchIntentForPackage()でスマホ向けアプリ起動を試みる、起動できない場合はExceptionga返却されるので次の起動をためす
getLeanbackLaunchIntentForPackage()でAndroidTV向けアプリの起動を試みる
最後に、URIスキーマでの起動を試みる
URIスキーマの調べ方
最後の起動方法については、対象のアプリのAndroidManifest.xmlを参照する必要がある
- インストールしている端末からAPKファイルの場所を特定する
adb shell pm list packages -f | findstr [パッケージ名]
→ package:/data/app/~~fugafugafugafuga==/[パッケージ名]-hogehogehogehogehoge==/base.apk=[パッケージ名] - APKファイルをPCにおとす
adb pull /data/app/~~fugafugafugafuga==/[パッケージ名]-hogehogehogehogehoge==/base.apk - APKを7Zipなどで解凍する
-
AXMLPrinter2でAndroidManifest.xmlを複合化する
java -jar AXMLPrinter2.jar AndroidManifest.xml > ConvertedManifest.xml - ConvertedManifest.xmlをテキストエディタで開いてスキームを確認(以下は、AmazonPrimeVideoの例)
ConvertedManifest.xml
<activity
android:name="com.amazon.ignition.MainActivity"
android:launchMode="2"
android:screenOrientation="0"
>
</activity>
<intent-filter
android:autoVerify="true"
>
<action
android:name="android.intent.action.VIEW"
>
</action>
<category
android:name="android.intent.category.DEFAULT"
>
</category>
<category
android:name="android.intent.category.BROWSABLE"
>
</category>
<data
android:scheme="https"
android:host="watch.amazon.com"
>
</data>
<data
android:scheme="http"
android:host="watch.amazon.com"
>
</data>
上記の例の場合、URIで起動する場合は、"https://watch.amazon.com" を指定することで起動できる
パラメータ渡し
Youtubeなどの例をあげると、Youtubeアプリを起動し、かつ、特定の動画を参照させたい場合があると思われる。
その場合、startActivityを行う前に、参照先のURLをintentに追加すれば解決できる
MainActivity.java
try {
// パッケージ起動
Intent intent = PackageManager.getLaunchIntentForPackage(packageName);
intent.setData(Uri.parse("https://xxxxx.yyyyyy"));
context.startActivity(intent);
} catch (Exception e1) {
:
最後に
AndroidManifest.xmlのqueries定義の代わりに、QUERY_ALL_PACKAGES権限を付与することでもできるが、アプリを公開する場合に、いろいろと申請が必要になるらしい。
すなおにqueriesに定義を書いた方が良いと思われる。