API レベル: 19
Android 4.4(KITKAT
)は Android プラットフォームの新しいリリースで、ユーザーおよびアプリのデベロッパーに新しい機能を提供します。このドキュメントでは、いくつかの注目すべき API の概要について説明します。
アプリのデベロッパーの皆様には、お早めに、SDK Manager から Android 4.4 のシステム イメージおよび SDK プラットフォームをダウンロードしていただく必要があります。アプリをテストするにあたり、Android 4.4 が搭載された端末をお持ちでない場合は、Android 4.4 のシステム イメージを使用して Android エミュレータでアプリをテストしてください。Android 4.4 プラットフォーム向けにアプリを作成し、最新の API をご利用ください。
対象 API レベルのアップデート
Android 4.4 が搭載された端末向けにアプリを最適化するには、targetSdkVersion
を "19"
に設定し、Android 4.4 システム イメージにアプリをインストールした後、この変更を加えたアップデート済みのアプリを公開します。
Android 4.4 の API を使用しながら旧バージョンも同時にサポートするには、minSdkVersion
でサポートされていない API を実行する前に、システムの API レベルをチェックする条件をコードに追加します。下位互換性の維持については、異なるプラットフォーム バージョンのサポートをご覧ください。
API レベルの仕組みについては、API レベルとはをご覧ください。
重要な動作の変更点
過去に Android にアプリを公開したことがある場合は、アプリが Android 4.4 の変更による影響を受ける場合があります。
アプリが外部ストレージから読み込む場合
Android 4.4 を使用している場合、アプリに READ_EXTERNAL_STORAGE
パーミッションがなければ外部ストレージの共有ファイルを読み込むことができません。つまり、パーミッションがなければ getExternalStoragePublicDirectory()
で返されるディレクトリ内のファイルにアクセスできなくなりました。ただし、getExternalFilesDir()
で提供されるアプリ固有のディレクトリのみにアクセスする必要がある場合は、READ_EXTERNAL_STORAGE
パーミッションは不要です。
アプリが WebView を使用する場合
Android 4.4 では、特にアプリの targetSdkVersion
を "19" 以上に更新すると、アプリの動作が変わる可能性があります。
WebView
のクラスおよび関連 API を基盤とするコードがアップグレードされ、Chromium ソース コードの最新スナップショットがベースになりました。この変更によってさまざまな点でパフォーマンスが改善され、HTML5 の新機能や、WebView
コンテンツのリモート デバッグがサポートされています。このようなアップグレードにより、アプリで WebView
を使用すると、その動作に影響が生じる場合があります。既知の動作の変更についてはドキュメント化され、ほとんどの場合、アプリに影響するのはアプリの targetSdkVersion
を "19" 以上に更新した場合に限られますが(新しい WebView
は「Quirks モード」で動作し、API レベル 18 以下をターゲットとするアプリにレガシー機能を提供します)、以前のバージョンの WebView
の不明な動作にアプリが依存している可能性があります。
既存のアプリが WebView
を使用している場合、なるべく早めに Android 4.4 でテストを行うことが重要です。targetSdkVersion
を "19" 以上に更新したときにアプリが受ける影響については、Migrating to WebView in Android 4.4 を参照してください。
アプリが AlarmManager を使用する場合
アプリの targetSdkVersion
を "19" 以上に設定する場合、set()
または setRepeating()
で作成するアラームは厳密ではなくなりました。
電力効率を高めるため、Android はほぼ同時に発生したすべてのアプリのアラームをまとめて処理するようになりました。これにより、各アラームを処理するために何度も端末を起動させることなく、一度起動させるだけで済みます。
アラームが正確な時刻と関連付けられておらず、一定の時間の範囲(午後 2 時から 4 時までなど)に発生させる必要がある場合、新しい setWindow()
メソッドを使用できます。このメソッドは、アラームの「一番早い」時刻と、その時刻を起点としてアラームを発生させる必要がある「時間枠」を受け取ります。
アラームに正確な時刻を指定する必要がある場合は(カレンダー イベントのリマインダーなど)、新しい setExact()
メソッドを使用できます。
この厳密ではない一括処理の動作は、アップデートされたアプリにのみ適用されます。targetSdkVersion
を "18" 以下に設定すると、Android 4.4 で実行しても、アラームは以前のバージョンの動作を継続します。
アプリが ContentResolver を使用してデータを同期する場合
アプリの targetSdkVersion
を "19" 以上に設定し、addPeriodicSync()
で同期の指定をすると、デフォルトで、指定した期間の約 4% のフレックス間隔で同期操作が実行されます。たとえば、ポーリング間隔を 24 時間とすると、同期操作は大まかに毎日 1 時間の時間枠内で実行され、毎日正確に同じ時刻に実行されるわけではありません。
同期操作のフレックス間隔を独自に指定するには、新しい requestSync()
メソッドを使用する必要があります。詳細については、以下の同期アダプタのセクションをご覧ください。
このフレックス間隔の動作は、アップデートされたアプリにのみ適用されます。targetSdkVersion
を "18" 以下に設定すると、Android 4.4 で実行しても、既存の同期リクエストは以前のバージョンの動作を継続します。
印刷フレームワーク
Wi-Fi、Bluetooth などのサービスを介して接続されたプリンターを使用してあらゆるドキュメントを印刷できる完全なフレームワークが Android で利用できるようになりました。システムは、ドキュメントを印刷するアプリとやり取りするトランザクションと、印刷ジョブをプリンターに配信するサービスを処理します。android.print
フレームワークは、印刷ドキュメントを指定してシステムに配信し、印刷を指示するために必要なすべての API を提供します。指定した印刷ジョブに対して実際に必要になる API は、コンテンツによって異なります。
一般的なコンテンツの印刷
UI からコンテンツをドキュメントとして印刷する場合、まず PrintDocumentAdapter
のサブクラスを作成する必要があります。このクラス内で、コールバック メソッドをいくつか実装する必要があります。たとえば、指定した印刷プロパティに基づいてレイアウトを作成するための onLayout()
、印刷可能なコンテンツをシリアライズして ParcelFileDescriptor
に渡すための onWrite()
などがあります。
コンテンツを ParcelFileDescriptor
に書き込むには、PDF を渡す必要があります。新しい PdfDocument
API では、getCanvas()
で取得した Canvas
を使用して印刷可能なコンテンツを描画する方法が提供されているため便利です。次に、writeTo()
メソッドを使用して PdfDocument
を ParcelFileDescriptor
に書き込みます。
PrintDocumentAdapter
の実装を定義すると、PrintManager
メソッド print()
を使用したユーザーのリクエストが発生したときに印刷ジョブを実行できます。このメソッドは、引数の 1 つとして PrintDocumentAdapter
を取ります。
画像の印刷
写真などのビットマップを印刷する場合は、サポート ライブラリ内のヘルパー API にすべての処理をまかせることができます。それには、PrintHelper
の新しいインスタンスを作成し、setScaleMode()
でスケールモードを設定し、Bitmap
を printBitmap()
に渡します。これだけです。このライブラリが、システムとの残りのやり取りをすべて処理して、ビットマップをプリンターに配信します。
印刷サービスの作成
プリンター OEM として、android.printservice
フレームワークを使用すると、Android 端末とプリンターとの相互運用を実現できます。ユーザーが端末にインストール可能な APK として印刷サービスを作成し、配布できます。印刷サービス アプリは、PrintService
クラスをサブクラス化することで主にヘッドレス サービスとして動作します。システムから印刷ジョブを受信し、適切なプロトコルを使用してジョブをプリンターに送信します。
アプリのコンテンツを印刷する方法の詳細については、印刷コンテンツをご覧ください。
SMS プロバイダ
Telephony
コンテンツ プロバイダ(SMS プロバイダ)を使用すると、アプリで端末の SMS や MMS メッセージを読み書きできます。これには、受信、下書き、送信、保留中などの各 SMS や MMS メッセージのテーブルが含まれます。
Android 4.4 以降、システム設定でユーザーがデフォルトの SMS アプリを選択できるようになりました。デフォルトの SMS アプリを選択すると、そのアプリのみが SMS プロバイダに書き込むことができます。また、デフォルトの SMS アプリのみがユーザーが SMS を受信したときにSMS_DELIVER_ACTION
ブロードキャストを受信し、MMS を受信したときに WAP_PUSH_DELIVER_ACTION
ブロードキャストを受信することができます。デフォルトの SMS アプリは、新しいメッセージを送受信するときに SMS プロバイダに詳細を書き込みます。
デフォルトの SMS アプリとして選択されていないその他のアプリは、SMS プロバイダの読み取りのみが可能です。ただし、SMS_RECEIVED_ACTION
ブロードキャストをリッスンすることで、新しい SMS の着信時に通知を受信することもできます。これは、複数のアプリに配信される中断不能なブロードキャストです。このブロードキャストは、デフォルトの SMS アプリとして選択されていなくても、電話番号での認証の実行など、特定の受信メッセージを読み取る必要があるアプリでの使用を想定しています。
詳細については、ブログ投稿 Getting Your SMS Apps Ready for KitKat をご覧ください。
ワイヤレスと接続
ホスト カード エミュレーション
Android アプリで、データ交換に APDU(ISO7816-4 で規定)を使用する ISO14443-4(ISO-DEP)NFC カードをエミュレートできるようになりました。これにより、Android 4.4 を搭載する NFC 対応端末で、複数の NFC カードを同時にエミュレートできます。また、NFC 決済端末やその他の NFC リーダーで、アプリケーション ID(AID)に基づいて該当する NFC カードとのトランザクションを開始することもできます。
アプリでこれらのプロトコルを使用する NFC カードのエミュレートが必要なときは、HostApduService
クラスをベースにサービス コンポーネントを作成します。一方、アプリでセキュア エレメントを使用してカードをエミュレートする場合、OffHostApduService
クラスをベースにしたサービスを作成する必要があります。これはトランザクションには直接関係しませんが、セキュアエレメントで扱わなければならない AID を登録するために必要です。
詳細については、NFC カード エミュレーション ガイドをご覧ください。
NFC リーダー モード
新しい NFC リーダー モードでは、アクティビティがフォアグラウンドの間、すべての NFC アクティビティを、対象となるタグの種類の読み取りのみに限定できます。アクティビティでリーダー モードを有効にするには、enableReaderMode()
を使用します。これは、新しいタグが検出されたときにコールバックを受信する NfcAdapter.ReaderCallback
の実装を提供します。
この新しい機能をホスト カード エミュレーションと組み合わせれば、モバイル決済インターフェースの双方で Android を動作させることができます。1 台の端末が決済端末(リーダー モード アクティビティを実行する端末)として動作し、別の端末が決済クライアント(NFC カードをエミュレートする端末)として動作します。
赤外線通信機能
赤外線(IR)通信機能を搭載した端末を使用している場合、ConsumerIrManager
API を使用した IR 信号の送信が可能になりました。ConsumerIrManager
のインスタンスを取得するには、CONSUMER_IR_SERVICE
を引数に指定して getSystemService()
を呼び出します。次に、getCarrierFrequencies()
で IR の周波数を照会して、transmit()
で目的の周波数と信号パターンを渡すことで信号を送信できます。
必ず最初に hasIrEmitter()
を呼び出して、IR 通信機能が搭載されているかを確認してください。IR 通信機能を搭載している端末のみと互換性があるアプリでは、マニフェストで <uses-feature>
要素を含めて "android.hardware.consumerir"
(FEATURE_CONSUMER_IR
)を指定する必要があります。
マルチメディア
Adaptive Playback
MediaCodec
API を使用して Adaptive Video Playback のサポートを利用できるようになりました。これにより、Surface
で再生中の解像度をシームレスに変更できます。新しい解像度のデコーダの入力フレームをフィードして、出力バッファの解像度をスムーズに変更できます。
Adaptive Playback を有効にするには、KEY_MAX_WIDTH
と KEY_MAX_HEIGHT
の 2 つのキーを MediaFormat
に追加します。これは、アプリがコーデックに求める最大解像度を指定します。これらを MediaFormat
に追加したら、configure()
で MediaFormat
を MediaCodec
インスタンスに渡します。
コーデックは、渡された値以下の解像度にシームレスに切り替えます。コーデックは指定した最大値以上の解像度もサポートしていますが(サポート対象プロファイルの制限内)、大きい解像度への切り替えはシームレスに行われない場合があります。
H.264 動画のデコード中に解像度を変更するには、MediaCodec.queueInputBuffer() を使用してフレームをキューに追加し続けながら、Instantaneous Decoder Refresh(IDR)フレームと共に必ず新しい Sequence Parameter Set(SPS)値と Picture Parameter Set(PPS)値を 1 つのバッファで提供します。
ただし、Adaptive Playback のコーデックの設定を試みる前に、FEATURE_AdaptivePlayback
を指定して isFeatureSupported(String)
を呼び出し、端末が Adaptive Playback をサポートしていることを確認する必要があります。
注: Adaptive Playback のサポートはベンダーによって異なります。コーデックによっては、解像度が大きくなることが検知されるとより多くのメモリを必要とする場合があります。したがって、デコードする参照元のマテリアルに基づいて、解像度の最大値を設定する必要があります。
オンデマンド オーディオ タイムスタンプ
オーディオと動画の同期を改善するため、新しい AudioTimestamp
クラスでは、AudioTrack
で処理されるオーディオ ストリームの特定の「フレーム」についてタイムラインの詳細を提供します。最新のタイムスタンプを利用するには、AudioTimestamp
オブジェクトをインスタンス化して getTimestamp()
に渡します。タイムスタンプのリクエストが成功すると、AudioTrack
インスタンスに、フレーム単位の位置に加えて、フレームの推定時間(過去または確実な将来のプレゼンテーション時間)が追加されます。
AudioTimestamp
の nanoTime
の値(単調)を使用して、framePosition
と比較して関連する最も近い動画フレームを見つけて、オーディオに一致するよう動画フレームをドロップ、複製、補間できます。または、nanoTime
の値と、それ以降の動画フレームの予想時間(サンプルレートを考慮)のデルタタイム(差分)を判断し、どのオーディオ フレームが動画フレームと同じ瞬間になるかを予測します。
Surface Image Reader
新しい ImageReader
API は、画像バッファが Surface
にレンダリングされる際に画像バッファへの直接アクセスを可能にします。静的メソッドの newInstance()
を使用して ImageReader
を取得できます。次に、getSurface()
を呼び出して新しい Surface
を作成し、画像データを MediaPlayer
や MediaCodec
などのプロデューサで配信します。新しい画像が Surface から入手可能になったときに通知を受けるには、ImageReader.OnImageAvailableListener
インターフェースを実装して setOnImageAvailableListener()
で登録します。
Surface
にコンテンツを描画するときは、新しい画像フレームが利用できるようになるたびに ImageReader.OnImageAvailableListener
が onImageAvailable()
への呼び出しを受け取り、対応する ImageReader
を提供します。acquireLatestImage()
または acquireNextImage()
を呼び出すと、ImageReader
を使用してフレームの画像データを Image
オブジェクトとして取得できます。
Image
オブジェクトは、ByteBuffer
内の画像のタイムスタンプ、形式、寸法、ピクセルデータへの直接アクセスを可能にします。ただし、Image
クラスで画像を解釈するには、ImageFormat
または PixelFormat
内の定数で定義されたいずれかのタイプに従ってフォーマットされている必要があります。
ピークと RMS の測定
現在のオーディオ ストリームのピークと RMS を Visualizer
から照会できるようになりました。照会するには、Visualizer.MeasurementPeakRms
のインスタンスを作成して getMeasurementPeakRms()
に渡します。このメソッドを呼び出すと、指定した Visualizer.MeasurementPeakRms
のピーク値と RMS 値が最新の測定値に設定されます。
ラウドネス エンハンサー
LoudnessEnhancer
は AudioEffect
の新しいサブクラスで、MediaPlayer
または AudioTrack
の音量を上げることができます。これを前述の新しい getMeasurementPeakRms()
メソッドと組み合わせると、他のメディアを再生しているときに会話のオーディオ トラックの音量を上げることができ、特に便利です。
リモート コントローラー
Android 4.0(API level 14)で RemoteControlClient
API が導入され、ロック画面のメディア コントロールなど、リモート クライアントからのメディア コントローラー イベントをメディアアプリで処理できるようになりました。新しい RemoteController
API を使用すると独自のリモート コントローラーを作成でき、RemoteControlClient
と統合したメディア アプリの再生を制御する、革新的な新しいアプリや機器の作成が可能になります。
リモート コントローラーを作成する際は好きな方法でユーザー インターフェースを実装できますが、メディアボタン イベントをユーザーのメディアアプリに配信するには、NotificationListenerService
クラスを拡張して RemoteController.OnClientUpdateListener
インターフェースを実装するサービスを作成する必要があります。NotificationListenerService
を基盤として使用することが重要です。これによって適切なプライバシー制限が提供され、ユーザーはシステムのセキュリティ設定でアプリを通知リスナーとして有効にすることが求められます。
NotificationListenerService
クラスには、実装する必要があるいくつかの抽象メソッドが含まれていますが、メディアの再生を処理するためのメディア コントローラー イベントだけが関係する場合はこれらの実装を空のままにして、代わりに RemoteController.OnClientUpdateListener
メソッドに専念することができます。
リモート コントローラーからの評価
Android 4.4 は、リモート コントロール クライアント(RemoteControlClient
を使用してメディア コントロール イベントを受け取るアプリ)の既存の機能を基盤に、リモート コントローラーから現在のトラックを評価できる機能を追加して構築されています。
新しい Rating
クラスは、ユーザーの評価に関する情報をカプセル化します。評価は、評価スタイル(RATING_HEART
、RATING_THUMB_UP_DOWN
、RATING_3_STARS
、RATING_4_STARS
、RATING_5_STARS
、RATING_PERCENTAGE
のいずれか)とそのスタイルに適切な評価値で定義されます。
ユーザーがリモート コントローラーでトラックを評価できるようにするには:
-
setTransportControlFlags()
にFLAG_KEY_MEDIA_RATING
フラグを追加して、評価 UI をユーザーに表示するよう指定します。 editMetadata()
を呼び出してRemoteControlClient.MetadataEditor
を取得し、これにRATING_KEY_BY_USER
をaddEditableKey()
を使用して渡します。- 次に、
putObject()
を呼び出し、RATING_KEY_BY_USER
をキーとして、また上記の表のいずれかのスタイルを値として渡し、評価スタイルを指定します。
ユーザーがリモート コントローラーから評価を変更したときにコールバックを受け取るには、新しい RemoteControlClient.OnMetadataUpdateListener
インターフェースを実装し、インスタンスを setMetadataUpdateListener()
に渡します。ユーザーが評価を変更したら、RemoteControlClient.OnMetadataUpdateListener
は onMetadataUpdate()
の呼び出しを受け取り、RATING_KEY_BY_USER
をキーとして、また Rating
オブジェクトを値として渡します。
クローズド キャプション
VideoView
は、WebVTT サブタイトル トラックをサポートするようになりました。HTTP Live Stream(HLS)動画を再生すると、ユーザーがシステム設定で定義したクローズド キャプションのプリファレンスに従ってサブタイトル トラックを表示します。
addSubtitleSource()
メソッドを使用して、VideoView
に WebVTT サブタイトル トラックを提供することもできます。このメソッドは、サブタイトル データを含む InputStream
と、サブタイトル データの形式を指定する MediaFormat
オブジェクトを受け入れます。形式は createSubtitleFormat()
で指定できます。これらのサブタイトルは、ユーザーのプリファレンスに従って動画にも表示されます。
動画コンテンツの表示に VideoView
を使用しない場合は、ユーザーのクローズド キャプションのプリファレンスにできる限り近い設定で、サブタイトル オーバーレイを作成する必要があります。新しい CaptioningManager
API を使用すると、ユーザーのクローズド キャプションのプリファレンスを照会できます。これには CaptioningManager.CaptionStyle
で定義されたスタイル(書体や色など)が含まれます。動画を既に開始した後にユーザーがプリファレンスを調整した場合に備えて、プリファレンスが変更されたらコールバックを受け取るように CaptioningManager.CaptioningChangeListener
のインスタンスを登録し、プリファレンスの変更をリッスンする必要があります。次に、必要に応じてサブタイトルを更新します。
アニメーションとグラフィック
シーンと遷移
新しい android.transition
フレームワークは、ユーザー インターフェースのさまざまな状態をアニメーションで切り替える API を提供します。主な機能は、「シーン」と呼ばれる UI の状態を定義できる機能で、シーンごとに個別のレイアウトを作成できます。シーンの切り替えをアニメーション化する場合は「遷移」を実行します。これにより、現在のシーンから次のシーンにレイアウトを変更するために必要なアニメーションが計算されます。
2 つのシーン間で遷移するには、一般に次のステップを実行する必要があります。
- 変更したい UI コンポーネントを含む
ViewGroup
を指定します。 - 変更の最終結果(次のシーン)を表すレイアウトを指定します。
- レイアウト変更をアニメーション化する遷移の種類を指定します。
- 遷移を実行します。
Scene
オブジェクトを使用してステップ 1 および 2 を実行できます。Scene
には、遷移に必要なレイアウトのプロパティを記述したメタデータが含まれます(シーンの親ビューとシーンのレイアウトなど)。クラス コンストラクタまたは静的メソッド getSceneForLayout()
を使用して、Scene
を作成できます。
次に、TransitionManager
を使用してステップ 3 および 4 を実行する必要があります。1 つ目の方法は、Scene
を静的メソッド go()
に渡します。その結果、現在のレイアウトにシーンの親ビューが表示され、Scene
で定義されたレイアウトに到達するように子ビューで遷移を実行します。
または、Scene
オブジェクトは一切作成せず、代わりに beginDelayedTransition()
を呼び出して、変更したいビューを含む ViewGroup
を指定します。次に、ターゲット ビューを追加、削除、または再構成します。必要に応じてシステムが変更のレイアウトを行った後、遷移が開始され、影響するすべてのビューがアニメーションします。
さらに細かく制御するには、プロジェクトの res/transition/
ディレクトリにある XML ファイルを使用して、定義済みのシーン間で発生する一連の遷移を定義できます。<transitionManager>
要素内に <transition>
タグを 1 つ以上指定し、各タグでシーン(レイアウト ファイルへの参照)と、シーンの開始または終了時に適用する遷移を指定します。次に、inflateTransitionManager()
を使用して、一連の遷移をインフレートします。返された TransitionManager
を使用して、transitionTo()
で各遷移を実行し、いずれかの <transition>
タグで表された Scene
を渡します。TransitionManager
API を使用し、プログラムで一連の遷移を定義することもできます。
遷移を指定するときは、Fade
、ChangeBounds
など、Transition
のサブクラスによって定義された複数の定義済みタイプを使用できます。遷移のタイプを指定しなかった場合、デフォルトで AutoTransition
が使用され、必要に応じてビューのフェード、移動、サイズ変更が自動的に行われます。さらに、お好みのアニメーションを実行するようにクラスを拡張して、カスタム遷移を作成することもできます。カスタム遷移は、お好みで設定したプロパティの変更を追跡し、これらの変更に基づいて必要なアニメーションを作成できます。たとえば、ビューの「roration」プロパティの変更をリッスンし、変更をアニメーション化する Transition
のサブクラスを指定できます。
詳細については、TransitionManager
ドキュメントを参照してください。
Animator での一時停止
Animator
API で、pause()
メソッドおよび resume()
メソッドを使用して、実行中のアニメーションを一時停止および再開できるようになりました。
アニメーションの状態を追跡するには、Animator.AnimatorPauseListener
インターフェースを実装します。このインスタンスはアニメーションが一時停止および再開されたときのコールバック(pause()
および resume()
)を提供します。次に、addPauseListener()
で Animator
オブジェクトにリスナーを追加します。
または、AnimatorListenerAdapter
抽象クラスをサブクラス化できます。このとき、Animator.AnimatorPauseListener
で定義される一時停止と再開のコールバックの空の実装を含めることができるようになりました。
再利用可能なビットマップ
BitmapFactory
で可変ビットマップを再利用して、他のビットマップをデコードできるようになりました。新しいビットマップのサイズが異なっていても再利用可能です。ただし、デコードされたビットマップのバイト数(getByteCount()
で取得可能)が、再利用されるビットマップに割り当てられたバイト数(getAllocationByteCount()
で取得可能)以下であることが条件です。詳細については、inBitmap
をご覧ください。
Bitmap
の新しい API を使用すると、BitmapFactory
を使用しない再利用(ビットマップの手動生成またはカスタムのデコード ロジック)でも、同様の再構成が可能です。ビットマップのサイズを setHeight()
メソッドと setWidth()
メソッドで設定し、さらに元となるビットマップの割り当てに影響することなく新しい Bitmap.Config
を setConfig()
で指定できるようになりました。reconfigure()
メソッドを使用すると、これらの変更を 1 回の呼び出しで実行できるため便利です。
ただし、現在ビュー システムで使用されているビットマップを再構成することは避けてください。元のピクセル バッファが予想どおりに再マッピングされません。
ユーザー コンテンツ
ストレージ アクセス フレームワーク
Android の以前のバージョンでは、アプリで特定の種類のファイルを別のアプリから取得したい場合、ACTION_GET_CONTENT
アクションでインテントを起動する必要があります。アプリにインポートしたいファイルをリクエストする場合は、この方法が依然として適切です。ただし、Android 4.4 では ACTION_OPEN_DOCUMENT
アクションを導入し、ユーザーが特定の種類のファイルを選択して、ファイルをアプリにインポートしなくても、そのファイルに対する長期読み取りアクセスを(場合によっては書き込みアクセスも)アプリに付与できるようになりました。
ファイルのストレージ サービスを提供するアプリ(クラウド保存サービスなど)を開発している場合、新しい DocumentsProvider
クラスのサブクラスとしてコンテンツ プロバイダを実装すると、この統合 UI を利用してファイルを取得できます。DocumentsProvider
のサブクラスには、PROVIDER_INTERFACE
アクション("android.content.action.DOCUMENTS_PROVIDER"
)を受け入れるインテント フィルタを含める必要があります。次に、DocumentsProvider
で次の 4 つの抽象メソッドを実装します。
queryRoots()
- このメソッドは、
DocumentsContract.Root
で定義される列を使って、ドキュメント ストレージ内のすべてのルート ディレクトリを指すCursor
を返します。 queryChildDocuments()
- このメソッドは、
DocumentsContract.Document
で定義される列を使って、指定したディレクトリ内のすべてのファイルを指すCursor
を返します。 queryDocument()
- このメソッドは、
DocumentsContract.Document
で定義される列を使って、指定したファイルを指すCursor
を返します。 openDocument()
- このメソッドは、指定したファイルを表す
ParcelFileDescriptor
を返します。ユーザーがファイルを選択するとシステムがこのメソッドを呼び出し、クライアント アプリはopenFileDescriptor()
を呼び出してファイルへのアクセスをリクエストします。
詳細については、ストレージ アクセス フレームワーク ガイドをご覧ください。
外部ストレージへのアクセス
端末でエミュレートしたストレージと SD カードの両方を使用できる場合などに、セカンダリ外部ストレージ メディアにあるアプリ固有のファイルを読み書きできるようになりました。新しいメソッド getExternalFilesDirs()
は既存の getExternalFilesDir()
メソッドと同様に動作しますが、File
オブジェクトの配列を返す点が異なります。このメソッドで返されたいずれかのパスを読み書きする前に、File
オブジェクトを新しい getStorageState()
メソッドに渡して、現在ストレージを利用できることを確認します。
アプリ固有のキャッシュ ディレクトリおよび OBB ディレクトリにアクセスするその他のメソッドでも、セカンダリ ストレージ デバイスへのアクセスを提供する対応バージョンを使用できるようになりました。それぞれ、getExternalCacheDirs()
とgetObbDirs()
です。
返された File
配列の最初のエントリは、端末のプライマリ外部ストレージと見なされ、これは既存のメソッド(getExternalFilesDir()
など) で返される File
と同じです。
注: Android 4.4 以降、上記のメソッドを使用してアプリ固有の外部ストレージ領域のみにアクセスする必要がある場合、プラットフォームがアプリに WRITE_EXTERNAL_STORAGE
または READ_EXTERNAL_STORAGE
の取得を求めることはなくなりました。ただし、getExternalStoragePublicDirectory()
で提供される共有可能な外部ストレージ領域にアクセスする場合は、パーミッションが必要です。
同期アダプタ
ContentResolver
の新しい requestSync()
メソッドは、SyncRequest.Builder
で作成できる新しい SyncRequest
オブジェクトにリクエストをカプセル化することで、ContentProvider
の同期リクエストを定義する手順を簡素化します。SyncRequest
のプロパティは、既存の ContentProvider
の同期呼び出しと同じ機能を提供しますが、setDisallowMetered()
を有効にすると、ネットワークが従量制である場合は、同期を中止するように指定する機能が追加されています。
ユーザー入力
新しいセンサーの種類
新しい TYPE_GEOMAGNETIC_ROTATION_VECTOR
センサーは、磁力計に基づき回転ベクトルデータを提供します。これはジャイロスコープが利用できないときや、スマートフォンがスリープ中にバッチ処理するセンサーイベントに使用して端末の画面の向きを記録するときに、TYPE_ROTATION_VECTOR
センサーの代わりに使用できるため便利です。このセンサーは、TYPE_ROTATION_VECTOR
よりも消費電力を節約できますが、不要なイベント データになることが多いため、ユーザーが屋外にいるときに最も効果的です。
また、Android はハードウェアに組み込まれた歩数センサーにも対応しました。
TYPE_STEP_DETECTOR
- このセンサーはユーザーが歩いたときに 1 歩ごとにイベントをトリガーします。1 歩ごとに、値 1.0 と歩いた時刻を示すタイムスタンプを設定したイベントを配信します。
TYPE_STEP_COUNTER
- このセンサーも 1 歩検出するたびにイベントをトリガーしますが、このセンサーをアプリに最初に登録して以降累積した合計歩数を配信します。
この 2 つの歩数センサーは常に同じ結果を配信しているとは限らない点に注意してください。TYPE_STEP_DETECTOR
からのイベントよりも、TYPE_STEP_COUNTER
イベントが大幅に遅れて発生することがあります。これは、TYPE_STEP_COUNTER
のアルゴリズムでは、偽陽性を削減するためにより多くの処理を実行するためです。したがって、TYPE_STEP_COUNTER
のほうがイベントの配信が遅れる場合がありますが、結果の精度は向上しています。
どちらの歩数センサーもハードウェアに依存しているため(Nexus 5 がこれらのセンサーをサポートする最初の端末)、FEATURE_SENSOR_STEP_DETECTOR
定数とFEATURE_SENSOR_STEP_COUNTER
定数を使用するときは、hasSystemFeature()
で可用性を確認する必要があります。
センサー イベントのバッチ処理
端末の電力を適切に管理するため、SensorManager
API でアプリにセンサー イベントを一括して配信する頻度を指定できるようになりました。これにより、所定の期間中にアプリで使用できるセンサー イベントの数自体は削減されず、システムが SensorEventListener
を呼び出してセンサーの最新情報を渡す頻度が削減されます。つまり、イベント発生時に毎回アプリにイベントを配信する代わりに、所定の期間に発生したイベントをすべて保持し、後で一括してアプリに配信します。
バッチ処理を行うために、SensorManager
クラスで registerListener()
メソッドの 2 つのバージョンが新たに追加され、「最大レポート レイテンシ」を指定できるようになりました。この新しいパラメーターは、SensorEventListener
が新しいセンサー イベントの配信を待機する最大の遅延時間を指定します。たとえば、バッチのレイテンシを 1 分に設定すると、onSensorChanged()
メソッドの連続呼び出しの間隔が 1 分以内になるように、イベントがバッチ処理されるたびに最近のイベントのセットを一括で配信します。センサー イベントの遅延時間が最大レポート レイテンシの値を超えることはありませんが、他のアプリが同じセンサーに短いレイテンシを要求していると、それよりも早く報告される場合があります。
ただし、センサーがバッチ処理したイベントがレポート レイテンシに基づいてアプリを配信するのは、CPU が稼働している間だけである点に注意してください。バッチ処理をサポートしているハードウェア センサーは CPU が休止している間もセンサー イベントの収集を継続しますが、CPU を起動してバッチ処理したイベントをアプリに配信することはありません。センサーが最終的にイベントのメモリを使い切ると、古いイベントから順番に削除を開始して、最新のイベントを保存します。センサーのメモリがいっぱいになる前に端末を起動し、flush()
を呼び出して最新のイベントのバッチを取得すると、イベントの取りこぼしを避けられます。メモリがいっぱいになり flush が必要になるタイミングを予測するには、getFifoMaxEventCount()
を呼び出して保存可能なセンサーの最大数を取得し、アプリで各イベントを発生させたいペースでその数値を割ります。その計算結果を元に、AlarmManager
で起動アラームを設定します。このアラームは Service
(SensorEventListener
を実装している)を起動して、センサーをバッチ処理します。
注: センサー イベントのバッチ処理は、ハードウェア センサーが対応している必要があるため、すべてのデバイスがサポートしているわけではありません。ただし Android 4.4 以降は、必ず新しい registerListener()
メソッドを使用する必要があります。そうすれば端末がバッチ処理をサポートしてい場合、システムが適切にバッチ レイテンシの引数を無視して、センサー イベントをリアルタイムで配信できます。
コントローラー ID
Android は接続された各コントローラーを固有の整数で識別するようになりました。この整数は、getControllerNumber()
で照会できるため、ゲームで異なるプレイヤーに各コントローラーを容易に関連付けられるようになります。各コントローラーの番号は、ユーザーがコントローラーを切断、接続、再構成すると変動する場合があるため、InputManager.InputDeviceListener
のインスタンスを登録し、各入力デバイスに対応するコントローラーの番号を追跡する必要があります。その後、変更が発生したときに各 InputDevice
の getControllerNumber()
を呼び出します。
接続されたデバイスから製品 ID とベンダー ID が提供されるようになり、この ID は getProductId()
と getVendorId()
で取得できます。取得できるデバイスのキーのセットに基づいてキーのマッピングを変更する必要がある場合は、hasKeys(int...)
を使用して、特定のキーを取得できるかをデバイスに照会できます。
ユーザー インターフェース
没入型フルスクリーン モード
画面全体に表示するレイアウトをアプリで使用するには、setSystemUiVisibility()
の新しい SYSTEM_UI_FLAG_IMMERSIVE
フラグ(SYSTEM_UI_FLAG_HIDE_NAVIGATION
と組み合わせて使用時)を使用すると、新しい没入型フルスクリーン モードを有効化できます。没入型フルスクリーン モードが有効になっている間、アクティビティは引き続きすべてのタップイベントを受け取ります。システムバーが通常表示されている領域に沿って内側にスワイプすると、システムバーが表示されます。このとき SYSTEM_UI_FLAG_HIDE_NAVIGATION
フラグ(および SYSTEM_UI_FLAG_FULLSCREEN
フラグ、該当する場合)がクリアされ、システムバーが表示されたままになります。ただし、しばらくしてからもう一度システムバーを非表示にしたい場合は、代わりに SYSTEM_UI_FLAG_IMMERSIVE_STICKY
フラグを使用します。
半透明のシステムバー
新しいテーマの Theme.Holo.NoActionBar.TranslucentDecor
と Theme.Holo.Light.NoActionBar.TranslucentDecor
を使用して、システムバーを部分的に半透明にできるようになりました。半透明のシステムバーを有効にすると、システムバーの背後の領域もレイアウトで埋められます。従って、レイアウト内でシステムバーで隠したくない部分については、fitsSystemWindows
を有効にする必要があります。
カスタムテーマを作成している場合、このいずれかのテーマを親テーマとして設定するか、作成したテーマに windowTranslucentNavigation
と windowTranslucentStatus
の各スタイル プロパティを含めます。
通知リスナーの機能強化
Android 4.3 で NotificationListenerService
API が追加され、システムによって送信された新しい通知に関する情報をアプリが受け取れるようになりました。Android 4.4 では、通知リスナーが追加のメタデータと、通知のアクションに関する完全な詳細を取得できます。
新しい Notification.extras
フィールドに Bundle
を含めて、EXTRA_TITLE
や EXTRA_PICTURE
などの追加のメタデータを通知ビルダーに配信できます。新しい Notification.Action
クラスは、通知にアタッチされたアクションの特性を定義します。このデータは新しい actions
フィールドから取得できます。
RTL レイアウト向けのドローアブル ミラーリング
以前の Android のバージョンでは、右から左へのレイアウトに合わせて水平方向に反転する必要がある画像がアプリに含まれている場合、ミラーリングした画像を drawables-ldrtl/
リソース ディレクトリに含める必要がありましたが、ドローアブル リソースで autoMirrored
属性を有効にするか setAutoMirrored()
を呼び出すと、画像を自動的にミラーリングできるようになりました。これを有効にすると、レイアウトの方向が右から左の場合、Drawable
が自動的にミラーリングされます。
ユーザー補助機能
View
クラスで、新しいテキスト コンテンツで動的に更新される UI の領域を「Live Region」として宣言できるようになりました。この機能を使用するには、新しい accessibilityLiveRegion
属性を XML レイアウトに追加するか、setAccessibilityLiveRegion()
を呼び出します。たとえば、「無効なパスワードです」という通知を表示するテキスト フィールドがあるログイン画面は、Live Region としてマークを付ける必要があります。そうすれば、メッセージが変更されたときにスクリーン リーダーが読み上げるようになります。
ユーザー補助機能サービスを提供するアプリは、AccessibilityNodeInfo.CollectionInfo
とAccessibilityNodeInfo.CollectionItemInfo
を使用して、リストビューやグリッドビューなど、ビュー コレクションに関する情報を提供する新しい API で機能を強化することもできます。
アプリのパーミッション
特定の新しい API を使用するには、アプリで <uses-permission>
タグを使用して、次の新しいパーミッションをリクエストする必要があります。
INSTALL_SHORTCUT
- ランチャーにショートカットをインストールする許可をアプリに付与します。
UNINSTALL_SHORTCUT
- ランチャーのショートカットをアンインストールする許可をアプリに付与します。
TRANSMIT_IR
- 端末の IR 通信機能(利用できる場合)を使用する許可をアプリに付与します。
注: Android 4.4 以降、getExternalFilesDir()
などのメソッドを使用してアプリ固有の外部ストレージ領域のみにアクセスする必要がある場合、プラットフォームが WRITE_EXTERNAL_STORAGE
または READ_EXTERNAL_STORAGE
の取得をアプリに求めることはなくなりました。ただし、getExternalStoragePublicDirectory()
で提供される共有可能な外部ストレージ領域にアクセスする場合は、依然としてパーミッションが必要です。
デバイス機能
次に、<uses-feature>
タグを使用して宣言できる新しいデバイス機能を紹介します。これによりアプリの要件を宣言して、Google Play でフィルタリングを有効にしたり、実行時に確認したりできます。
FEATURE_CONSUMER_IR
- デバイスはコンシューマー向けの IR デバイスと通信できます。
FEATURE_DEVICE_ADMIN
- デバイスはデバイス管理者からのデバイスポリシーの強化をサポートしています。
FEATURE_NFC_HOST_CARD_EMULATION
- デバイスはホストベースの NFC カード エミュレーションをサポートしています。
FEATURE_SENSOR_STEP_COUNTER
- デバイスには歩数計ハードウェアが搭載されています。
FEATURE_SENSOR_STEP_DETECTOR
- デバイスには歩行検出ハードウェアが搭載されています。
Android 4.4 のすべての API の変更点の詳細については、API Differences Report をご覧ください。