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&lt;uses-feature android:name="android.hardware.touchscreen"
107        android:required="false"/&gt;
108&lt;uses-feature android:name="android.hardware.telephony"
109        android:required="false"/&gt;
110&lt;uses-feature android:name="android.hardware.camera"
111        android:required="false"/&gt;
112&lt;uses-feature android:name="android.hardware.nfc"
113        android:required="false"/&gt;
114&lt;uses-feature android:name="android.hardware.gps"
115        android:required="false"/&gt;
116&lt;uses-feature android:name="android.hardware.microphone"
117        android:required="false"/&gt;
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&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
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&lt;activity
288  android:name="com.example.android.TvActivity"
289  android:label="&#64;string/app_name"
290  <strong>android:configChanges="keyboard|keyboardHidden|navigation"</strong>
291  android:theme="&#64;style/Theme.Leanback"&gt;
292
293  &lt;intent-filter&gt;
294    &lt;action android:name="android.intent.action.MAIN" /&gt;
295    &lt;category android:name="android.intent.category.LEANBACK_LAUNCHER" /&gt;
296  &lt;/intent-filter&gt;
297  ...
298&lt;/activity&gt;
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