sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

残りの小ネタ (Android 4.3 API)

前回へ戻る

ここからは小ネタがポロポロ続きます。

Notification Listener

Android 4.3 では NotificationListenerServiceが追加された。これを使うと、システムによって送信された新着のnotivicationに関する情報を受け取ることができるようになる。

現在、accessibility service APIを使ってSystem notificationにアクセスしているのなら、この新しいAPIを使用するように更新するべきである。

 

Contacts Provider

Query for "contactables"

新しいContacts Providerのqueryである Contactables.CONTENT_URIは、指定されたクエリに一致する全ての連絡先に所属する、全てのメールアドレスと電話番号を含んだCursorを取得するための効率的な方法を提供する。

Query for contacts deltas

Contacts Providerに追加された新しいAPIで、連絡先の最近の更新を効率的に問い合わせることができる。

これまでも、連絡先の何かが変わったときにはアプリに通知が来ていたが、何が変化したのかを正確に知る事ができず、変更を見つけるために、全ての連絡先データを取得して調べる必要があった。

insertとupdateによる変更を追跡するために、前回の問い合わせ以降に変更された連絡先だけを取り出すために、CONTACT_LAST_UPDATED_TIMESTAMPパラメータをクエリに含めることができるようになった。

deleteされた連絡先を追跡するために、ContactsContract.DeletedContactsテーブルが削除された連絡先のログを提供する。(ただし、削除された連絡先は限られた回数しかこのテーブルには保持されない)
CONTACT_LAST_UPDATED_TIMESTAMPに同様に、前回の問い合わせ以降に削除された連作先をチェックするために、CONTACT_DELETED_TIMESTAMPパラメータを使う事ができる。

このテーブルは、DAYS_KEPT_MILLISECONDSの定数でログが保存される日数をミリ秒で含んでいる。

さらに、Contacts Providerは、ユーザーがシステム設定メニューで連絡先をクリアした時に、効果的にContactsProvierデータベースを再構築するためにCONTACTS_DATABASE_CREATEDアクションをBroadcastする。

全ての連絡先情報を再起し、新しい問い合わせで保持しなおすためのサインとしてのIntentである。

連絡先の変更をチェックするためのこれらのAPIを使ったサンプルは、ApiDemosに含まれている。

 

Localization

Improved support for bi-directional text

アンドロイドの以前のバージョンで、右から左の(RTL)言語とレイアウトをサポートしている。 しかし、たまに混ざったテキストを正しく処理できないことがあるため、Android 4.3ではBidiFormatter APIを追加し、文字化けすることなしに反対方向のテキストコンテンツを扱えるようにした。

例えば"Did you mean 15 Bay Street, Laurel, CA?"という文字列の文章を作りたいとき、普通はString.format()に文字列リソースを渡せばよい。

Resources res = getResources();
String suggestion = String.format(res.getString(R.string.did_you_mean), address);

しかし、もしロケールがヘブライなら、右から左の文字列になる。ただ、アドレスの部分正しくないフォーマットになるため、 BidiFormatterとそのunicodeWrap()メソッドを使う。

Resources res = getResources();
BidiFormatter bidiFormatter = BidiFormatter.getInstance();
String suggestion = String.format(res.getString(R.string.did_you_mean), bidiFormatter.unicodeWrap(address));

デフォルトではunicodeWrap()は最初の方向にそった推定をしようとするが、間違っていたり、文章全体の方向ではないこともあるため、必要なら unicodeWrap()に別のTextDirectionHeuristicを渡す事も可能である。

  • BidiFormatterや関連する新しいAPIは、Android Support Libraryを通して、古いバージョンのAndroidでも利用が可能となっている。
 

Accessibility Services

Handle key events

AccessibilityServiceは、onKeyEvent() メソッドによって、Key入力イベントを受け取ることができるようになった。これは、キーボードのようなキー入力ベースの装置からのイベントによって、以前はタッチや方向パッドで行っていた特別なアクションを処理できるようになることを意味する。

Select text and copy/paste

AccessibilityNodeInfoは、AccessibilityServiceに対して、テキストの選択や、カット、コピー、ペーストを行うためのAPIを提供している。

カットやコピーで文字列を選択するためのACTION_SET_SELECTIONや、選択の開始と終了の位置を示すためのACTION_ARGUMENT_SELECTION_START_INTとACTION_ARGUMENT_SELECTION_END_INTがある。

別の方法としては、既存のアクションのACTION_NEXT_AT_MOVEMENT_GRANULARITYでカーソルを移動し、ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN で選択を行う。

カットやコピー、ペーストには、ACTION_CUT, ACTION_COPY, ACTION_PASTEを使う。

  • これらのAPIは、AccessibilityNodeInfoCompatとして、Android Support Libraryでも提供されているため、以前のバージョンのAndroidでも利用が可能である。

Declare accessibility features

アンドロイド4.3以降では、特定のアクセシビリティ機能を使用するためには、メタデータファイルに宣言を行って機能の要求を行う必要があり、要求しないとその機能は使用できない。

宣言を行うには、AccessibilityServiceInfoクラスの定数に対応するものをxmlで使用する必要がある。

例えば、flagRequestFilterKeyEventsを要求しないと、キーイベントを受け取る事ができない。

 

Testing and Debugging

Automated UI testing

UiAutomationクラスは、自動テストのためにユーザーのアクションを発生させるAPIを提供する。プラットフォームのAccessibilityService APIのUiAutomation APIを使用すると、画面の内容を検査し、任意のキー入力やタッチイベントを発生させることができる。

UiAutomationのインスタンスを取得するには、Instrumentation.getUiAutomation()を呼び出す。adbのシェルからInstrumentationTestCaseを実行する際には、コマンドに-wオプションを指定する必要がある。

UiAutomationのインスタンスを使用して、あなたはそれを実行するRunnableをを渡し、呼び出しexecuteAndWaitForEvent()によってあなたのアプリケーションをテストするために、任意のイベントを実行することができ、操作、およびUiAutomation.AccessibilityEventFilterインタフェースの実装のためのタイムアウト時間。それはあなたがあなたに興味を持っていることをイベントをフィルタリングし、与えられたテストケースの成否を決定することができ、コールを受けるだろうというあなたのUiAutomation.AccessibilityEventFilter実装内です。

UiAutomationのインスタンスを使用して、executeAndWaitForEvent()を呼んでアプリをテストするために任意のイベントを実行できる。また、UiAutomation.AccessibilityEventFilterインターフェースを実装して、アクセス可能なイベントをフィルタリングできる。

テスト中のすべてのイベントを観察するには、UiAutomation.OnAccessibilityEventListenerを実装し、setOnAccessibilityEventListener()に渡す。イベントが発生するたびにonAccessibilityEvent()が呼び出される。

UiAutomation APIは、ローレベルのUIテスト等を手助けするために、たくさんの手段を提供している。

例えば、UiAutomationでは以下が可能

そして、最も重要なのは、アプリケーションの境界を越えて動作するということ。

Systrace events for apps

Android 4.3は、Traceクラスで2つのstaticメソッドを提供している。 beginSection()とendSection()は、systraceレポートに含まれるブロックを定義できる。

トレース可能なコードのセクションを作成し、ログを確認する事で、速度低下の原因となる箇所等のより細かな分析が可能となる。

Systraceツールの使い方は、Analyzing Display and Performance with Systraceを参照のこと。

 

Security

Android key store for app-private keys

Androidは、Android Key Storeと呼ばれるKeyStoreを提供している。これを利用して、そのアプリだけで利用可能な秘密鍵を生成・保持することができる。

Android Key Storeをロードするために、KeyStore.getInstance("AndroidKeyStore")を呼ぶ。

Android Key Storeでプライベート証明書を管理するには、KeyPairGeneratorSpecとKeyPairGeneratorで新しいキーを生成する。

KeyPairGenerator.getInstance()でインスタンスを取得し、initialize()でKeyPairGeneratorSpecを渡す。最後にgenerateKeyPair()でKeyPariを取得する。

Javaで鍵の生成や管理をやったことがあればなんてことはない操作かも。おれおれ証明書をプログラム内で生成する時などに便利ですね。

Hardware credential storage

Androidは、hardware-backed(ハードウェアに紐づいた?)ストレージをサポートし、展開のためのキーを無効にすることでKeyChainや証明書のセキュリティを高める。

キーはhadrware-backed key store内に保持され、暗号に関する処理での利用は可能だが、外部にexportされることはなく、OS kernelからもKeyにアクセスはできない。

全てのAndroid端末がハードウェア上のストレージをサポートしているわけではないため、 hardware-backed storageを利用する場合は、KeyChain.IsBoundKeyAlgorithm()でチェックを行う必要がある。

 

Manifest Declarations

Declarable required features

<uses-feature>に以下の値が追加された。

FEATURE_APP_WIDGETS

アプリがAppWidgetを提供し、ホームスクリーンか同様の場所に app widgetsを配置可能なデバイスにのみインストールされるべきことを示す

<uses-feature android:name="android.software.app_widgets" android:required="true" />
FEATURE_HOME_SCREEN

アプリがホーム画面の代替として動くことを示し、サードパーティ製のホームスクリーンアプリを許可するデバイスにのみインストールされるべきであることを示す

<uses-feature android:name="android.software.home_screen" android:required="true" />
FEATURE_INPUT_METHODS

アプリがカスタム入力メソッド(InputMethodServiceで構築されたキーボード)を提供し、サードパーティ製の入力方法を許可するデバイスにのみインストールされるべきであることを示す

<uses-feature android:name="android.software.input_methods" android:required="true"/>
FEATURE_BLUETOOTH_LE

アプリがBluetooth Low Energy APIを使用しており、BLEで他のデバイスと通信が可能なデバイスにのみインストールされるべきであることを示す

<uses-feature android:name="android.software.bluetooth_le" android:required="true" />

User permissions

<uses-permission>に定義するパーミッション

BIND_NOTIFICATION_LISTENER_SERVICE

NotificationListenerService APIを使用するパーミッション

SEND_RESPOND_VIA_MESSAGE

ACTION_RESPOND_VIA_MESSAGEのインテントを受け取るパーミッション

 

4.3でのAPIの変更点の詳細は、API Differences Reportを参照。

 


というわけでなんとか終了。日本語の5割増しくらいで読めるまで訓練しないと時間がもったいなさすぎです…しかし今回の機能追加は思ったより微妙だったかも? やはり5でガラっと変わるんでしょうか?