ロコガイド テックブログ

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

「地域のくらしを、かしこく、たのしく」する、株式会社ロコガイドの社員がいろいろな記事を書いています。

Android Qにむけて開発者が対応すべきことまとめ by Google I/O 2019

f:id:chibatching:20190529160750j:plain

こんにちは、普段は技術部でAndroidアプリの開発をしている@chibatchingです。
Google I/O 2019ではAndroid Qに向けて数々の新機能や変更点が発表されました。
その中でも既存のアプリが影響を受けた場合、対応が必要になりそうな箇所をまとめました。

[はじめに] NonNull, Nullable対応

既存のKotlinで書かれたアプリをAndroid Qでビルドするにはまずここから対応が必要です。

Android Pに引き続きKotlin Friendlyを実現するためのアノテーション対応が追加されています。 Kotlinで実装している場合、新たにNullableアノテーションが付与された箇所の扱いを適切に修正する必要があります。

Android Q improves the coverage of nullability annotations in the SDK for libcore APIs.

https://developer.android.com/preview/features#libcore-nullability

バックグラウンドでの位置情報取得

これまでのAndroidでは位置情報のパーミッションにフォアグラウンド・バックグラウンドの区別はなく、単に位置情報パーミッションを取得すればいつでも位置情報にアクセスすることができました。
Android Qからはプライバシー保護強化の一環としてバックグラウンドでの位置情報取得には追加のパーミッションが必要となっています。

Target SDK <= P Target SDK = Q
f:id:chibatching:20190529160030p:plain f:id:chibatching:20190529160035p:plain

Target SDKがAndroid P以下の場合はパーミッションのリクエスト時に「アプリ使用中のみ」と「常に」の2つの選択肢が出ます。 そのまま、コードを変更せずにTarget SDKをAndroid Qに上げるとアプリ使用中のみパーミッションを取得できます。

Target SDKがQの状態でバックグラウンドでの位置情報取得をリクエストしたい場合は、AndroidManifestとパーミッションリクエスト時にACCESS_BACKGROUND_LOCATIONを追加します。

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+   <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
 requestPermissions(
     arrayOf(
-        Manifest.permission.ACCESS_FINE_LOCATION
+        Manifest.permission.ACCESS_FINE_LOCATION,
+        Manifest.permission.ACCESS_BACKGROUND_LOCATION
     ),
     PERMISSION_REQUEST_CODE
 )

これでリクエスト時にバックグラウンドでの位置情報取得のパーミッションを同時にリクエストできます。

しかし、バックグラウンドでの位置情報を要求してもフォアグラウンドのパーミッションだけ許可されるというパターンも十分にあり得ます。 したがって、必要に応じてどのレベルで許可されたのか確認し処理を分岐することも検討していきましょう。

https://developer.android.com/preview/privacy/device-location

外部ストレージへのアクセスSandbox化

Android QではTarget SDKがQのアプリで外部ストレージ(Context.getExternalFilesDir()で取得したディレクトリ)へのアクセスにREAD_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGEといったパーミッションが不要になりました。
代わりに、アプリから外部ストレージへのアクセスはすべてSandbox化され自分のアプリで作成したファイルのみ参照可&アプリアンインストール時には作成したファイルがすべて削除されます。 外部ストレージに保存することでアンインストール後も情報を残しておくことを意図していたアプリは何かしらの対応が必要になりそうですね。(Sandbox化はopt-outも可能なようです)

音楽ファイルやビデオ、写真へのアクセスは MediaStore を、ダウンロードファイルやその他のファイルへのアクセスは DocumentProvider を使ってアクセスしましょうという従来から言われているお行儀の良いアプリにすることの必要性が強まった感じですね。

https://developer.android.com/preview/privacy/scoped-storage

バックグランドからのActivity起動が不可に

Android QではTarget SDKにかかわらず原則バックグラウンドからActivityを起動できなくなります。 これにより、突然バックグラウンドからActivityを起動してくる行儀の悪いアプリはOSレベルで制限が入ることになります。

https://developer.android.com/preview/privacy/background-activity-starts

デバイス固有IDの取得制限

Android Qではプライバシー保護強化のため、リセットできないデバイス固有値などの取得が制限されています。 デバイスを特定するためにこれらの値を使用している場合は広告IDなど、ユーザが任意にリセットできる識別子の利用をする必要があります。

具体的な制限を下記に記載します。

ランダム化されたMACアドレス

Android Qが動作している端末ではデフォルトでランダム化されたMACアドレスが返されます。
エンタープライズ用途のために、デバイスオーナーアプリでのみ実際のハードウェアMACアドレスを取得することができるようです。

/proc/net へのアクセス制限

VPN情報などこのディレクトリへのアクセスを必要としているアプリは NetworkStatsManagerConnectivityManager を利用するように変更する必要があります。

リセット不可固有IDへのアクセス制限

IMEIやシリアルナンバーといったリセットできないデバイス固有IDへのアクセスには READ_PRIVILEGED_PHONE_STATE パーミッションが必要になります。
この制限はTarget SDKがAndroid Qよりも低いアプリも対象になります。Target SDK毎の動作は以下のようになります。

  1. Target SDKがAndroid Qの場合、READ_PRIVILEGED_PHONE_STATE がなければ SecurityException が発生
  2. Target SDKがAndroid Q未満の場合、READ_PHONE_STATE パーミッションがあれば null またはプレースホルダ値が返却される。ない場合は SecurityException が発生。

https://developer.android.com/preview/privacy/data-identifiers

Dark Theme

Android QではOSレベルでDark Themeの設定が可能になります。 アプリ側ではDark Themeが有効であることを宣言しない限りはOS設定でDark Themeにしても影響は受けませんが、ユーザ体験を著しく下げることになるため対応することが強く推奨されていました。

お手軽にDark Themeを適用する方法としてForce Darkを許可する方法があります。 これはアプリのstyleに android:forceDarkAllowed="true" を追加するだけでシステムが自動でDark Themeを適用してくれます。

以下はトクバイアプリにForce Darkを適用したある画面の状態です

適用前 適用後
f:id:chibatching:20190529160043p:plain f:id:chibatching:20190529160047p:plain

意外とそれっぽくなるのですが、やはり画像周りは厳しいですね。

そういった場合はvalues-nightのように-nightをつけたリソースディレクトリに画像や色定義などを格納しておくとDark Themeになったときにはそちらのリソースを使うようにできます。

かけられる工数や必要性によって次のようなパターンでのDark Themeへの準備を行うことができそうです(上から順に工数が少ない)

  1. Dark Themeは対応しない
  2. システムでDark Theme設定しているのにアプリがDark Themeにならないのでユーザー体験的には悪くなります
  3. Force Darkを許可し、不自然なところ、視認性の悪いところを個別に -night リソースを用意して対応する
  4. Force Darkは許可せず、全体でDark Theme用の -night リソースを用意する

画像をベクタ化し、内部の色定義をカラーリソースを参照するようにするとDark Theme時に色だけ差し替えることもできるようなので画像を徐々にベクタ化して色の差し替えが容易にできるように準備をしておくのも効果がありそうです。

https://developer.android.com/preview/features/darktheme

まとめ

今回の変更点はプライバシー保護の強化を目的としている箇所が多く、これらの情報を利用していないアプリにとっては大きな影響がないものが多かったように思います。 ただ、Dark Themeへの対応は必須ではないものの対応することが強く推奨されておりAndroid Qユーザのユーザ体験を損ねないためにもできる限り対応していきたいですね。

また、今年のGoogle I/Oは現地で参加することができたのですが、ARや機械学習などの分野で行われたたくさんの熱い発表やそれに対する世界中のエンジニアの反応や空気感を感じることができとても面白かったです!

トクバイアプリの開発も、Android Qへの変更点対応だけでなく、こういった新しい技術などをどんどん取り入れていきます!