Android 8.1(API レベル 27)では、ユーザーとデベロッパー向けのさまざまな新機能が導入されています。このドキュメントでは、デベロッパー向けの新機能について説明します。
Android Oreo(Go バージョン)
Android Go は、世界中でインターネットを利用する何十億人ものユーザーの Android エクスペリエンスを最適化する取り組みです。Android 8.1 以降、Android はエントリレベルのデバイスに適したプラットフォームとなっています。Android Oreo(Go バージョン)構成の機能は次のとおりです。
- メモリの最適化。プラットフォーム全体のメモリ使用量を改善し、RAM が 1 GB 以下のデバイスでアプリを効率的に実行できるようにしました。
- 柔軟なターゲット設定オプション。新しいハードウェア機能定数を使用すると、Google Play を通じて通常のデバイスまたは低 RAM デバイスにアプリを配布できます。
- Google Play。すべてのアプリは Android Oreo(Go バージョン)を搭載したデバイスで利用できますが、Google Play では、何十億人ものユーザーに受け入れられるアプリの作成に関する ガイドラインに沿って、デベロッパーが特に最適化したアプリを公開します。
何十億人ものユーザー向けにビルドに関する ガイドラインを更新し、 Android Oreo(Go バージョン)デバイス向けにアプリを最適化する方法に関するガイダンスを追加しました。ほとんどのデベロッパーにとって、Android Oreo(Go バージョン)デバイスに備えるには、既存の APK を最適化するか、Google Play の 複数 APK 機能を使用して、APK の特定のバージョンを低 RAM デバイスをターゲットにすることをおすすめします。アプリの 軽量化と効率化は、デバイスに関係なく、すべてのユーザーにとってメリットとなることを忘れないでください。
ニューラル ネットワーク API
Neural Networks API は、TensorFlow Lite(Google のモバイル用クロス プラットフォーム ML ライブラリ)や Caffe2 などのデバイス上の機械学習フレームワークの計算と推論を高速化します。ダウンロードとドキュメントについては、TensorFlow Lite オープンソース リポジトリにアクセスしてください。TensorFlow Lite は Neural Networks API と連携して、モバイル デバイスで MobileNets、Inception v3、 スマート リプライなどのモデルを効率的に実行します。
自動入力フレームワークの更新
Android 8.1(API レベル 27)では、アプリに組み込むことができる自動入力フレームワークが改善されています。
BaseAdapter
クラスに setAutofillOptions()
メソッドが追加されました。これにより、アダプター内の値の文字列表現を提供できます。これは、アダプター内で値を動的に生成するスピナー コントロールで役立ちます。たとえば、setAutofillOptions()
メソッドを使用して、ユーザーがクレジット カードの有効期限の一部として選択できる年リストの文字列表現を提供できます。自動入力サービスは、文字列表現を使用して、データを必要とするビューを適切に入力できます。
さらに、AutofillManager
クラスには、仮想構造内のビューの表示に関する変更についてフレームワークに通知するために呼び出すことができる notifyViewVisibilityChanged(View, int, boolean)
メソッドが含まれています。また、非仮想構造用のメソッドのオーバーロードもあります。ただし、非仮想構造の場合、このメソッドは通常、View
クラスによってすでに呼び出されているため、フレームワークに明示的に通知する必要はありません。
また、Android 8.1 では、SaveInfo
内に CustomDescription
and
Validator
のサポートを追加することで、自動入力サービスが保存 UI のアフォーダンスをカスタマイズできるようにしています。
カスタムの説明は、自動入力サービスが何を保存するかを明確にするのに役立ちます。たとえば、画面にクレジット カードが含まれている場合は、クレジット カード銀行のロゴ、クレジット カード番号の下 4 桁、有効期限番号を表示できます。詳細については、
CustomDescription
クラスをご覧ください。
Validator
オブジェクトは、Validator 条件が満たされていない場合に自動入力保存 UI が表示されないようにするために使用されます。詳しくは、
Validator クラスとそのサブクラス(
LuhnChecksumValidator および RegexValidator)をご覧ください。
通知
Android 8.1 では、通知が次のように変更されています。
- アプリでは、通知アラートを 1 秒に 1 回だけ音を鳴らすことができるようになりました。このレートを超えるアラート音はキューに追加されず、失われます。通知の動作の他の側面には影響せず、通知メッセージは引き続き想定どおりに送信されます。
-
NotificationListenerService
とConditionProviderService
は、ActivityManager.isLowRamDevice()
が呼び出されたときにtrue
を返す低 RAM の Android 搭載デバイスではサポートされていません。
EditText の更新
API レベル 27 以降では、EditText.getText()
メソッドは Editable
を返します。以前は CharSequence
を返していました。Editable
が CharSequence
を実装するため、この変更には下位互換性があります。
Editable
インターフェースには有用な追加機能が用意されています。たとえば、Editable
は Spannable
インターフェースも実装しているため、EditText
のインスタンス内のコンテンツにマークアップを適用できます。
プログラマティックなセーフ ブラウジング アクション
Safe Browsing API の
WebView
実装を使用すると、Google が既知の脅威として分類した URL に WebView
のインスタンスが移動しようとした場合に、それをアプリで検出できます。デフォルトでは、既知の脅威についてユーザーに警告するインタースティシャルが WebView
に表示されます。この画面では、このまま URL を読み込むか、安全な前のページに戻るかを選択できます。
Android 8.1 では、既知の脅威に対するアプリの対応方法をプログラムで定義できます。
- アプリからセーフ ブラウジングに既知の脅威を報告するかどうかは、ユーザーが管理できます。
- セーフ ブラウジングで既知の脅威に分類された URL に遭遇するたびに、安全なページに戻るなどの特定のアクションをアプリに自動的に実行させることができます。
注: 既知の脅威に対する保護を最適化するには、セーフ ブラウジングを初期化してから WebView
オブジェクトの loadUrl()
メソッドを呼び出してください。
次のコード スニペットは、既知の脅威に遭遇した後に常に安全な状態に戻るようにアプリの WebView
インスタンスに指示する方法を示しています。
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="true" /> </application> </manifest>
Kotlin
private var superSafeWebView: WebView? = null private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this).apply { webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false startSafeBrowsing(this@SafeBrowsingActivity, { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); }
Kotlin
class MyWebViewClient : WebViewClient() { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponse ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } }
Java
public class MyWebViewClient extends WebViewClient { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponse callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } }
動画のサムネイルの抽出ツール
MediaMetadataRetriever
クラスにある新しいメソッド getScaledFrameAtTime()
は、指定された時間位置付近のフレームを検出し、ソースフレームと同じアスペクト比のビットマップを返しますが、指定された幅と高さの長方形に収まるようにスケーリングされます。このメソッドは、動画からサムネイル画像を生成するのに便利です。
元の動画と同じ解像度のビットマップを返すため、メモリを浪費する可能性のある getFrameAtTime()
ではなく、この方法をおすすめします。たとえば、4K 動画のフレームは 16 MB のビットマップで、サムネイル画像に必要なサイズよりもはるかに大きくなります。
SharedMemory API
Android 8.1(API レベル 27)では、新しい SharedMemory
API が導入されています。このクラスを使用すると、匿名の SharedMemory
インスタンスを作成、マッピング、管理できます。読み取りと書き込みの SharedMemory
オブジェクトにメモリ保護を設定できます。また、SharedMemory
オブジェクトは Parcelable であるため、AIDL を介して別のプロセスに簡単に渡すことができます。
SharedMemory
API は、NDK の ASharedMemory
機能と相互運用します。ASharedMemory
は、読み取りと書き込みにマッピングできるファイル記述子へのアクセスを許可します。アプリ間や単一アプリ内の複数のプロセス間で大量のデータを共有する場合に適しています。
WallpaperColors API
Android 8.1(API レベル 27)では、ライブ壁紙からシステム UI に色情報を提供できます。そのためには、ビットマップやドローアブルから WallpaperColors
オブジェクトを作成するか、手動で選択した 3 つの色を使用します。この色の情報も取得できます。
WallpaperColors
オブジェクトを作成するには、次のいずれかを行います。
- 3 色を使用して
WallpaperColors
オブジェクトを作成するには、プライマリ カラー、セカンダリ カラー、ターシャリ カラーを渡して、WallpaperColors
クラスのインスタンスを作成します。プライマリ カラーを null にすることはできません。 - ビットマップから
WallpaperColors
オブジェクトを作成するには、ビットマップ ソースをパラメータとして渡してfromBitmap()
メソッドを呼び出します。 - ドローアブルから
WallpaperColors
オブジェクトを作成するには、ドローアブル ソースをパラメータとして渡してfromDrawable()
メソッドを呼び出します。
壁紙からプライマリ カラー、セカンダリ カラー、ターシャリ カラーの詳細を取得するには、次のメソッドを呼び出します。
getPrimaryColor()
は、壁紙の中で最も視覚的に表現できる色を返します。getSecondaryColor()
は、壁紙の中で 2 番目に目立つ色を返します。getTertiaryColor()
メソッドは、壁紙の中で 3 番目に目立つ色を返します。
ライブ壁紙の色の大幅な変化についてシステムに通知するには、notifyColorsChanged()
メソッドを呼び出します。このメソッドは、新しい WallpaperColors
オブジェクトを提供できる onComputeColors()
ライフサイクル イベントをトリガーします。
色の変化に対するリスナーを追加するには、addOnColorsChangedListener()
メソッドを呼び出します。また、getWallpaperColors()
メソッドを呼び出して、壁紙のメインカラーを取得することもできます。
フィンガープリントの更新
FingerprintManager
クラスに次のエラーコードが導入されました。
-
FINGERPRINT_ERROR_LOCKOUT_PERMANENT
– ユーザーが指紋認証リーダーを使用してデバイスのロック解除を何度も試行した。 -
FINGERPRINT_ERROR_VENDOR
- ベンダー固有の指紋リーダーエラーが発生しました。
暗号化の更新
Android 8.1 では、暗号化に関するさまざまな変更が行われています。
- 新しいアルゴリズムが Conscrypt に実装されました。Conscrypt 実装は、既存の Bouncy Castle 実装よりも優先的に使用されます。新しいアルゴリズムは次のとおりです。
AlgorithmParameters:GCM
KeyGenerator:AES
KeyGenerator:DESEDE
KeyGenerator:HMACMD5
KeyGenerator:HMACSHA1
KeyGenerator:HMACSHA224
KeyGenerator:HMACSHA256
KeyGenerator:HMACSHA384
KeyGenerator:HMACSHA512
SecretKeyFactory:DESEDE
Signature:NONEWITHECDSA
Cipher.getParameters().getParameterSpec(IvParameterSpec.class)
は、GCM を使用するアルゴリズムでは機能しなくなりました。代わりにgetParameterSpec(GCMParameterSpec.class)
を使用してください。- TLS に関連付けられている多くの Conscrypt 内部クラスがリファクタリングされました。デベロッパーがリフレクティブにアクセスする場合があるため、以前の使用をサポートするために shim が残されていますが、詳細の一部は変更されています。たとえば、以前は
OpenSSLSocketImpl
型でしたが、現在はConscryptFileDescriptorSocket
型またはConscryptEngineSocket
型になりました。どちらもOpenSSLSocketImpl
を拡張します。 - null 参照が渡されたときに
IllegalArgumentException
をスローするために使用されていたSSLSession
メソッドが、NullPointerException
をスローするようになりました。 - RSA
KeyFactory
では、エンコードされた鍵より大きいバイト配列から鍵を生成できなくなりました。鍵構造がバッファ全体を満たさないKeySpec
を提供するgeneratePrivate()
とgeneratePublic()
を呼び出すと、InvalidKeySpecException
になります。 - ソケットが閉じられることでソケットの読み取りが中断された場合、Conscrypt は読み取りから -1 を返すために使用されます。読み取りは
SocketException
をスローするようになりました。 - ルート CA 証明書のセットが変更されました。多くの古い証明書が削除されましたが、WoSign と StartCom のルート証明書も削除されました。この決定について詳しくは、Google セキュリティ ブログの WoSign 証明書と StartCom 証明書の信頼の最終削除をご覧ください。