Tabelog Tech Blog

食べログの開発者による技術ブログです

Android13(APIレベル33)への対応について

この記事は 食べログアドベントカレンダー2022 の8日目の記事です。

初めまして、食べログAndroidアプリをメインで担当しているsadaです。
私は食べログシステム本部 アプリ開発部の基盤チームリーダーをしています。
アプリ基盤チームでは機能開発はあまり行わず、リファクタリングや開発環境(IDEやCI/CDなど)の整備、ライブラリ選定、アーキテクチャ設計など、食べログアプリの下支えをしているチームになります。

今回は私が直近で対応したAndroid13(APIレベル33)への対応について、書きたいと思います。
もし、まだ対応をされていない方がいれば、何かお役に立てば幸いです。

目次

前置き

2022年8月15日(米国時間)に「Android 13」が正式にリリースされました。
最初のアップデート対象は「Pixel 4/4 XL」以降のPixelスマートフォンのみになっていましたが、日本でもPixelユーザーが以前より増えていて、例年より食べログアプリでの最新OSがリリースされてからのシェアの伸びが良くなっている印象でした。

さらに今回のアップデートではプッシュ通知の権限許諾が必要になるなど、ユーザーとコミュニケーションを取る上で重要な部分に影響が出ていたため、例年より早めにOSバージョンのアップデート対応を実施しました。

どんな対応が必要だったか

Android13における新機能や変更点はこちらの公式ドキュメントのサマリーを参照していただくと良いかと思います。

この中で食べログアプリで実際に影響のあったもの、修正が必要になったものをいくつかご紹介したいと思います。

広告ID

マニュフェストでの宣言

広告IDを使用しているアプリは、Android13(APIレベル33)以上をターゲットにする場合に、マニフェストファイル内で、広告ID権限を宣言する必要があります。

<manifest ...>
    <!-- Required only if your app targets Android 13 or higher. -->
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

    <application ...>
        ...
    </application>
</manifest>

引用 : Permission required for advertising ID より

これを行わないと広告IDは自動的に削除され、0 を羅列した文字列に置換されてしまいます。

詳細はこちらのヘルプを参照していただくのが良いですが、Google Mobile Ads SDK(play-services-ads)などではすでにマニュフェストで宣言している可能性もありますので、確認してみてください。

マージ後のマニュフェストファイルはこちらのドキュメントに記載されている通り、Android StudioでAndroidManifest.xmlを開いて、左下にある「Merged Manifest」というタブを選択するだけでマージ後のマニフェストファイルが確認できます。

食べログではすでに宣言済みだったため、特に影響はなかったのですが、後述するPlay Consoleでの広告IDの利用用途を申告する必要はあったため、今回ご紹介しました。

Play Console での回答

おそらくPlay Console上でも警告のメッセージが表示されていると思いますのでお気づきの方も多いと思いますが、Android13をターゲットとするアプリをリリースするには広告IDをどのように利用しているか申告する必要があります。

申告は Play Console > ポリシー > アプリコンテンツ ページにある「広告ID」の項目に回答をすれば大丈夫です。
※「広告」の項目もありますのでご注意ください。

設問内容も、おそらくすでに回答済みと思われる Data Safety と同じものでしたので、そちらで調査済みであればその中の広告IDに関わる部分のみ回答するだけとなります。

Runtime Permission

ターゲットをAndroid13にすることで一番影響があったのは権限周りでした。
そのままのコードでは権限が取得できておらず機能が動かなかったり、意図していないタイミングで権限許諾ダイアログが表示されてしまっていたりしていました。

影響範囲

具体的に影響のあった箇所を以下に記載します。

Push通知の許諾

Android13より通知に関するRuntime Permissionが必要となりました。

ターゲットをAndroid13にした場合はRuntime Permissionを実装するしかないのでまだ良いのですが、気になるのはターゲットがAndroid12L(APIレベル32)以下で新規インストールした場合です。

ドキュメントには以下のように書かれています。

If your app targets 12L (API level 32) or lower, the system shows the permission dialog the first time your app starts an activity after you create a notification channel, or when your app starts an activity and then creates its first notification channel. This is usually on app startup.
 
引用 : Notification runtime permission より

最初に通知チャネルを生成したタイミングで自動的に権限許諾ダイアログが表示されるようになります。
許諾を取りたいタイミングで通知チャンネルを生成している場合は問題なく動きそうですが、そうでない場合は意図したタイミングで許諾が取れないので、修正が必要になります。

今回、食べログでは早めにAndroid13対応をすることでちゃんと許諾ダイアログを表示するようにしようとなったため、特に事前の対応は入れませんでした。

また、注意点としてHyperionのようなデバッグツールを使っている場合、debugビルド時のみimplementationしていると思いますが、Hyperionでも通知を利用しているため、起動時に権限許諾ダイアログが出てしまいます。
releaseビルドした際とは挙動が変わってしまうので、一時的に無効化するなどして確認するようにしましょう。

メディア権限が変更

写真などのメディアにアクセスする際の権限が変更となりました。

今までは READ_EXTERNAL_STORAGE の権限でしたが(食べログではACCESS_MEDIA_LOCATIONも)、Android13からは以下の3つに権限が分割されました。

Type of media Permission to request
Images and photos READ_MEDIA_IMAGES
Videos READ_MEDIA_VIDEO
Audio files READ_MEDIA_AUDIO

引用 : Granular media permissions より

食べログでは口コミに投稿する写真であったり、ユーザーのアイコンなどに設定する画像にアクセスしていますので、READ_MEDIA_IMAGESに変更する必要があります。(要バージョン分岐)

PermissionDispatcherが新しい権限に対応していなかった

こちらは実装上の都合ですが、食べログで権限チェックの際に利用していたOSSの PermissionDispatcher が現時点(2022月12月現在)では新しいPermissionに対応していませんでした。
また、食べログでは位置情報の権限は「正確な位置情報(ACCESS_FINE_LOCATION)」か「おおよその位置情報(ACCESS_COARSE_LOCATION)」のどちらかだけ許諾を取れれば現在地検索などの機能が使えますので、両方のパーミッションを求めてしまうとユーザーが「おおよその位置情報」を許諾した場合に拒否された扱いになってしまい、やや使いにくいケースがありました。

対応方法

PermissionDispatcherが未対応なだけが理由であれば、OSSにコントリビュートするのも手段として考えられたのですが、それ以外にActivity Result APIsへの移行もしたいと考えました。
現在はonRequestPermissionsResult()が非推奨となっており、いつまでも放置できないので、これを機に移行する判断をしました。

参考までにそれぞれ非推奨となったバージョンは以下のrelease noteをご参照ください。

上記より、今回は権限許諾処理用の自作クラスを作成し、権限許諾処理をすべて刷新することで対応しました。

また、テストをする際には以下に記載されている Android Debug Bridge(ADB) コマンドを利用することで、わざわざアプリ設定でデータクリアや権限設定を変更することなくテストできます。ぜひ活用してみてください。

以下、コマンド例です。

# 全権限をリセット
adb shell pm reset-permissions

# 通知権限のみを初期状態に戻す(clear-permission-flagsはAndroid13以降のみ使える)
adb shell pm revoke ${PACKAGE_NAME} android.permission.POST_NOTIFICATIONS
adb shell pm clear-permission-flags ${PACKAGE_NAME} android.permission.POST_NOTIFICATIONS user-set
adb shell pm clear-permission-flags ${PACKAGE_NAME} android.permission.POST_NOTIFICATIONS user-fixed

その他

その他にも色々変更点はありますが、大きな影響はないと判断して、今回は対応を見送っているものがいくつかありますので、そちらもご紹介したいと思います。

Predictive back gesture

予測型「戻る」ジェスチャー(Predictive back gesture)と言われるものがAndroid13から追加されました。

こちらについては DroidKaigi2022 で「Android アプリの内と外をつなぐ UI」というセッションでも紹介されていました。
※動画の中での説明箇所はこちらをご参照ください。

セッションの中でも説明されていますが、ジェスチャーナビゲーションが導入されて以来、今まではアプリが終了する際の戻るジェスチャーとホームジェスチャーは微妙に違うアニメーションをしていました。

これが予測型「戻る」ジェスチャーにより、同じアニメーションになります。

これは画像です。

引用 : Add support for the predictive back gesture
Figure 1: Mockup of the predictive back gesture look and feel on a phone」 より

対応方法

対応するには従来の onBackPressedonKeyDown/Up(KEYCODE_BACK)をAndroid13で追加されたonBackInvokedDispatcherに対応する必要があります。
ただ、普通に対応しようとするとAndroid13未満のOSへの対応などがあり大変なので、AndroidXで提供されている onBackPressedDispatcher を使うようにすれば従来とAndroid13以降の両方に対応することができます。
詳細はセッションの動画を見ていただくのが一番わかりやすいと思います。実装方法も紹介されています。

現在はデフォルトオプトアウトされていますので、今回のタイミングでは対応を見送りましたがオプトインは以下に記載されている通り、AndroidManifest.xml<application> タグ内で、android:enableOnBackInvokedCallback フラグを trueに設定するだけでできます。

おそらくすぐに(Android14とか?)デフォルトオプトインになったり、従来方式が非推奨になることもありえるかもしれませんので、できる時に移行することをお勧めします。

テキストコピーのプレビュー表示

Android13より、クリップボードにコピーしたテキストがプレビュー表示されるようになりました。

これは画像です。

引用 : Provide feedback when copying to the clipboard
「UI shown when content enters the clipboard in Android 13 and up.」 より

テキストをコピーした際に独自にSnackBarやToastなどを表示していると、レイアウトが被ってしまうので、注意が必要です。

また、センシティブな内容を隠すこともできます。
その場合は ClipboardManager#setPrimaryClip() を呼び出す前に、 ClipDataClipDescription にフラグを追加する必要があります。
詳細は以下の公式ドキュメントをご参照ください。

まとめ

いかがでしたでしょうか?
Android13にはご紹介した以外にも様々な機能が追加されています。

権限周りだと他には以下のようなものも追加されています。

  • 付近のWi-Fiデバイスにアクセスする権限
  • バックグラウンド時にボディセンサーにアクセスする権限
  • 正確なアラームを使用するための権限

それ以外にも 写真選択ツールテーマ別アプリアイコンアプリごとの言語設定 など、注目の機能もあります。
プロダクトによって影響範囲は異なるので、上記紹介させていただいたものだけでは知りたいことが足りてないかもしれませんが、これからcompileSdkを33に対応される方のお役に立てば幸いです。

明日は @k-sekido さんの「システムの理想を描くための取り組み」です。お楽しみに!