1page.title=TV Recording
2page.keywords=preview,sdk,tv,recording
3page.tags=androidn
4page.image=images/cards/card-nyc_2x.jpg
5
6@jd:body
7
8<div id="qv-wrapper">
9<div id="qv">
10  <h2>In this document</h2>
11  <ol>
12    <li><a href="#supporting">Indicating Support for Recording</a></li>
13    <li><a href="#recording">Recording a Session</a></li>
14    <li><a href="#errors">Handling Recording Errors</a></li>
15    <li><a href="#sessions">Managing Recorded Sessions</a></li>
16    <li><a href="#best">Best Practices</a></li>
17  </ol>
18</div>
19</div>
20
21<p>TV input services let the user pause and resume channel playback via
22time-shifting APIs. Android N expands on time-shifting
23by letting the user save multiple recorded sessions.</p>
24
25<p>Users can schedule recordings in advance, or start a recording as they watch
26a program. Once the system has saved a recording, the user can browse, manage,
27and play back the recording using the system TV app.</p>
28
29<p>If you want to provide recording functionality for your TV input service,
30you must indicate to the system that your app supports recording, implement
31the ability to record programs, handle and communicate any errors that occur
32during recording, and manage your recorded sessions.</p>
33
34<p class="note"><strong>Note:</strong> The Live Channels app does not yet
35provide a way for users to create or access recordings. Until changes are
36made to the Live Channels app, it may be difficult to fully test the recording
37experience for your TV input service.</p>
38
39<h2 id="supporting">Indicating Support for Recording</h2>
40
41<p>To tell the system that your TV input service supports recording, set
42the <code>android:canRecord</code> attribute in your service metadata XML file
43to <code>true</code>:
44</p>
45
46<pre>
47&lt;tv-input xmlns:android="http://schemas.android.com/apk/res/android"
48  <b>android:canRecord="true"</b>
49  android:setupActivity="com.example.sampletvinput.SampleTvInputSetupActivity" /&gt;
50</pre>
51
52<p>For more information on the service metadata file, see
53<a href="{@docRoot}training/tv/tif/tvinput.html#manifest">Declare Your TV Input
54Service in the Manifest</a>.
55</p>
56
57<p>Alternatively, you can indicate recording support in your code using
58these steps:</p>
59
60<ol>
61<li>In your <code>TvInputService.onCreate()</code> method, create a new
62<code>TvInputInfo</code> object using the <code>TvInputInfo.Builder</code>
63class.</li>
64<li>When creating the new <code>TvInputInfo</code> object, call
65<code>setCanRecord(true)</code> before calling <code>build()</code> to
66indicate your service supports recording.</li>
67<li>Register your <code>TvInputInfo</code> object with the system by calling
68<code>TvInputManager.updateTvInputInfo()</code>.</li>
69</ol>
70
71<h2 id="recording">Recording a Session</h2>
72
73<p>After your TV input service registers that it supports recording
74functionality, the system calls your
75<code>TvInputService.onCreateRecordingSession()</code> when it needs to access
76your app's recording implementation. Implement your own
77<code>TvInputService.RecordingSession</code> subclass and return it
78when the <code>onCreateRecordingSession()</code> callback
79fires. This subclass is responsible for switching to the correct channel data,
80recording the requested data, and communicating recording status and errors to
81the system.</p>
82
83<p>When the system calls <code>RecordingSession.onTune()</code>, passing in a
84channel URI, tune to the channel that the URI specifies. Notify the system that
85your app has tuned to the desired channel by calling <code>notifyTuned()</code>,
86or, if your app could not tune to the proper channel, call
87<code>notifyError()</code>.</p>
88
89<p>The system next invokes the <code>RecordingSession.onStartRecording()</code>
90callback. Your app must start recording immediately. When the system invokes
91this callback, it may provide a URI that contains information about the program
92that is about to be recorded. When the recording is done, you need to copy this
93data to the <code>RecordedPrograms</code> data table.</p>
94
95<p>Finally, the system calls <code>RecordingSession.onStopRecording()</code>.
96At this point, your app must stop recording immediately. You also need to
97create an entry in the <code>RecordedPrograms</code> table. This entry should
98include the recorded session data URI in the
99<code>RecordedPrograms.COLUMN_RECORDING_DATA_URI</code> column, and any program
100information that the system provided in the initial call to
101<code>onStartRecording()</code>.</p>
102
103<p>For more details on how to access the <code>RecordedPrograms</code> table
104see <a href="#sessions">Managing Recorded Sessions</a>.</p>
105
106<h2 id="errors">Handling Recording Errors</h2>
107
108<p>If an error occurs during recording, rendering the recorded data unusable,
109notify the system by calling <code>RecordingSession.notifyError()</code>.
110Similarly, you can call <code>notifyError()</code> after a recording session is
111created to let the system know that your app can no longer record sessions.</p>
112
113<p>If an error occurs during recording, but you'd like to provide a usable
114partial recording to users for playback, call
115<code>RecordingSession.notifyRecordingStopped()</code> to enable the system to
116use the partial session.</p>
117
118<h2 id="sessions">Managing Recorded Sessions</h2>
119
120<p>The system maintains information for all recorded sessions from all
121recording-capable channel apps in the <code>TvContract.RecordedPrograms</code>
122content provider table. This information is accessible via the
123<code>RecordedPrograms.Uri</code> content URI. Use content provider APIs to
124read, add, and delete entries from this table.</p>
125
126<p>For more information on working with content provider data see
127<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
128Content Provider Basics</a> .</p>
129
130<h2 id="best">Best Practices</h2>
131
132<p>TV devices may have limited storage, so use your best judgment when
133allocating storage to save recorded sessions. Use
134<code>RecordingCallback.onError(RECORDING_ERROR_INSUFFICIENT_SPACE)</code> when
135there isn't enough space to save a recorded session.</p>
136
137<p>When the user initiates recording, you should start recording data as soon
138as possible. To facilitate this, complete any up-front time-consuming tasks,
139like accessing and allocating storage space, when the system invokes the
140<code>onCreateRecordingSession()</code> callback. Doing so lets you start
141recording immediately when the <code>onStartRecording()</code> callback
142fires.</p>
143