diff --git a/docs/html/preview/preview_toc.cs b/docs/html/preview/preview_toc.cs index 377c487381cd7..162c3a90a6a2e 100644 --- a/docs/html/preview/preview_toc.cs +++ b/docs/html/preview/preview_toc.cs @@ -24,6 +24,42 @@
Information about the ADT-1 developer kit, including:
+ +To be included, but not listed on page:
+ + \ No newline at end of file diff --git a/docs/html/preview/tv/adt-1/request.jd b/docs/html/preview/tv/adt-1/request.jd new file mode 100644 index 0000000000000..dc13de099cfb2 --- /dev/null +++ b/docs/html/preview/tv/adt-1/request.jd @@ -0,0 +1,5 @@ +page.title=Request ADT-1 Developer Kit + +@jd:body + +Request form for the ADT-1 developer kit
\ No newline at end of file diff --git a/docs/html/preview/tv/games/index.jd b/docs/html/preview/tv/games/index.jd new file mode 100644 index 0000000000000..9471df0495dfd --- /dev/null +++ b/docs/html/preview/tv/games/index.jd @@ -0,0 +1,66 @@ +page.title=Games on TV +page.tags="controller" + +@jd:body + +This document complements the larger best-practice guidelines for [Design for TV](TODO, use formal name of referenced doc, and add link). It assumes that you have read those guidelines, and seeks to minimize repetition.
+Because of factors including its large size, its control scheme, and its nature as a shared display, the television screen presents a number of considerations that may be new to mobile developers. This document breaks these considerations down into five sections:
+A living-room TV presents design challenges for multiplayer games, in that all of the players can see everything. This issue is especially germane to games (such as card games or strategy games) that rely on each player’s possession of hidden information.
+Some mechanisms you can implement to address the problem of one player’s “eavesdropping” on another’s information are:
+A television does not have a touch interface. Your game design, therefore, need not take into account the possibility that a player’s controlling fingers might block the on-screen action. You can assume constant visibility of the entire viewing area.
+See the Control section in this document and in [Design for TV](TODO, use formal name of referenced doc, and add link) for more implications of the lack of touch interface.
+In mobile-device terms, a TV is always “sideways.” You can’t turn it, and there is no portrait orientation. You should always be designing your TV games to be displayed in landscape mode.
+Because of the lack of touch interface, you should be planning your control scheme based on a D-pad. Some key points to keep in mind include:
+The player needs to use the gamepad in all aspects of the game–not just controlling core gameplay, but also navigating menus and ads. For this reason, you should also ensure that your Android TV game does not refer to a touch interface: for example, an Android TV game cannot tell a player to "Tap to skip".
+You can avoid unhappy surprises (and resulting low ratings) by using your Play Store description to communicate to the player any expectations about controllers. If a game is better suited to a gamepad with a joystick than one with only a D-pad, you should make this clear. A player who uses an ill-suited controller for a game is likely to have a subpar experience–and penalize your game in the ratings.
+You can also help ensure a good player experience by ensuring that button mapping is intuitive and flexible. A widely accepted standard has the A button serving to Accept, and the B button serving to Cancel. You can also offer flexibility in the form of remappability. For more information on button mapping, Handling Controller Actions.
Your game can also contribute to a good match between controller and game by querying the controller about its capabilities. For example, you may intend for a player to steer an object by waving the controller in the air. If a player's controller lacks accelerometer and gyroscope hardware, however, waving will not work. But when your game queries the controller and discovers that motion detection is not supported, it can switch over to an alternative, available control scheme.
+For more information on querying controller capabilities, see Supporting Controllers Across Android Versions.
+The Back button should never act as a toggle. For example, do not use it to both open and close a menu. Its behavior should only be linear. For example: Game play > Game pause screen > Game main screen > Android home screen.
+With this principle of "linear navigation" in mind, the back button may leave an in-game menu (opened by a different button) to return to gameplay.
+When multiple players are playing a game, each with his or her own controller, it is important to map each player-controller pair. For information on how to implement controller-number identification, see Input Devices) on the Android developer site.
+When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog should appear prompting the disconnected player to reconnect his or her controller.
+The dialog should also offer troubleshooting tips (e.g., "Check your Bluetooth connection").
+Games are displayed in a separate row from regular apps in the launcher. Android TV uses the android:isGame flag to differentiate games from non-game apps. You can assign it a value of either true or false.
<application> + . . . + <meta-data android:name="isGame" android:value=["true" | "false"]/> +android:isGame=["true" | "false"] > + . . . +</application> +
If your game integrates Google Play Game Services, you should keep in mind a number of considerations pertaining to achievements, sign-on, saving games, and multiplayer play.
+Your game should include at least five (earnable) achievements. Only a user controlling gameplay from a supported input device should be able to earn achievements.
+Your game should attempt to sign the user in on launch. If the player declines sign-in several times in a row, your game should stop asking.
+We highly recommend using Play Services cloud save to store your game save. Your game should bind game saves to a specific Google account, so as to be uniquely identifiable, even across devices: Whether the player is using her phone or her tablet, the game should be able to pull the same game-save information from her account.
+You should also provide an option in your game's UI to prompt the player to destroy save data. You might put the option in the game's Settings screen.
A game offering a multiplayer experience must allow at least two players to enter a room.
+Android TV games do not support a full web browser. You should therefore avoid using generic URLs in your game.
+Webviews will work for logins to services like Google+ and Facebook.
diff --git a/docs/html/preview/tv/images/atv.png b/docs/html/preview/tv/images/atv.png new file mode 100644 index 0000000000000..cd96164ca3bb6 Binary files /dev/null and b/docs/html/preview/tv/images/atv.png differ diff --git a/docs/html/preview/tv/images/browsefragment.png b/docs/html/preview/tv/images/browsefragment.png new file mode 100644 index 0000000000000..8998b136853c3 Binary files /dev/null and b/docs/html/preview/tv/images/browsefragment.png differ diff --git a/docs/html/preview/tv/images/detailsfragment.png b/docs/html/preview/tv/images/detailsfragment.png new file mode 100644 index 0000000000000..014ab231151eb Binary files /dev/null and b/docs/html/preview/tv/images/detailsfragment.png differ diff --git a/docs/html/preview/tv/images/home-recommendations.png b/docs/html/preview/tv/images/home-recommendations.png new file mode 100644 index 0000000000000..2c188270a9385 Binary files /dev/null and b/docs/html/preview/tv/images/home-recommendations.png differ diff --git a/docs/html/preview/tv/index.jd b/docs/html/preview/tv/index.jd new file mode 100644 index 0000000000000..da4098569480d --- /dev/null +++ b/docs/html/preview/tv/index.jd @@ -0,0 +1,12 @@ +page.title=Android on TV + +@jd:body + +
+
+Android offers a rich user experience that's optimized for apps running on large screen + devices, such as high-definition televisions. Apps on TV offer new opportunities to + delight your users from the comfort of their couch.
+ +Get Started > + diff --git a/docs/html/training/tv/unsupported-features-tv.jd b/docs/html/preview/tv/start/hardware-features.jd similarity index 75% rename from docs/html/training/tv/unsupported-features-tv.jd rename to docs/html/preview/tv/start/hardware-features.jd index a9f090bfe1e23..3c1cd78238a7f 100644 --- a/docs/html/training/tv/unsupported-features-tv.jd +++ b/docs/html/preview/tv/start/hardware-features.jd @@ -1,22 +1,15 @@ -page.title=Handling Features Not Supported on TV -parent.title=Designing for TV -parent.link=index.html - -trainingnavtop=true -previous.title=Optimizing Navigation for TV -previous.link=optimizing-navigation-tv.html +page.title=Hardware Features on TV +page.tags="unsupported" @jd:body --Because TVs have a different purpose from other devices, they usually don't have hardware features -that other Android-powered devices often have. For this reason, the Android system does not +Because TVs have a different purpose from other devices, they usually don't have hardware features +that other Android-powered devices often have. For this reason, the Android system does not support the following features for a TV device:
| Attribute | +Function | +
|---|---|
| {@link android.R.attr#nextFocusDown} | +Defines the next view to receive focus when the user navigates down. | +
| {@link android.R.attr#nextFocusLeft} | +Defines the next view to receive focus when the user navigates left. | +
| {@link android.R.attr#nextFocusRight} | +Defines the next view to receive focus when the user navigates right. | +
| {@link android.R.attr#nextFocusUp} | +Defines the next view to receive focus when the user navigates up. | +
To use one of these explicit navigation attributes, set the value to the ID (android:id + value) of another widget in the layout. You should set up the navigation order as a loop, so that + the last control directs focus back to the first one.
+ ++ Note: You should only use these attributes to modify the navigation order if the + default order that the system applies does not work well. +
+ + +Use appropriate color highlights for all navigable and selectable elements in the UI. This makes + it easy for users to know whether the control is currently focused or selected when they navigate + with a D-pad. Also, use uniform highlight scheme across your application.
+ ++Android provides Drawable State List Resources to implement highlights +for selected and focused controls. For example: +
+ +res/drawable/button.xml: ++<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" + android:drawable="@drawable/button_pressed" /> <!-- pressed --> + <item android:state_focused="true" + android:drawable="@drawable/button_focused" /> <!-- focused --> + <item android:state_hovered="true" + android:drawable="@drawable/button_focused" /> <!-- hovered --> + <item android:drawable="@drawable/button_normal" /> <!-- default --> +</selector> ++ +
+This layout XML applies the above state list drawable to a {@link android.widget.Button}: +
++<Button + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/button" /> ++ +
Provide sufficient padding within the focusable and selectable controls so that the + highlights around them are clearly visible.
+ + +Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation + should be easy and intuitive to understand. For any non-intuitive actions, provide users with + written help, using a dialog triggered by a help button or action bar icon.
+ +Predict the next screen that the user will want to navigate to and provide one click + navigation to it. If the current screen UI is very sparse, consider making it a multi pane screen. + Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with + continent names on the left and list of cool places in each continent on the right.
+ +
+
+The above UI consists of three fragments - left_side_action_controls,
+ continents, and places - as shown in its layout xml file below.
+ Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen
+ space for TVs.
+
+<!-- res/layout/cool_places.xml --> + +<LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + > + <fragment + android:id="@+id/left_side_action_controls" + android:layout_width="0px" + android:layout_height="match_parent" + android:layout_marginLeft="10dip" + android:layout_weight="0.2"/> + <fragment + android:id="@+id/continents" + android:layout_width="0px" + android:layout_height="match_parent" + android:layout_marginLeft="10dip" + android:layout_weight="0.2"/> + + <fragment + android:id="@+id/places" + android:layout_width="0px" + android:layout_height="match_parent" + android:layout_marginLeft="10dip" + android:layout_weight="0.6"/> + +</LinearLayout> ++ +
Also, notice in the UI layout above action controls are on the left hand side of a vertically + scrolling list to make them easily accessible using D-pad. In general, for layouts with + horizontally scrolling components, place action controls on left or right hand side and vice versa + for vertically scrolling components.
+ diff --git a/docs/html/preview/tv/ui/recommendations.jd b/docs/html/preview/tv/ui/recommendations.jd new file mode 100644 index 0000000000000..52ac2e5ad8fef --- /dev/null +++ b/docs/html/preview/tv/ui/recommendations.jd @@ -0,0 +1,234 @@ +page.title=Making Recommendations +parent.title=User Interfaces for TV +parent.link=index.html + +trainingnavtop=true +previous.title=Searching in TV Apps +previous.link=in-app-search.html + +@jd:body + +Content recommendations appear as the first row of the TV launch screen after the first use + of the device. This row is intended to help users quickly find content they enjoy. Contributing + recommendations from your apps content catalog can help bring users back to your app.
+ + +
++ Figure 1. The first row after the search widget is the system-wide + recommendations. +
+ + +Content recommendations are created with background processing. In order for your application + to contribute to recommendations, you create a service that periodically adds listings from your + app's catalog to the system list of recommendations.
+ +The following code example illustrates how to extend the {@link android.app.IntentService} to + create a recommendation service for your application.
+ +
+public class RecommendationsService extends IntentService {
+
+ ...
+
+ public Notification buildRecommendation(Context context, Movie movie)
+ throws IOException {
+
+ if (mNotificationManager == null) {
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+
+ Bundle extras = new Bundle();
+ if (mBackgroundUri != movie.getBackgroundUri()) {
+ extras.putString(EXTRA_BACKGROUND_IMAGE_URL, movie.getBackgroundUri());
+ }
+
+ // build the recommendation as a Notification object
+ Notification notification = new NotificationCompat.BigPictureStyle(
+ new NotificationCompat.Builder(context)
+ .setContentTitle(movie.getTitle())
+ .setContentText(movie.getDescription())
+ .setPriority(movie.getPriority())
+ .setOngoing(true)
+ .setCategory("recommendation")
+ .setLargeIcon(movie.getImage())
+ .setSmallIcon(movie.getSmallIcon())
+ .setContentIntent(buildPendingIntent(movie.getId()))
+ .setExtras(extras))
+ .build();
+
+ // post the recommendation to the NotificationManager
+ mNotificationManager.notify(movie.getId(), notification);
+ mNotificationManager = null;
+ return notification;
+ }
+
+ private PendingIntent buildPendingIntent(long id) {
+ Intent detailsIntent = new Intent(this, DetailsActivity.class);
+ detailsIntent.putExtra("id", id);
+
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+ stackBuilder.addParentStack(DetailsActivity.class);
+ stackBuilder.addNextIntent(detailsIntent);
+ // Ensure each PendingIntent is unique
+ detailsIntent.setAction(Long.toString(id));
+
+ PendingIntent intent = stackBuilder.getPendingIntent(
+ 0, PendingIntent.FLAG_UPDATE_CURRENT);
+ return intent;
+ }
+}
+
+
+In order for this class to be recognized and run as a service, you must register this service + using your app manifest. The following code snippet illustrates how to add this class as a + service:
+ ++<manifest ... > + <application ... > + ... + + <service android:name=".UpdateRecommendationsService" + android:enabled="true" android:exported="true"/> + </application> +</manifest> ++ +
Once it starts running, your service must create recommendations and pass them to the Android + framework. The framework receives the recommendations as {@link android.app.Notification} objects + that use a specific style and are marked with a specific category.
+ +The following code example demonstrates how to get an instance of the {@link + android.app.NotificationManager}, build a recommendation and post it to the manager:
+ +
+public class RecommendationsService extends IntentService {
+
+ ...
+
+ public Notification buildRecommendation(Context context, Movie movie)
+ throws IOException {
+
+ if (mNotificationManager == null) {
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+
+ Bundle extras = new Bundle();
+ if (mBackgroundUri != movie.getBackgroundUri()) {
+ extras.putString(EXTRA_BACKGROUND_IMAGE_URL, movie.getBackgroundUri());
+ }
+
+ // build the recommendation as a Notification object
+ Notification notification = new NotificationCompat.BigPictureStyle(
+ new NotificationCompat.Builder(context)
+ .setContentTitle(movie.getTitle())
+ .setContentText(movie.getDescription())
+ .setPriority(movie.getPriority())
+ .setOngoing(true)
+ .setCategory("recommendation")
+ .setLargeIcon(movie.getImage())
+ .setSmallIcon(movie.getSmallIcon())
+ .setContentIntent(buildPendingIntent(movie.getId()))
+ .setExtras(extras))
+ .build();
+
+ // post the recommendation to the NotificationManager
+ mNotificationManager.notify(movie.getId(), notification);
+ mNotificationManager = null;
+ return notification;
+ }
+
+ private PendingIntent buildPendingIntent(long id) {
+ Intent detailsIntent = new Intent(this, DetailsActivity.class);
+ detailsIntent.putExtra("id", id);
+
+ TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+ stackBuilder.addParentStack(DetailsActivity.class);
+ stackBuilder.addNextIntent(detailsIntent);
+ // Ensure each PendingIntent is unique
+ detailsIntent.setAction(Long.toString(id));
+
+ PendingIntent intent = stackBuilder.getPendingIntent(
+ 0, PendingIntent.FLAG_UPDATE_CURRENT);
+ return intent;
+ }
+}
+
+
+
+Your app's recommendation service must run periodically in order to create current + recommendations. In order to run your service, you should create a class that runs a timer and + invokes it at regular intervals. The following code example extends the {@link + android.content.BroadcastReceiver} class to start periodic execution of a recommendation service + every 30 minutes:
+ +
+public class BootupActivity extends BroadcastReceiver {
+ private static final String TAG = "BootupActivity";
+
+ private static final long INITIAL_DELAY = 5000;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().endsWith(Intent.ACTION_BOOT_COMPLETED)) {
+ scheduleRecommendationUpdate(context);
+ }
+ }
+
+ private void scheduleRecommendationUpdate(Context context) {
+ AlarmManager alarmManager = (AlarmManager)context.getSystemService(
+ Context.ALARM_SERVICE);
+ Intent recommendationIntent = new Intent(context,
+ UpdateRecommendationsService.class);
+ PendingIntent alarmIntent = PendingIntent.getService(context, 0,
+ recommendationIntent, 0);
+
+ alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ INITIAL_DELAY,
+ AlarmManager.INTERVAL_HALF_HOUR,
+ alarmIntent);
+ }
+}
+
+
+In order for the {@link android.content.BroadcastReceiver} class to execute after an TV + device starts up, you must register this class in your app manifest and attach an intent filter + for the completion of the device boot process. This sample code demonstrates how to add this + configuration to the manifest:
+ ++<manifest ... > + <application ... > + <receiver android:name=".BootupActivity" android:enabled="true" + android:exported="false"> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED"/> + </intent-filter> + </receiver> + </application> +</manifest> +diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd deleted file mode 100644 index 54f7016a8b29b..0000000000000 --- a/docs/html/training/tv/index.jd +++ /dev/null @@ -1,59 +0,0 @@ -page.title=Designing for TV -page.tags="input","screens" - -trainingnavtop=true -startpage=true - -@jd:body - -
DevBytes: Design for Large Displays - Part 1
-- Smart TVs powered by Android bring your favorite Android apps to the best screen in your house. - Thousands of apps in the Google Play Store are already optimized for TVs. This class shows how - you can optimize your Android app for TVs, including how to build a layout that - works great when the user is ten feet away and navigating with a remote control. -
- --An important aspect of the user experience when operating a TV is the direct human interface: a remote control. -As you optimize your Android application for TVs, you should pay special attention to how the user actually navigates -around your application when using a remote control instead of a touchscreen. -
--This lesson shows you how to optimize navigation for TV by: -
- --On a TV, users navigate with controls on a TV remote, using either a D-pad or arrow keys. -This limits movement to up, down, left, and right. -To build a great TV-optimized app, you must provide a navigation scheme in which the user can -quickly learn how to navigate your app using the remote. -
- --When you design navigation for D-pad, follow these guidelines: -
- --Android usually handles navigation order between layout elements automatically, so you don't need to do anything extra. If the screen layout -makes navigation difficult, or if you want users to move through the layout in a specific way, you can set up explicit navigation for your -controls. -For example, for an {@code android.widget.EditText}, to define the next control to receive focus, use: -
-<EditText android:id="@+id/LastNameField" android:nextFocusDown="@+id/FirstNameField"\> --The following table lists all of the available navigation attributes: - - -
| Attribute | -Function | -
|---|---|
| {@link android.R.attr#nextFocusDown} | -Defines the next view to receive focus when the user navigates down. | -
| {@link android.R.attr#nextFocusLeft} | -Defines the next view to receive focus when the user navigates left. | -
| {@link android.R.attr#nextFocusRight} | -Defines the next view to receive focus when the user navigates right. | -
| {@link android.R.attr#nextFocusUp} | -Defines the next view to receive focus when the user navigates up. | -
-To use one of these explicit navigation attributes, set the value to the ID (android:id value) of another widget in the layout. You should set -up the navigation order as a loop, so that the last control directs focus back to the first one. -
- --Note: You should only use these attributes to modify the navigation order if the default order that the system applies does not work well. -
- --Use appropriate color highlights for all navigable and selectable elements in the UI. This makes it easy for users to know whether the control -is currently focused or selected when they navigate with a D-pad. Also, use uniform highlight scheme across your application. -
- --Android provides Drawable State List Resources to implement highlights -for selected and focused controls. For example: -
- -res/drawable/button.xml: --<?xml version="1.0" encoding="utf-8"?> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" - android:drawable="@drawable/button_pressed" /> <!-- pressed --> - <item android:state_focused="true" - android:drawable="@drawable/button_focused" /> <!-- focused --> - <item android:state_hovered="true" - android:drawable="@drawable/button_focused" /> <!-- hovered --> - <item android:drawable="@drawable/button_normal" /> <!-- default --> -</selector> -- -
-This layout XML applies the above state list drawable to a {@link android.widget.Button}: -
--<Button - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:background="@drawable/button" /> -- -
-Provide sufficient padding within the focusable and selectable controls so that the highlights around them are clearly visible. -
- --Users should be able to navigate to any UI control with a couple of D-pad clicks. Navigation should be easy and intuitive to -understand. For any non-intuitive actions, provide users with written help, using a dialog triggered by a help button or action bar icon. -
- --Predict the next screen that the user will want to navigate to and provide one click navigation to it. If the current screen UI is very sparse, -consider making it a multi pane screen. Use fragments for making multi-pane screens. For example, consider the multi-pane UI below with continent names -on the left and list of cool places in each continent on the right. -
- -
-
-
-The above UI consists of three Fragments - left_side_action_controls, continents and
-places - as shown in its layout
-xml file below. Such multi-pane UIs make D-pad navigation easier and make good use of the horizontal screen space for
-TVs.
-
-<LinearLayout - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal" - > - <fragment - android:id="@+id/left_side_action_controls" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_marginLeft="10dip" - android:layout_weight="0.2"/> - <fragment - android:id="@+id/continents" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_marginLeft="10dip" - android:layout_weight="0.2"/> - - <fragment - android:id="@+id/places" - android:layout_width="0px" - android:layout_height="match_parent" - android:layout_marginLeft="10dip" - android:layout_weight="0.6"/> - -</LinearLayout> -- -
-Also, notice in the UI layout above action controls are on the left hand side of a vertically scrolling list to make -them easily accessible using D-pad. -In general, for layouts with horizontally scrolling components, place action controls on left or right hand side and -vice versa for vertically scrolling components. -
-