Android 5.0 の動作変更

API レベル: 21

Android 5.0 では、新機能に加えて、さまざまなシステム変更や API 動作の変更が行われています。このドキュメントでは、アプリで理解および考慮すべき主な変更点について説明します。

以前に Android 向けのアプリを公開したことがある場合は、Android 5.0 でのこれらの変更の影響を受ける可能性があるので注意してください。

新しいプラットフォーム機能の概要については、Android Lollipop のハイライトをご覧ください。

動画

Dev Byte: Android 5.0 の新機能

Dev Byte: 通知

Android ランタイム(ART)

Android 5.0 では、Dalvik がプラットフォームのデフォルトとして ART ランタイムに置き換えられました。ART ランタイムは Android 4.4 で試験運用版として導入されました。

ART の新機能の概要については、ART の概要をご覧ください。主な新機能は次のとおりです。

  • 事前(AOT)コンパイル
  • ガベージ コレクション(GC)の改善
  • デバッグ サポートの改善

ほとんどの Android アプリは、ART で変更なしで動作します。ただし、Dalvik で機能する一部の手法は ART では機能しません。最も重要な問題については、Android ランタイム(ART)でのアプリの動作確認をご覧ください。次の場合は特に注意してください。

  • アプリで Java Native Interface(JNI)を使用して C/C++ コードを実行しています。
  • 非標準コードを生成する開発ツール(一部の難読化ツールなど)を使用している。
  • ガベージ コレクションの圧縮と互換性のない手法を使用している。

通知

通知で Android 5.0 の変更を反映するようにしてください。 Android 5.0 以降向けの通知の設計について詳しくは、通知の設計ガイドをご覧ください。

マテリアル デザイン スタイル

通知は、新しいマテリアル デザイン ウィジェットに合わせて、白い(または非常に明るい)背景の上に暗いテキストで描画されます。すべての通知が新しいカラーパターンで正しく表示されることを確認してください。通知の表示が間違っている場合は、修正します。

  • setColor() を使用して、アイコン画像の背後にある円にアクセント カラーを設定します。
  • 色を含むアセットを更新または削除します。アクション アイコンとメインの通知アイコンで、アルファ版以外のチャンネルがすべて無視されます。これらのアイコンはアルファ版のみであると想定してください。白色の通知アイコンと濃いグレーのアクション アイコンが描画されます。

音とバイブレーション

現在、Ringtone クラス、MediaPlayer クラス、または Vibrator クラスを使用して通知に音とバイブレーションを追加している場合は、このコードを削除して、システムが優先モードで通知を正しく表示できるようにします。代わりに、Notification.Builder メソッドを使用して音とバイブレーションを追加します。

デバイスを RINGER_MODE_SILENT に設定すると、デバイスは新しい優先モードに入ります。RINGER_MODE_NORMAL または RINGER_MODE_VIBRATE に設定すると、デバイスは優先モードを終了します。

以前の Android では、タブレット デバイスの音量を制御するマスター ストリームとして STREAM_MUSIC が使用されていました。Android 5.0 では、スマートフォン デバイスとタブレット デバイスのマスター ボリューム ストリームが統合され、STREAM_RING または STREAM_NOTIFICATION によって制御されるようになりました。

ロック画面の公開設定

Android 5.0 では、デフォルトでユーザーのロック画面に通知が表示されるようになりました。 ユーザーは機密情報の漏洩を防ぐことを選択できます。この場合、通知に表示されるテキストはシステムによって自動的に秘匿化されます。この除去された通知をカスタマイズするには、setPublicVersion() を使用します。

通知に個人情報が含まれていない場合、または通知でのメディア再生コントロールを許可する場合は、setVisibility() メソッドを呼び出して、通知の公開設定レベルを VISIBILITY_PUBLIC に設定します。

メディア再生

メディアの再生ステータスやトランスポート コントロールを表示する通知を実装する場合は、カスタム RemoteViews.RemoteView オブジェクトではなく、新しい Notification.MediaStyle テンプレートの使用を検討してください。いずれの方法を使用する場合でも、通知の公開設定を VISIBILITY_PUBLIC に設定して、ロック画面からコントロールにアクセスできるようにしてください。Android 5.0 以降、ロック画面に RemoteControlClient オブジェクトが表示されなくなりました。詳しくは、アプリで RemoteControlClient を使用している場合をご覧ください。

ヘッドアップ通知

デバイスがアクティブなとき(つまり、デバイスがロック解除され、画面がオンになっているとき)に、小さなフローティング ウィンドウ(ヘッドアップ通知とも呼ばれます)に通知が表示されるようになりました。ヘッドアップ通知にはアクション ボタンも表示される点を除き、コンパクトな通知形式と同様に表示されます。ユーザーは、現在のアプリから移動することなく、ヘッドアップ通知に対する操作や、ヘッドアップ通知を非表示にできます。

ヘッドアップ通知をトリガーする可能性のある条件の例:

  • ユーザーのアクティビティが全画面モードになっている(アプリが fullScreenIntent を使用している)
  • 通知の優先度が高く、着信音またはバイブレーションが使用されている

これらのシナリオのいずれかでアプリに通知を実装する場合は、ヘッドアップ通知が正しく表示されていることを確認してください。

メディア コントロールと RemoteControlClient

RemoteControlClient クラスのサポートが終了しました。できるだけ早く新しい MediaSession API に切り替えてください。

Android 5.0 のロック画面では、MediaSession または RemoteControlClient のトランスポート コントロールは表示されません。代わりに、アプリで通知を通じてロック画面からメディア再生コントロールを提供できます。これにより、アプリはメディアボタンの表示をより細かく制御できるとともに、ロック状態でもロック解除状態でも、一貫したユーザー エクスペリエンスを提供できます。

Android 5.0 では、この目的のために新しい Notification.MediaStyle テンプレートが導入されています。Notification.MediaStyle は、Notification.Builder.addAction() で追加した通知アクションを、アプリのメディア再生通知に埋め込まれたコンパクト ボタンに変換します。セッション トークンを setSession() メソッドに渡して、この通知が進行中のメディア セッションを制御することをシステムに通知します。

通知の公開設定を VISIBILITY_PUBLIC に設定して、通知をロック画面に表示しても問題ないとマークしてください(セキュアか否かにかかわらず)。詳しくは、ロック画面通知をご覧ください。

アプリが Android TV または Wear プラットフォームで実行されている場合にメディア再生コントロールを表示するには、MediaSession クラスを実装します。また、アプリが Android デバイスでメディアボタン イベントを受信する必要がある場合は、MediaSession も実装する必要があります。

getRecentTasks()

Android 5.0 で新たにドキュメントとアクティビティの同時実行タスク機能が導入されたことに伴い(以下の履歴画面の同時ドキュメントとアクティビティの同時を参照)、ユーザーのプライバシーを向上させるため、ActivityManager.getRecentTasks() メソッドのサポートが終了しました。下位互換性を確保するために、このメソッドは引き続きデータの小さなサブセットを返します。これには、呼び出し元アプリの独自のタスクと、場合によってはその他の機密性の低いタスク(Home など)も含まれます。アプリがこのメソッドを使用して独自のタスクを取得している場合は、代わりに getAppTasks() を使用してその情報を取得します。

Android NDK での 64 ビットのサポート

Android 5.0 では、64 ビットシステムのサポートが導入されました。64 ビットの機能強化により、既存の 32 ビットアプリを完全にサポートしながら、アドレス空間を拡張してパフォーマンスを向上させます。また、64 ビットのサポートにより、暗号化における OpenSSL のパフォーマンスも向上します。さらにこのリリースでは、新しいネイティブ メディア NDK API とネイティブ OpenGL ES(GLES)3.1 サポートが導入されています。

Android 5.0 で提供されている 64 ビット サポートを使用するには、Android NDK のページから NDK リビジョン 10c をダウンロードしてインストールします。NDK の重要な変更とバグの修正の詳細については、リビジョン 10c のリリースノートをご覧ください。

サービスにバインドする

Context.bindService() メソッドは明示的な Intent を必要とし、暗黙的インテントが与えられると例外をスローするようになりました。アプリの安全性を確保するには、Service を開始またはバインドするときに明示的インテントを使用し、サービスのインテント フィルタを宣言しないでください。

WebView

Android 5.0 では、アプリのデフォルトの動作が変更されました。

  • アプリが API レベル 21 以降をターゲットとしている場合:
    • システムはデフォルトで混合コンテンツとサードパーティ Cookie をブロックします。混合コンテンツとサードパーティ Cookie を許可するには、それぞれ setMixedContentMode() メソッドと setAcceptThirdPartyCookies() メソッドを使用します。
    • これにより、描画する HTML ドキュメントの一部がシステムによってインテリジェントに選択されるようになりました。この新しいデフォルト動作により、メモリ使用量の削減とパフォーマンスの向上が実現します。ドキュメント全体を一度にレンダリングする場合は、enableSlowWholeDocumentDraw() を呼び出してこの最適化を無効にします。
  • API レベル 21 未満をターゲットとしているアプリの場合: 混合コンテンツとサードパーティ Cookie が許可され、常にドキュメント全体が一度にレンダリングされます。

カスタム権限の一意性の要件

権限の概要で説明されているように、Android アプリでは、プラットフォームの事前定義システム権限を使用せずに、独自の方法でコンポーネントへのアクセスを管理する手段として、カスタム権限を定義できます。アプリは、マニフェスト ファイルで宣言された <permission> 要素でカスタム権限を定義します。

カスタム権限を定義することが合法的かつ安全なアプローチであるシナリオは、いくつかあります。ただし、カスタム権限の作成は不要な場合もあります。権限に割り当てられた保護レベルによっては、アプリに潜在的リスクをもたらす可能性があります。

Android 5.0 では、権限を定義する他のアプリと同じキーで署名されていない限り、1 つのアプリのみが特定のカスタム権限を定義できるように動作が変更されています。

重複するカスタム権限を使用するアプリ

どのアプリも必要なカスタム権限を定義できるため、複数のアプリが同じカスタム権限を定義する可能性があります。たとえば、2 つのアプリが同様の機能を提供している場合、カスタム権限に同じ論理名が導出される可能性があります。アプリには、同じカスタム権限の定義を含む共通の公開ライブラリやコードサンプルを組み込むこともできます。

Android 4.4 以前では、最初にインストールされたアプリで指定された保護レベルがシステムによって割り当てられていましたが、1 つのデバイスに複数のそのようなアプリをインストールできました。

Android 5.0 以降では、異なる鍵で署名されたアプリに対して、新しいカスタム権限の一意性の制限が適用されます。今後は、権限を定義する他のアプリが同じ鍵で署名されていない限り、デバイス上の 1 つのアプリのみが特定のカスタム権限(名前で判別されます)を定義できるようになりました。重複するカスタム権限を使用してアプリをインストールしようとしたときに、権限を定義している常駐アプリと同じ鍵で署名されていない場合、システムはインストールをブロックします。

アプリに関する考慮事項

Android 5.0 以降では、アプリは以前と同様に引き続き独自のカスタム権限を定義でき、<uses-permission> メカニズムを通じて他のアプリにカスタム権限をリクエストできます。ただし、Android 5.0 で導入された新しい要件により、アプリへの影響を慎重に評価する必要があります。

次の点に注意してください。

  • アプリのマニフェストで <permission> 要素を宣言していますか?使用している場合、そのアプリはアプリやサービスの適切な機能に本当に必要か?または、代わりにシステムのデフォルトの権限を使用できますか?
  • アプリに <permission> 要素がある場合、その要素がどこから来たかわかりますか?
  • 実際に他のアプリが <uses-permission> を介してカスタム権限をリクエストするつもりですか?
  • アプリで <permission> 要素を含むボイラープレートまたはサンプルコードを使用していますか?それらの権限要素は実際に必要ですか?
  • カスタム権限で、シンプルな名前や、他のアプリと共通する可能性のある一般的な用語に基づいた名前を使用していますか?

新規インストールとアップデート

前述のとおり、Android 4.4 以前を搭載したデバイスでのアプリの新規インストールと更新は影響を受けず、動作に変更はありません。Android 5.0 以降を搭載したデバイスの新規インストールとアップデートでは、既存の常駐アプリですでに定義されているカスタム権限が定義されている場合、アプリのインストールが禁止されます。

Android 5.0 システム アップデートによる既存のインストール

カスタム権限を使用するアプリが広く配信、インストールされている場合、ユーザーがデバイスを Android 5.0 にアップデートすると、影響を受ける可能性があります。システム アップデートがインストールされると、システムはインストール済みのアプリを再検証し、カスタム権限のチェックも行います。検証済みの別のアプリですでに定義されているカスタム権限をアプリで定義していて、そのアプリが他のアプリと同じ鍵で署名されていない場合、システムはアプリを再インストールしません

推奨事項

Android 5.0 以降を搭載したデバイスでは、アプリをすぐに確認し、必要な調整を行い、更新版をできるだけ早くユーザーに公開することをおすすめします。

  • アプリでカスタム権限を使用している場合は、その作成元と、実際にそれらが必要かどうかを検討してください。アプリからすべての <permission> 要素を削除します。ただし、アプリの正常な機能に必要であることが確実な場合を除きます。
  • 可能であれば、カスタム権限をシステムのデフォルトの権限に置き換えることを検討してください。
  • アプリでカスタム権限が必要な場合は、アプリに固有の名前に変更します。たとえば、アプリの完全なパッケージ名にカスタム権限を追加します。
  • 異なる鍵で署名されたアプリスイートがあり、アプリがカスタム権限によって共有コンポーネントにアクセスする場合、共有コンポーネント内でカスタム権限が 1 回だけ定義されるようにします。共有コンポーネントを使用するアプリは、カスタム権限自体を定義するのではなく、 <uses-permission> メカニズムを通じてアクセスをリクエストする必要があります。
  • 一連のアプリを同じ鍵で署名している場合、各アプリは必要に応じて同じカスタム権限を定義できます。システムは、通常どおりにアプリをインストールできます。

TLS/SSL のデフォルト構成の変更

Android 5.0 では、アプリが HTTPS や他の TLS/SSL トラフィックに使用するデフォルトの TLS/SSL 構成が変更されました。

  • TLSv1.2 プロトコルと TLSv1.1 プロトコルが有効になりました。
  • AES-GCM(AEAD)暗号スイートが有効になりました。
  • MD5、3DES、エクスポート、静的鍵 ECDH 暗号スイートが無効になりました。
  • 前方秘匿性暗号スイート(ECDHE と DHE)が推奨されます。

この変更により、以下のごく一部のケースで HTTPS または TLS/SSL 接続の破損につながる可能性があります。

Google Play 開発者サービスのセキュリティ ProviderInstaller には、Android 2.3 以降の Android プラットフォーム バージョン全体で、すでにこれらの変更が反映されています。

有効な暗号スイートのいずれもサーバーでサポートしていない

たとえば、サーバーが 3DES または MD5 暗号スイートのみをサポートする場合があります。推奨される修正は、サーバーの設定を改善して、より強力で最新の暗号スイートとプロトコルを有効にすることです。理想的には、TLSv1.2 と AES-GCM を有効にして、前方秘匿性暗号スイート(ECDHE、DHE)を有効にして優先します。

また、カスタムの SSLSocketFactory を使用してサーバーと通信するようにアプリを変更することもできます。ファクトリは、デフォルトの暗号スイートに加えて、サーバーが必要とする暗号スイートの一部が有効になった SSLSocket インスタンスを作成するように設計する必要があります。

サーバーへの接続に使用される暗号スイートについて、アプリが誤った想定をしている

たとえば、一部のアプリにはカスタムの X509TrustManager が含まれています。これは、authType パラメータが RSA であると想定しているのに、ECDHE_RSA または DHE_RSA を受け取るために動作しません。

サーバーが TLSv1.1、TLSv1.2、または新しい TLS 拡張に対して耐性がない

たとえば、サーバーとの TLS/SSL handshake が誤って拒否されるか、停止します。推奨される修正は、TLS/SSL プロトコルに準拠するようサーバーをアップグレードすることです。これにより、サーバーはこれらの新しいプロトコルを正常にネゴシエートするか、TLSv1 または古いプロトコルをネゴシエートし、認識できない TLS 拡張を無視します。サーバー ソフトウェアがアップグレードされるまで、サーバーで TLSv1.1 と TLSv1.2 を無効にしておくことが一時的な措置として機能する場合があります。

また、カスタムの SSLSocketFactory を使用してサーバーと通信するようにアプリを変更することもできます。サーバーによって正しくサポートされているプロトコルのみが有効である SSLSocket インスタンスを作成するように、ファクトリを設計する必要があります。

管理対象プロファイルのサポート

デバイス管理者は、管理対象プロファイルをデバイスに追加できます。このプロファイルは管理者が所有します。これにより、管理者は管理対象プロファイルを管理できますが、ユーザーの個人用プロファイルとそのストレージ容量はユーザーの制御下に置いたままにします。この変更は、既存のアプリの動作に次のような影響を与える可能性があります。

インテントを処理する

デバイス管理者は、管理対象プロファイルからシステムアプリへのアクセスを制限できます。この場合、通常はそのアプリで処理できるインテントを管理対象プロファイルからアプリが呼び出し、管理対象プロファイルのインテントに適したハンドラがない場合、そのインテントによって例外が発生します。たとえば、デバイス管理者は、管理対象プロファイルのアプリがシステムのカメラアプリにアクセスできないように制限できます。アプリが管理対象プロファイルで実行され、MediaStore.ACTION_IMAGE_CAPTURE に対して startActivityForResult() を呼び出し、インテントを処理できるアプリが管理対象プロファイルに存在しない場合、ActivityNotFoundException が発生します。

これを防ぐには、インテントを呼び出す前に、インテントにハンドラが少なくとも 1 つあることを確認します。有効なハンドラかどうかを確認するには、Intent.resolveActivity() を呼び出します。この処理の例については、Take Photos Simply: カメラアプリで写真を撮影するをご覧ください。

プロファイル間でのファイルの共有

プロファイルごとに専用のファイル ストレージがあります。ファイル URI はファイル ストレージ内の特定の場所を参照するため、あるプロファイルで有効なファイル URI が別のプロファイルでは有効でないことを意味します。通常は、作成したファイルにアクセスするだけのアプリにとって、これは通常問題ではありません。ただし、アプリがインテントにファイルを添付する場合、ファイルの URI のアタッチは安全ではありません。状況によっては、インテントが他のプロファイルで処理されることがあるためです。たとえば、デバイス管理者は、画像キャプチャ イベントを個人用プロファイルのカメラアプリで処理するように指定できます。インテントが管理対象プロファイル上のアプリによって起動された場合、管理対象プロファイルのアプリが画像を読み取れる場所にカメラが画像を書き込める必要があります。

安全のため、プロファイル間で横断する可能性があるインテントにファイルを添付する必要がある場合は、ファイルのコンテンツ URI を作成して使用する必要があります。コンテンツ URI を使用したファイルの共有について詳しくは、ファイルを共有するをご覧ください。たとえば、デバイス管理者が個人用プロファイルのカメラによる ACTION_IMAGE_CAPTURE の処理を許可している場合があります。起動インテントの EXTRA_OUTPUT には、写真の保存場所を指定するコンテンツ URI が含まれている必要があります。カメラアプリは、その URI で指定された場所に画像を書き込めます。インテントを起動したアプリは、別のプロファイルにあるアプリでも、そのファイルを読み取ることができます。

ロック画面ウィジェットのサポートの削除

Android 5.0 では、ロック画面ウィジェットのサポートが削除されました。ホーム画面のウィジェットは引き続きサポートされます。