Android 8.1(API レベル 27)では、ユーザーとデベロッパー向けのさまざまな新機能が導入されています。このドキュメントでは、デベロッパー向けの新機能について説明します。
Android Oreo(Go バージョン)
Android Go は、世界中でインターネットを利用する何十億人もの人々のために Android のエクスペリエンスを最適化するための Google の取り組みです。Android 8.1 以降、Google は Android をエントリレベルのデバイスに最適なプラットフォームにしています。Android Oreo(Go バージョン)構成の機能は次のとおりです。
- メモリの最適化。プラットフォーム全体のメモリ使用量が改善され、1 GB 以下の RAM を搭載したデバイスでアプリが効率的に実行されるようにしました。
- 柔軟なターゲティング オプション。新しいハードウェア機能定数を使用することで、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 セキュリティ ブログの投稿「Final removal of trust in WoSign and StartCom Certificates」をご覧ください。