Android 5.0 の動作の変更点

動画

Dev Byte:Android 5.0 の新機能

動画

Dev Byte:通知

API レベル: 21

Android 5.0 には、新機能以外にもさまざまなシステムの変更や API の動作の変更が盛り込まれています。このドキュメントでは、アプリ開発において把握しておくべき主な変更点について説明します。

過去に Android にアプリを公開したことがある場合は、アプリが Android 5.0 の変更点による影響を受ける場合があります。

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

Android ランタイム(ART)

Android 5.0 では、Dalvik に代わって ART ランタイムがプラットフォームのデフォルトになりました。ART ランタイムは、試験運用版として Android 4.4 で導入されました。

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

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

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

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

通知

アプリの通知が Android 5.0 の変更点を考慮した設計になっていることを確認してください。Android 5.0 以上を対象にした通知の設計については、通知設計ガイドをご覧ください。

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

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

  • setColor() を使用して、アイコン画像の背後にある円形のアクセントカラーを設定する。
  • 色に関係するアセットを更新または削除する。アクション アイコンおよびメインの通知アイコンでは、非アルファ チャンネルはすべて無視されます。これらのアイコンはアルファ チャンネル限定と考えてください。通知アイコンは白、アクション アイコンはダークグレーで描画されます。

通知音と振動

現在、RingtoneMediaPlayer、または 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 に設定して、どのロック画面でも通知が表示されるように、通知を安全なものとしてマークしてください([Secure] など)。詳細については、ロック画面通知をご覧ください。

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 の暗号化のパフォーマンスも向上します。さらに、今回のリリースではネイティブの OpenGL ES(GLES)3.1 のサポートに加えて、新しいネイティブのメディア NDK API も導入されています。

Android 5.0 で提供される 64 ビットのサポートを利用するには、Android NDK のページから NDK Revision 10c をダウンロードしてインストールしてください。NDK の重要な変更点とバグ修正の詳細は、Revision 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 以前は、最初にインストールされたアプリによって指定された保護レベルをシステムが割り当てていたとしても、任意の端末にこのようなアプリを複数インストールすることができました。

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 暗号スイートは無効になりました。
  • Forward Secrecy 暗号スイート(ECDHE および DHE)が推奨されます。

これらの変更により、以下に示すケースで HTTPS または TLS / SSL 接続の障害が発生するおそれがあります。

Android 2.3 までさかのぼるすべての Android プラットフォーム バージョンで、Google Play Services の Security ProviderInstaller で既にこれらの変更が提供されています。

有効化された暗号スイートをサーバーがサポートしていない

たとえば、サーバーが 3DES または MD5 暗号スイートのみをサポートしている場合があります。この問題を修正するには、サーバーの構成を改善して、より強力な最新の暗号スイートとプロトコルを有効にすることをお勧めします。理想的には、TLSv1.2 および AES-GCM を有効にして、Forward Secrecy 暗号スイート(ECDHE、DHE)を有効化および優先してください。

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

サーバーへの接続に使用する暗号スイートをアプリが誤って推定している

たとえば、一部のアプリにはカスタム X509TrustManager が含まれていますが、authType パラメータとして期待される RSA ではなく、ECDHE_RSA または DHE_RSA が渡されるため、接続できません。

サーバーで TLSv1.1、TLSv1.2、または新しい TLS 拡張機能が許可されていない

たとえば、サーバーとの TLS/SSL ハンドシェイクで、誤って拒否されるかストールします。この問題を修正するには、TLS/SSL プロトコルに準拠するようサーバーをアップグレードすることをお勧めします。このアップグレードによって、サーバーが新しいプロトコルや TLSv1 や古いプロトコルと正常にネゴシエーションできるようになり、サーバーが理解できない TLS 拡張機能は無視するようになります。場合によっては、サーバーで TLSv1.1 および TLSv1.2 を無効にすると、サーバー ソフトウェアをアップグレードするまでは応急処置として動作する可能性があります。

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

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

端末管理者は管理対象プロファイルを端末に追加することができます。このプロファイルは管理者が所有者となり、管理者が管理対象プロファイルを制御できます。ただしユーザーの個人プロファイルとストレージ領域は引き続きユーザーが制御できます。この変更により、既存のアプリの動作に次のような影響を及ぼす可能性があります。

インテントの処理

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

インテントを起動する前に 1 つ以上のハンドラが存在することを確認すれば、この例外を防止できます。有効なハンドラを確認するには、Intent.resolveActivity() を呼び出します。この処理の例については、簡単にカメラアプリで写真を撮影する方法に関する記事をご覧ください。

複数のプロファイル間でファイルを共有する

プロファイルにはそれぞれ専用のファイル ストレージがあります。ファイル URI はファイル ストレージ内の特定の場所を参照します。これは、あるプロファイルでは有効なファイル URI が、他のプロファイルでは無効になることを意味します。これは一般に、アプリで問題になることはありません。アプリは通常、アプリで作成したファイルのみにアクセスするためです。ただし、アプリがインテントにファイルを添付する場合、ファイル URI を添付するのは危険です。場合によっては、他のファイルでそのインテントが処理される可能性があるからです。たとえば端末管理者が、画像撮影イベントは個人プロファイルのカメラアプリで処理する必要がある、と指定したとします。このインテントが管理対象プロファイル上のアプリで起動されると、カメラアプリは管理対象プロファイルで読み取り可能な場所に画像を書き込めなければなりません。

安全のため、プロファイルをまたがってファイルをインテントに添付する必要がある場合は、ファイルのコンテンツ URI を作成して使用する必要があります。コンテンツ URI を使用したファイル共有については、ファイルの共有をご覧ください。たとえば、端末管理者が ACTION_IMAGE_CAPTURE を個人プロファイルのカメラで処理するようにホワイトリストに登録したとします。インテントの EXTRA_OUTPUT を起動するときは、写真を保存する場所を指定するコンテンツ URI が含まれている必要があります。そうすれば、カメラアプリはその URI で指定された場所に画像を書き込むことができます。また、インテントを起動したアプリは、他のプロファイルでアプリが実行されても、そのファイルを読み取ることができます。

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

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