- Kotlin 78.7%
- TypeScript 20.5%
- JavaScript 0.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github/workflows | ||
| .idea | ||
| android | ||
| src | ||
| .eslintrc.json | ||
| .gitignore | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| rollup.config.mjs | ||
| tsconfig.json | ||
| vitest.config.ts | ||
capacitor-android-tv-channel
Capacitor plugin for Android TV Home Screen Channels (androidx.tvprovider) and background periodic synchronization with androidx.work.WorkManager.
Allows your Android TV Capacitor application to publish and manage home screen recommendation rows (channels and content cards) and schedule automatic background synchronization directly from a remote JSON feed.
Features
- 📺 Android TV Channels & Programs: Create, update, and remove rows and cards on the Android TV launcher screen (
androidx.tvprovider). - 🔄 Periodic Background Sync: Built-in
WorkManagerbackground worker to periodically fetch a remote JSON feed and update channels without opening the app. - ⚡ Immediate Content Delivery: Automatically runs an initial one-time background job upon configuration to immediately display content cards.
- 🛡️ Anti-Duplication: Automatic clearing and atomic updates to ensure cards don't accumulate duplicates.
- 🌐 Web Mock Fallback: Safe stub implementations for Web/PWA, Tizen, and WebOS environments without runtime exceptions.
- 🚀 100% Kotlin Native Layer: Written in modern idiomatic Kotlin with null-safety and robust error handling.
Install
npm install capacitor-android-tv-channel
npx cap sync android
Android Permissions
The plugin automatically includes the required permissions in its AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Usage Examples
1. Automated Background Periodic Synchronization (Recommended)
Configures Android TV to poll your backend endpoint (e.g. every 6 hours) and populate cards automatically:
import { TvChannel } from 'capacitor-android-tv-channel';
await TvChannel.configureSyncWorker({
channelId: 'trending_videos',
channelName: 'Trending Now',
channelDescription: 'Most watched videos today',
appLinkUri: 'myapp://home',
syncUrl: 'https://api.example.com/tv/trending.json',
headers: {
'Authorization': 'Bearer YOUR_AUTH_TOKEN',
'X-App-Version': '1.0.0'
},
intervalHours: 6, // Minimum 1 hour
clearOldPrograms: true, // Avoid duplicate cards
maxItems: 30
});
2. Manual Channel & Program Management
You can also programmatically publish or clear programs directly from JavaScript:
import { TvChannel } from 'capacitor-android-tv-channel';
// 1. Create channel
await TvChannel.createChannel({
id: 'featured_channel',
name: 'Featured Movies',
description: 'Hand-picked movies for you',
appLinkUri: 'myapp://movies'
});
// 2. Publish program cards
await TvChannel.setPrograms({
channelId: 'featured_channel',
programs: [
{
id: 'movie_101',
channelId: 'featured_channel',
title: 'Cosmic Journey',
description: 'Sci-Fi • 2h 15m',
posterArtUri: 'https://cdn.example.com/posters/cosmic.jpg',
intentUri: 'myapp://watch?id=movie_101',
durationMillis: 8100000,
type: 'movie'
}
],
clearOld: true
});
3. Cleanup on User Logout
await TvChannel.cancelSyncWorker({
channelId: 'trending_videos',
clearPrograms: true // Clears recommendation cards from the TV screen
});
JSON Feed Format (syncUrl)
Your remote endpoint configured in syncUrl should return a JSON response matching either format:
Structure Format (Recommended)
{
"channel": {
"id": "trending_videos",
"name": "Trending Now"
},
"programs": [
{
"id": "vid_101",
"title": "Amazing Nature Highlights",
"description": "4K Ultra HD • 15 min",
"posterArtUri": "https://cdn.example.com/thumbnails/101.jpg",
"intentUri": "myapp://watch?v=vid_101",
"durationMillis": 900000,
"type": "clip"
}
]
}
Flat Array Format
[
{
"id": "vid_101",
"title": "Amazing Nature Highlights",
"description": "4K Ultra HD • 15 min",
"posterArtUri": "https://cdn.example.com/thumbnails/101.jpg",
"intentUri": "myapp://watch?v=vid_101",
"durationMillis": 900000,
"type": "clip"
}
]
API
createChannel(...)deleteChannel(...)setPrograms(...)clearPrograms(...)configureSyncWorker(...)cancelSyncWorker(...)syncNow(...)getChannelStatus(...)requestChannelBrowsable(...)- Interfaces
- Type Aliases
Interfaces
TvChannelData
| Prop | Type | Description |
|---|---|---|
id |
string |
Unique identifier of the channel (internalProviderId). |
name |
string |
Display name of the channel row on the Android TV home screen. |
description |
string |
Optional channel description. |
appLinkUri |
string |
Deep link URI opened when clicking on the channel header or logo. |
logoUri |
string |
Optional URL or drawable resource name for the channel logo. |
TvProgramData
| Prop | Type | Description |
|---|---|---|
id |
string |
Unique identifier of the program item. |
channelId |
string |
Parent channel ID matching TvChannelData.id. |
title |
string |
Title shown on the program card. |
description |
string |
Subtitle or description text. |
posterArtUri |
string |
URL of the card's poster image / thumbnail. |
intentUri |
string |
Deep link URI opened when the user clicks this card. |
durationMillis |
number |
Duration in milliseconds (optional). |
type |
TvProgramType |
Program content type: clip, movie, episode, track. |
SyncWorkerConfig
| Prop | Type | Description |
|---|---|---|
channelId |
string |
Channel ID to be synchronized. |
channelName |
string |
Display name of the channel. |
channelDescription |
string |
Optional channel description. |
appLinkUri |
string |
Deep link URI for channel header click. |
syncUrl |
string |
HTTP(S) endpoint URL returning JSON feed. |
headers |
Record<string, string> |
Optional custom HTTP headers (e.g. Authorization, X-Api-Key). |
intervalHours |
number |
Periodic sync interval in hours (default: 6). |
clearOldPrograms |
boolean |
Whether to remove old programs before publishing new ones (default: true). |
maxItems |
number |
Maximum number of cards to display in the row (default: 30). |
TvChannelStatus
| Prop | Type | Description |
|---|---|---|
isCreated |
boolean |
Whether the channel has been registered in Android TvProvider. |
channelId |
number |
System row ID assigned by Android TvProvider (if created). |
isBrowsable |
boolean |
Whether the channel is currently visible/browsable on the home screen. |
programCount |
number |
Number of active programs in this channel. |
lastSyncTimestamp |
number |
Unix timestamp in milliseconds of the last successful background sync. |
Type Aliases
TvProgramType
'clip' | 'movie' | 'episode' | 'track'
License
MIT © MarcBanc