1page.title= TV ハードウェアを処理する 2page.tags=tv 3trainingnavtop=true 4 5@jd:body 6 7<div id="tb-wrapper"> 8<div id="tb"> 9 <h2>学習の目的</h2> 10 <ol> 11 <li><a href="#runtime-check">TV 端末をチェックする</a> 12 <li><a href="#handle-features">サポートされていないハードウェア機能を処理する</a></li> 13 <li><a href="#controllers">ハードウェア コントローラを管理する</a> 14 </li> 15 </ol> 16</div> 17</div> 18 19<p> 20 TV のハードウェアは、他の Android 端末とは大きく異なります。TV には、タッチスクリーン、カメラ、GPS 受信機など、他の Android 端末でよく使われるハードウェア機能がありません。そして TV は、2 次ハードウェア端末に完全に依存しています。つまり、ユーザーはリモコンやゲーム機のコントローラで TV アプリを操作する必要があります。TV アプリをビルドする際は、ハードウェア上の制限や TV 向けハードウェアの操作要件を慎重に考慮する必要があります。 21</p> 22 23<p> 24 このレッスンでは、TV でアプリが正常に動作するかどうかチェックする方法や、サポートされていないハードウェア機能を処理する方法、そして TV 端末用のコントローラを処理するための要件について説明します。 25</p> 26 27 28<h2 id="runtime-check">TV 端末をチェックする</h2> 29 30<p> 31 TV 端末やその他の端末の両方で動作するアプリをビルドする場合、アプリが実行される端末の種類をチェックして、アプリの動作を調整する必要があります。たとえば、{@link android.content.Intent} を介して起動するアプリの場合、アクティビティをテレビ向けに起動するか、携帯電話向けに起動するかを判断するために、アプリ側で端末のプロパティをチェックする必要があります。 32</p> 33 34<p> 35 TV 端末でアプリが正常に動作するかどうかを判断するには、{@link android.app.UiModeManager#getCurrentModeType UiModeManager.getCurrentModeType()} メソッドを使用して、その端末がアプリの TV モードで正常に動作するかどうかをチェックすることをお勧めします。次のコード例では、TV 端末でアプリが正常に動作するかどうかチェックする方法を示します。 36</p> 37 38<pre> 39public static final String TAG = "DeviceTypeRuntimeCheck"; 40 41UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); 42if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) { 43 Log.d(TAG, "Running on a TV Device") 44} else { 45 Log.d(TAG, "Running on a non-TV Device") 46} 47</pre> 48 49 50<h2 id="handle-features">サポートされていないハードウェア機能を処理する</h2> 51 52<p> 53 アプリのデザインと機能によっては、特定のハードウェア機能を利用できないという事態を回避できる場合があります。このセクションでは、一般的に TV で使用できないハードウェア機能や、それらを検出する方法、そしてそれらの機能の代替案について説明します。 54</p> 55 56 57<h3 id="unsupported-features">サポートされていない TV ハードウェア機能</h3> 58 59<p> 60 TV には他の端末と異なる用途がありますので、他の Android 端末で提供されることの多いハードウェア機能がない場合があります。このため、Android システムは TV 端末では次の機能をサポートしていません。 61</p> 62 63<table> 64 <tr> 65 <th>ハードウェア</th> 66 <th>Android の Feature Descriptor</th> 67 </tr> 68 <tr> 69 <td>タッチスクリーン</td> 70 <td>{@code android.hardware.touchscreen}</td> 71 </tr> 72 <tr> 73 <td>電話</td> 74 <td>{@code android.hardware.telephony}</td> 75 </tr> 76 <tr> 77 <td>カメラ</td> 78 <td>{@code android.hardware.camera}</td> 79 </tr> 80 <tr> 81 <td>近距離無線通信(NFC)</td> 82 <td>{@code android.hardware.nfc}</td> 83 </tr> 84 <tr> 85 <td>GPS</td> 86 <td>{@code android.hardware.location.gps}</td> 87 </tr> 88 <tr> 89 <td>マイク</td> 90 <td>{@code android.hardware.microphone}</td> 91 </tr> 92</table> 93 94 95<h3 id="declare-hardware-requirements">TV のハードウェア要件を宣言する</h3> 96 97<p> 98 Android アプリでは、機能提供がない端末にインストールされてしまわないように、アプリのマニフェストでハードウェア機能の要件を宣言できます。TV 向けに既存のアプリを拡張している場合は、TV 端末へのインストールを阻害する可能性のあるハードウェア要件を宣言しているかどうかについて、アプリのマニフェストを詳細に見直す必要があります。 99</p> 100 101<p> 102 アプリでは TV で使用できないハードウェア機能(タッチスクリーンやカメラなど)を使用しているが、TV 向けにはそれらの機能がなくても構わない場合、アプリのマニフェストを編集して、それが不要な機能であることを示します。次のマニフェストのコード スニペットでは、TV 端末で使用できないハードウェア機能を(TV 以外の端末には提供する可能性がある場合でも)不要と宣言する方法を示します。 103</p> 104 105<pre> 106<uses-feature android:name="android.hardware.touchscreen" 107 android:required="false"/> 108<uses-feature android:name="android.hardware.telephony" 109 android:required="false"/> 110<uses-feature android:name="android.hardware.camera" 111 android:required="false"/> 112<uses-feature android:name="android.hardware.nfc" 113 android:required="false"/> 114<uses-feature android:name="android.hardware.gps" 115 android:required="false"/> 116<uses-feature android:name="android.hardware.microphone" 117 android:required="false"/> 118</pre> 119 120<p> 121 なお、TV 端末向けのすべてのアプリは、<a href="{@docRoot}training/tv/start/start.html#no-touchscreen">TV アプリのビルドを開始する</a>で説明したように、タッチスクリーン機能が不要であることを宣言する必要があります。アプリで上記の機能を 1 つ以上使用している場合は、マニフェストで該当する機能の {@code android:required} 属性の設定を {@code false} に変更します。 122</p> 123 124<p class="caution"> 125 <strong>警告:</strong>この値を {@code true} に設定してハードウェア機能を必要と宣言すると、TV 端末にインストールされず、Android 版 TV のホーム スクリーン ランチャーにもアプリが表示されなくなります。 126</p> 127 128<p> 129 アプリのハードウェア機能をオプションにする場合は、実行時にこれらの機能が利用できるかをチェックしてから、アプリの動作を調整する必要があります。次のセクションでは、ハードウェア機能をチェックする方法と、アプリの動作を変更するためのいくつかのアプローチについて説明します。 130</p> 131 132<p> 133 マニフェスト内でのフィルタリングと機能の宣言については、<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a>ガイドを参照してください。 134</p> 135 136 137<h3 id="hardware-permissions">ハードウェア機能を暗示するパーミッションを宣言する</h3> 138 139<p> 140 <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">{@code uses-permission}</a> のマニフェストにおける宣言には、<em>ハードウェア機能を暗示する</em>ものがあります。これは、アプリのマニフェストでいくつかのパーミッションを要求すると、アプリが TV 端末にインストールされず、使用されなくなることを意味します。次の一般によく要求されるパーミッションにより、暗黙的なハードウェア機能の要件が作成されます。 141</p> 142 143<table> 144 <tr> 145 <th>パーミッション</th> 146 <th>暗黙的なハードウェア機能</th> 147 </tr> 148 <tr> 149 <td>{@link android.Manifest.permission#RECORD_AUDIO}</td> 150 <td>{@code android.hardware.microphone}</td> 151 </tr> 152 <tr> 153 <td>{@link android.Manifest.permission#CAMERA}</td> 154 <td>{@code android.hardware.camera} <em>と</em> <br/> {@code android.hardware.camera.autofocus}</td> 155 </tr> 156 <tr> 157 <td>{@link android.Manifest.permission#ACCESS_COARSE_LOCATION}</td> 158 <td>{@code android.hardware.location} <em>と</em> <br/> {@code android.hardware.location.network}</td> 159 </tr> 160 <tr> 161 <td>{@link android.Manifest.permission#ACCESS_FINE_LOCATION}</td> 162 <td>{@code android.hardware.location} <em>と</em> <br/> {@code android.hardware.location.gps}</td> 163 </tr> 164</table> 165 166<p> 167 ハードウェア機能の要件を暗示するパーミッション要求を網羅したリストについては、<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#permissions-features">{@code uses-feature}</a>ガイドを参照してください。アプリが上記の機能のいずれかを要求する場合、暗示されたハードウェア機能についてマニフェストに <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code uses-feature}</a> 宣言を含めて、不要であることを示します({@code android:required="false"})。 168</p> 169 170 171<h3 id="check-features">ハードウェア機能をチェックする</h2> 172 173<p> 174 Android のフレームワークでは、アプリを実行している端末でハードウェア機能が使用できない場合を判別できます。{@link android.content.pm.PackageManager#hasSystemFeature(String)} メソッドを使用して、実行時に特定の機能をチェックできます。この場合、チェック対象の機能を指定する単一の文字列の引数を使用します。 175</p> 176 177<p>次のコード例では、アプリの実行時にハードウェア機能の利用可能性を検出する方法を示します。</p> 178 179<pre> 180// Check if the telephony hardware feature is available. 181if (getPackageManager().hasSystemFeature("android.hardware.telephony")) { 182 Log.d("HardwareFeatureTest", "Device can make phone calls"); 183} 184 185// Check if android.hardware.touchscreen feature is available. 186if (getPackageManager().hasSystemFeature("android.hardware.touchscreen")) { 187 Log.d("HardwareFeatureTest", "Device has a touch screen."); 188} 189</pre> 190 191 192<h4 id="no-touchscreen">タッチスクリーン</h4> 193 194<p> 195 TV には通常タッチスクリーンがないので、Android は TV 端末向けにはタッチスクリーン操作をサポートしていません。そもそも、タッチスクリーン操作は、ユーザーが 10 フィート離れた場所から視聴するという TV 特有の使用環境にそぐわないものです。 196</p> 197 198<p> 199 TV 端末ではリモコンの矢印ボタンによるナビゲーションをサポートして、TV 特有のインタラクション モデルに適したアプリをデザインする必要があります。TV 向けのコントロールを使用してナビゲーションを適切にサポートする方法については、<a href="{@docRoot}training/tv/start/navigation.html">TV 用のナビゲーションを作成する</a>を参照してください。 200</p> 201 202 203<h4 id="no-camera">カメラ</h4> 204 205<p> 206 TV にはカメラがないことが一般的ですが、カメラ関連アプリを提供することは可能です。たとえば、写真の撮影、表示、編集の機能があるアプリの場合、TV 向けに撮影機能を無効にながら、写真をの表示や編集は可能にすることができます。カメラ関連アプリをTV 向けにする場合、アプリのマニフェストには次の機能の宣言を追加します。 207</p> 208 209<pre> 210<uses-feature android:name="android.hardware.camera" android:required="false" /> 211</pre> 212 213<p> 214 カメラ機能を除いてアプリを動作させる場合、カメラ機能の存在を検出し、アプリの動作を調整するためのコードを追加します。次のコード例では、カメラ機能の存在を検出する方法を示します。 215</p> 216 217<pre> 218// Check if the camera hardware feature is available. 219if (getPackageManager().hasSystemFeature("android.hardware.camera")) { 220 Log.d("Camera test", "Camera available!"); 221} else { 222 Log.d("Camera test", "No camera available. View and edit features only."); 223} 224</pre> 225 226 227<h4 id="no-gps">GPS</h4> 228 229<p> 230 TV は据え付けタイプの室内用端末であり、全地球測位システム(GPS)の受信機を内蔵していません。アプリが位置情報を使用している場合、TV 端末のセットアップ時に郵便番号などの静的なロケーション プロバイダを構成して、ユーザーが位置を調べたり、それらを使用できるようにすることが可能です。 231</p> 232 233<pre> 234// Request a static location from the location manager 235LocationManager locationManager = (LocationManager) this.getSystemService( 236 Context.LOCATION_SERVICE); 237Location location = locationManager.getLastKnownLocation("static"); 238 239// Attempt to get postal or zip code from the static location object 240Geocoder geocoder = new Geocoder(this); 241Address address = null; 242try { 243 address = geocoder.getFromLocation(location.getLatitude(), 244 location.getLongitude(), 1).get(0); 245 Log.d("Zip code", address.getPostalCode()); 246 247} catch (IOException e) { 248 Log.e(TAG, "Geocoder error", e); 249} 250</pre> 251 252 253<h2 id="controllers">コントローラを処理する</h2> 254 255<p> 256 TV 端末ではベーシックなタイプのリモコン、ゲーム機のコントローラといった、アプリを操作するための2 次ハードウェア端末が必要となります。これは、アプリで矢印ボタンによる入力をサポートする必要がある、ということです。そして、コントローラのオフライン操作と複数のタイプのコントローラによる入力を処理することも必要です。 257</p> 258 259 260<h3 id="d-pad-minimum">矢印ボタンによる最小限のコントロール</h3> 261 262<p> 263 TV 端末のデフォルト コントローラはリモコン端末の矢印ボタンです。すなわち、上下、左右、[選択]、[戻る]、[ホーム] ボタンのみを使用して、アプリを操作できるようにする必要があります。ゲーム アプリの場合、通常は追加のコントロール機能のあるゲーム機のコントローラが必要ですが、TV ではリモコン端末の矢印ボタンでプレイできるようにする必要があります。この場合、コントローラが必要な旨をユーザーに警告した上で、リモコン端末の矢印ボタンでゲームを終了できるようにする必要があります。TV のリモコン端末の矢印ボタンによるナビゲーションを処理する方法については、<a href="{@docRoot}training/tv/start/navigation.html">TV 用のナビゲーションを作成する</a>を参照してください。 264</p> 265 266 267<h3 id="controller-disconnects">コントローラの接続の切断を処理する</h3> 268 269<p> 270 TV 用コントローラは Bluetooth 端末であることが多く、定期的にスリープ モードに入って TV との接続を切断し、消費電力を節約しようとする場合があります。この場合、アプリ側で再接続イベントの処理を構成していないと、アプリが中断したり再起動する可能性が生じます。これらのイベントは、次のいずれかの場合に発生する可能性があります。 271</p> 272 273<ul> 274 <li>ビデオ(数分程度)を見ている間にリモコン端末かゲーム機のコントローラがスリープ モードになり、TV 端末との接続が失われ、その後再び接続される場合。 275 </li> 276 <li>ゲームプレイ中に、新しいプレイヤーがオフライン状態のゲーム機のコントローラを使用してゲームに参加した場合。 277 </li> 278 <li>ゲームプレイ中に、プレイヤーがゲームを中断し、ゲーム機のントローラとの接続が失われた場合。 279 </li> 280</ul> 281 282<p> 283 接続の切断や再接続の対象となる TV アプリのアクティビティはすべて、アプリのマニフェストで再接続イベントを処理できるように構成する必要があります。次のコード サンプルでは、キーボードやナビゲーション端末の接続、切断、再接続などを含む構成の変更を処理するアクティビティの記述方法を示します。 284</p> 285 286<pre> 287<activity 288 android:name="com.example.android.TvActivity" 289 android:label="@string/app_name" 290 <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong> 291 android:theme="@style/Theme.Leanback"> 292 293 <intent-filter> 294 <action android:name="android.intent.action.MAIN" /> 295 <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> 296 </intent-filter> 297 ... 298</activity> 299</pre> 300 301<p> 302 この構成の変更により、Android のフレームワークによる再起動(ユーザー エクスペリエンスの観点から望ましくない)ではなく、再接続イベントを介してアプリの中断を回避することが可能です。 303</p> 304 305 306<h3 id="d-pad-variants">矢印ボタンによる入力のバリエーションを処理する</h3> 307 308<p> 309 TV 端末のユーザーは、複数のタイプのコントローラを使用して TV を操作する場合があります。たとえば、ベーシックなタイプのリモコンとゲーム機のコントローラを使用している場合があります。TV リモコンの矢印ボタンの機能をゲーム機のコントローラで実行する場合、送信されるキーコードはリモコン本体が送信するキーコードとは異なる場合があります。 310</p> 311 312<p> 313 ユーザーがアプリ操作のためにコントローラとリモコンを持ち替える必要がないよう、アプリでは、ゲーム機のコントローラからの矢印ボタンによる入力のバリエーションを処理する必要があります。入力のバリエーションの処理については、<a href="{@docRoot}training/game-controllers/controller-input.html#dpad">コントローラのアクションを処理する</a>を参照してください。 314</p> 315