Dịch vụ đầu vào TV đại diện cho một nguồn luồng nội dung nghe nhìn và cho phép bạn trình bày nội dung nghe nhìn của mình trong một kiểu truyền hình truyền thống, phát sóng dưới dạng kênh và chương trình. Với dịch vụ đầu vào TV, bạn có thể cung cấp chế độ kiểm soát của cha mẹ, thông tin hướng dẫn chương trình và mức phân loại nội dung. Dịch vụ đầu vào TV hoạt động bằng ứng dụng Android trên TV. Ứng dụng này rốt cuộc sẽ kiểm soát và trình bày nội dung của kênh trên TV. Ứng dụng TV hệ thống được phát triển riêng cho thiết bị và không thể thay đổi theo các ứng dụng bên thứ ba. Để biết thêm thông tin về Khung đầu vào TV (TIF) cấu trúc và các thành phần của nó, xem Khung đầu vào TV.
Tạo dịch vụ đầu vào TV bằng Thư viện đồng hành TIF
Thư viện đồng hành TIF là một khung cung cấp khả năng mở rộng triển khai các tính năng phổ biến của dịch vụ đầu vào TV. API này dành cho nhà sản xuất thiết bị gốc (OEM) để tạo chỉ dành cho Android 5.0 (API cấp 21) đến Android 7.1 (API cấp 25).
Cập nhật dự án
Thư viện đồng hành TIF có sẵn để nhà sản xuất thiết bị gốc (OEM) sử dụng trong androidtv-sample-inputs kho lưu trữ. Hãy xem kho lưu trữ đó để biết ví dụ về cách đưa thư viện vào ứng dụng.
Khai báo dịch vụ đầu vào TV trong tệp kê khai
Ứng dụng của bạn phải cung cấp phiên bản tương thích với TvInputService
mà hệ thống dùng để truy cập vào ứng dụng của bạn. TIF
Thư viện đồng hành cung cấp lớp BaseTvInputService
cung cấp phương thức triển khai mặc định của TvInputService
mà bạn có thể tuỳ chỉnh. Tạo một lớp con của BaseTvInputService
,
và khai báo lớp con trong tệp kê khai dưới dạng dịch vụ.
Trong phần khai báo tệp kê khai, hãy chỉ định
BIND_TV_INPUT
để cho phép
để kết nối đầu vào TV với hệ thống. Dịch vụ hệ thống
thực hiện liên kết và có
Quyền BIND_TV_INPUT
.
Ứng dụng TV của hệ thống gửi yêu cầu đến dịch vụ đầu vào TV
thông qua giao diện TvInputManager
.
Trong phần khai báo dịch vụ, hãy thêm một bộ lọc ý định chỉ định
TvInputService
làm hành động để thực hiện với
ý định. Ngoài ra, hãy khai báo siêu dữ liệu dịch vụ dưới dạng một tài nguyên XML riêng. Chiến lược phát hành đĩa đơn
Nội dung khai báo dịch vụ, bộ lọc ý định và khai báo siêu dữ liệu dịch vụ
trong ví dụ sau:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
Xác định siêu dữ liệu dịch vụ trong một tệp XML riêng. Dịch vụ Tệp XML siêu dữ liệu phải bao gồm giao diện thiết lập mô tả đầu vào TV cấu hình ban đầu và quét kênh. Tệp siêu dữ liệu cũng phải chứa gắn cờ cho biết người dùng có thể ghi lại nội dung hay không. Để biết thêm thông tin về cách hỗ trợ ghi lại nội dung trong ứng dụng của bạn, hãy xem Hỗ trợ ghi nội dung.
Tệp siêu dữ liệu dịch vụ nằm trong thư mục tài nguyên XML
cho ứng dụng của bạn và phải khớp với tên của tài nguyên mà bạn đã khai báo trong
tệp kê khai. Bằng cách sử dụng các mục nhập tệp kê khai từ ví dụ trước, bạn sẽ
tạo tệp XML tại res/xml/richtvinputservice.xml
, với phần tử
những nội dung sau:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
Xác định các kênh và tạo hoạt động thiết lập của bạn
Dịch vụ đầu vào TV của bạn phải xác định ít nhất một kênh mà người dùng truy cập thông qua ứng dụng TV hệ thống. Bạn nên đăng ký kênh của mình trong cơ sở dữ liệu hệ thống và cung cấp hoạt động thiết lập mà hệ thống gọi khi không tìm thấy kênh cho ứng dụng của bạn.
Trước tiên, hãy cho phép ứng dụng của bạn đọc từ và ghi vào hệ thống Điện tử Hướng dẫn lập trình (EPG), trong đó dữ liệu bao gồm các kênh và chương trình có sẵn cho người dùng. Để cho phép ứng dụng của bạn thực hiện những tác vụ này và đồng bộ hoá với EPG sau khi khởi động lại thiết bị, hãy thêm các phần tử sau vào tệp kê khai ứng dụng:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
Hãy thêm phần tử sau đây để đảm bảo rằng ứng dụng của bạn sẽ xuất hiện trong Cửa hàng Google Play dưới dạng một ứng dụng cung cấp các kênh nội dung trong Android TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
Tiếp theo, hãy tạo một lớp mở rộng EpgSyncJobService
. Lớp trừu tượng này giúp bạn dễ dàng tạo dịch vụ công việc
tạo và cập nhật các kênh trong cơ sở dữ liệu hệ thống.
Trong lớp con, hãy tạo và trả về danh sách đầy đủ các kênh trong
getChannels()
. Nếu kênh của bạn đến từ một tệp XMLTV,
hãy sử dụng lớp XmlTvParser
. Nếu không, hãy tạo
các kênh theo phương thức lập trình bằng lớp Channel.Builder
.
Đối với mỗi kênh, hệ thống gọi getProgramsForChannel()
khi dịch vụ này cần danh sách các chương trình có thể xem được trong một khoảng thời gian nhất định
trên kênh. Trả về danh sách đối tượng Program
cho
của bạn. Dùng lớp XmlTvParser
để tải các chương trình từ
tệp XMLTV hoặc tạo tệp theo phương thức lập trình bằng
Lớp Program.Builder
.
Đối với mỗi đối tượng Program
, hãy sử dụng một
InternalProviderData
để thiết lập thông tin chương trình, chẳng hạn như
loại video của chương trình. Nếu chỉ giới hạn số lượng chương trình
muốn kênh lặp lại trong một vòng lặp, hãy sử dụng phương thức
Phương thức InternalProviderData.setRepeatable()
có giá trị là
true
khi thiết lập thông tin về chương trình của bạn.
Sau khi bạn triển khai dịch vụ công việc, hãy thêm dịch vụ đó vào tệp kê khai ứng dụng:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
Cuối cùng, hãy tạo một hoạt động thiết lập. Hoạt động thiết lập của bạn sẽ cung cấp một cách để đồng bộ hoá dữ liệu kênh và chương trình. Một cách để thực hiện việc này là để người dùng thực hiện thông qua giao diện người dùng trong hoạt động. Bạn cũng có thể để ứng dụng tự động thực hiện việc này khi hoạt động bắt đầu. Khi hoạt động thiết lập cần đồng bộ hoá kênh và thông tin chương trình, ứng dụng sẽ bắt đầu dịch vụ việc làm:
Kotlin
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
Java
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
Sử dụng phương thức requestImmediateSync()
để đồng bộ hoá
dịch vụ làm việc. Người dùng phải đợi quá trình đồng bộ hoá hoàn tất, vì vậy bạn nên
hãy giữ cho khoảng thời gian yêu cầu tương đối ngắn.
Sử dụng phương thức setUpPeriodicSync()
để có dịch vụ công việc
đồng bộ hoá định kỳ dữ liệu kênh và chương trình trong nền:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
Thư viện đồng hành TIF cung cấp một phương thức nạp chồng bổ sung của
requestImmediateSync()
cho phép bạn chỉ định thời lượng
để đồng bộ hoá theo mili giây. Phương thức mặc định sẽ đồng bộ hoá
giá trị của dữ liệu kênh.
Thư viện đồng hành TIF cũng cung cấp phương thức nạp chồng bổ sung của
setUpPeriodicSync()
cho phép bạn chỉ định thời lượng
để đồng bộ hoá và tần suất đồng bộ hoá định kỳ. Chiến lược phát hành đĩa đơn
mặc định đồng bộ hoá 48 giờ dữ liệu kênh mỗi 12 giờ.
Để biết thêm thông tin chi tiết về dữ liệu kênh và EPG, hãy xem Làm việc với dữ liệu kênh.
Xử lý các yêu cầu điều chỉnh và phát nội dung nghe nhìn
Khi người dùng chọn một kênh cụ thể, ứng dụng TV hệ thống sẽ sử dụng
Session
(do ứng dụng của bạn tạo) để chuyển sang kênh được yêu cầu
và phát nội dung. Thư viện đồng hành TIF cung cấp một số
bạn có thể mở rộng để xử lý lệnh gọi kênh và lệnh gọi phiên từ hệ thống.
Lớp con BaseTvInputService
tạo các phiên xử lý
yêu cầu điều chỉnh. Ghi đè
onCreateSession()
, tạo một phiên được mở rộng từ
lớp BaseTvInputService.Session
và gọi
super.sessionCreated()
với phiên mới của bạn. Trong phần sau
Ví dụ: onCreateSession()
trả về một
Đối tượng RichTvInputSessionImpl
mở rộng
BaseTvInputService.Session
:
Kotlin
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
Java
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
Khi người dùng sử dụng ứng dụng TV hệ thống để bắt đầu xem một trong các kênh của bạn,
hệ thống sẽ gọi phương thức onPlayChannel()
của phiên hoạt động. Ghi đè
bằng phương thức này nếu bạn cần thực hiện bất kỳ hoạt động khởi tạo kênh đặc biệt nào trước khi
bắt đầu phát.
Sau đó, hệ thống sẽ thu thập chương trình hiện đang được lên lịch và gọi
phương thức onPlayProgram()
của phiên, chỉ định chương trình
và thời gian bắt đầu tính bằng mili giây. Sử dụng
Giao diện TvPlayer
để bắt đầu phát chương trình.
Mã trình phát nội dung đa phương tiện của bạn nên triển khai TvPlayer
để xử lý
các sự kiện phát cụ thể. Lớp TvPlayer
xử lý các tính năng
chẳng hạn như các chế độ điều khiển ghi dịch thời gian mà không khiến
Triển khai BaseTvInputService
.
Trong phương thức getTvPlayer()
của phiên hoạt động, hãy trả về
trình phát nội dung đa phương tiện triển khai TvPlayer
. Chiến lược phát hành đĩa đơn
Ứng dụng mẫu TV Input Service triển khai trình phát nội dung đa phương tiện sử dụng
ExoPlayer.
Tạo dịch vụ đầu vào TV bằng khung đầu vào TV
Nếu dịch vụ đầu vào TV không thể sử dụng Thư viện đồng hành TIF, bạn cần để triển khai các thành phần sau:
TvInputService
cung cấp khả năng hoạt động trong thời gian dài và ở chế độ nền cho đầu vào TVTvInputService.Session
duy trì trạng thái đầu vào TV và giao tiếp với ứng dụng lưu trữTvContract
mô tả các kênh và chương trình có sẵn cho TV nguồn đầu vàoTvContract.Channels
biểu thị thông tin về một kênh truyền hìnhTvContract.Programs
mô tả một chương trình truyền hình có dữ liệu như chương trình tiêu đề và thời gian bắt đầuTvTrackInfo
đại diện cho âm thanh, video hoặc bản phụ đềTvContentRating
mô tả mức phân loại nội dung, cho phép áp dụng nội dung tuỳ chỉnh hệ thống phân loạiTvInputManager
cung cấp một API cho ứng dụng TV của hệ thống và quản lý sự tương tác với đầu vào và ứng dụng TV
Bạn cũng cần thực hiện các thao tác sau:
- Khai báo dịch vụ đầu vào TV trong tệp kê khai, như được mô tả trong Khai báo dịch vụ đầu vào TV trong tệp kê khai.
- Tạo tệp siêu dữ liệu về dịch vụ.
- Tạo và đăng ký thông tin kênh và chương trình của bạn.
- Tạo hoạt động thiết lập của bạn.
Xác định dịch vụ đầu vào TV
Đối với dịch vụ của mình, bạn mở rộng lớp TvInputService
. Đáp
Quá trình triển khai TvInputService
là một
dịch vụ ràng buộc, trong đó dịch vụ hệ thống
là ứng dụng khách liên kết với nó. Các phương thức vòng đời dịch vụ
3 bước được minh hoạ trong hình 1.
Phương thức onCreate()
khởi chạy và bắt đầu
HandlerThread
cung cấp một luồng quy trình tách biệt với luồng giao diện người dùng để
xử lý các thao tác do hệ thống điều khiển. Trong ví dụ sau, onCreate()
sẽ khởi chạy CaptioningManager
và chuẩn bị xử lý
ACTION_BLOCKED_RATINGS_CHANGED
và ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
hành động. Các
hành động mô tả ý định của hệ thống được kích hoạt khi người dùng thay đổi chế độ kiểm soát của cha mẹ, cũng như khi
nhưng danh sách điểm xếp hạng bị chặn sẽ có sự thay đổi.
Kotlin
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
Java
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }
Xem
Kiểm soát nội dung để biết thêm thông tin về cách xử lý nội dung bị chặn và cung cấp
chế độ kiểm soát của cha mẹ. Hãy xem TvInputManager
để biết các thao tác khác do hệ thống điều khiển
mà bạn có thể muốn xử lý trong dịch vụ đầu vào TV.
TvInputService
tạo một
TvInputService.Session
triển khai Handler.Callback
để xử lý các thay đổi về trạng thái của người chơi. Bằng
onSetSurface()
,
TvInputService.Session
sẽ thiết lập Surface
với
nội dung video. Xem Tích hợp trình phát với nền tảng
để biết thêm thông tin về cách làm việc với Surface
để kết xuất video.
TvInputService.Session
xử lý
onTune()
khi người dùng chọn một kênh đồng thời thông báo cho ứng dụng TV của hệ thống về các thay đổi về nội dung và
siêu dữ liệu nội dung. Các phương thức notify()
này được mô tả trong
Kiểm soát nội dung và Xử lý việc lựa chọn bản nhạc
trong khoá đào tạo này.
Xác định hoạt động thiết lập
Ứng dụng TV hệ thống sẽ xử lý hoạt động thiết lập mà bạn xác định cho đầu vào TV. Chiến lược phát hành đĩa đơn hoạt động thiết lập là bắt buộc và phải cung cấp ít nhất một bản ghi kênh cho cơ sở dữ liệu hệ thống. Chiến lược phát hành đĩa đơn ứng dụng TV của hệ thống gọi hoạt động thiết lập khi không thể tìm thấy kênh cho đầu vào TV.
Hoạt động thiết lập mô tả cho ứng dụng truyền hình của hệ thống các kênh được cung cấp qua TV như minh hoạ trong bài học tiếp theo, Tạo và cập nhật dữ liệu của kênh.