Skip to content

Instantly share code, notes, and snippets.

@ademirqueiroga
ademirqueiroga / SimplePlaybackTransportControlGlue.kt
Last active March 14, 2023 16:51
SimplePlaybackTransportControlGlue media session creation
class SimplePlaybackTransportControlGlue(
context: Context,
playerAdapter: MediaPlayerAdapter,
) : PlaybackTransportControlGlue<MediaPlayerAdapter>(context, playerAdapter) {
private val mediaSession = MediaSessionCompat(context, "VideoPlayback")
init {
mediaSession.setCallback(SimpleMediaSessionCallback())
}
@ademirqueiroga
ademirqueiroga / AndroidManifest.xml
Created March 14, 2023 15:34
MediaSession sample AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<uses-permission android:name="com.amazon.permission.media.session.voicecommandcontrol" />
...
<application>
<meta-data
android:name="com.amazon.voice.supports_background_media_session"
android:value="true" />
<application/>
@ademirqueiroga
ademirqueiroga / themes.xml
Created March 6, 2023 12:05
Widget.Leanback.Headers.VerticalGridView default style
<style name="Widget.Leanback.Headers.VerticalGridView">
<item name="android:background">?attr/defaultBrandColor</item>
<item name="android:paddingStart">?attr/browsePaddingStart</item>
<item name="focusOutFront">true</item>
<item name="focusOutEnd">true</item>
<item name="android:verticalSpacing">@dimen/lb_browse_headers_vertical_spacing</item>
<item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:contentDescription">@string/lb_navigation_menu_contentDescription</item>
</style>
@ademirqueiroga
ademirqueiroga / MainFragment.kt
Created March 6, 2023 02:08
MainFragment.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60f, resources.displayMetrics).toInt()
val headerPresenterSelector = headersSupportFragment.presenterSelector as ClassPresenterSelector
headerPresenterSelector
.addClassPresenter(IconSectionRow::class.java, IconSectionPresenter())
.addClassPresenter(DividerRow::class.java, SpaceDividerPresenter(height))
}
@ademirqueiroga
ademirqueiroga / SpaceDividerPresenter.kt
Created March 6, 2023 02:01
SpaceDividerPresenter.kt
class SpaceDividerPresenter(private val height: Int) : Presenter() {
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
val view = View(parent.context)
// Make sure to make it not focusable. Otherwise, when
// HeadersSupportFragment tries to cast this ViewHolder to
// RowHeaderPresenter.ViewHolder it will crash.
view.isFocusable = false
view.isFocusableInTouchMode = false
// For the same reason, disable clicks so your app does not
@ademirqueiroga
ademirqueiroga / icon_section_row.xml
Created March 6, 2023 01:47
icon_section_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="center|start"
android:orientation="horizontal">
<ImageView
android:id="@+id/row_header_icon"
@ademirqueiroga
ademirqueiroga / IconSectionPresenter.kt
Created March 6, 2023 01:43
IconSectionPresenter.kt
class IconSectionPresenter : RowHeaderPresenter() {
override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
val customView = LayoutInflater.from(parent.context)
.inflate(R.layout.icon_section_row, parent, false)
val superHolder = super.onCreateViewHolder(parent) as ViewHolder
(customView as ViewGroup).addView(superHolder.view)
return IconSectionViewHolder(customView)
}
@ademirqueiroga
ademirqueiroga / Fragment.kt
Created February 22, 2023 22:27
Handling channel/program intent
fun handleIntent(intent: Intent) {
val intentAction = intent.action
if (intentAction == Intent.ACTION_VIEW) {
val intentData = intent.data
val pathSegments = intentData?.pathSegments ?: emptyList()
when (pathSegments.firstOrNull()) {
"movie" -> pathSegments.get(1)?.let { movieId ->
val movie = MovieList.list.firstOrNull { it.id.toString() == movieId }
if (movie != null) {
val movieIntent = Intent(context, PlaybackActivity::class.java)
@ademirqueiroga
ademirqueiroga / AndroidManifest.xml
Created February 22, 2023 22:22
Channel/Program App link intent filters
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content" />
<data android:host="channelsample.com" android:pathPrefix="/discover"/>
<data android:host="channelsample.com" android:pathPrefix="/category"/>
<data android:host="channelsample.com" android:pathPrefix="/movie"/>
@ademirqueiroga
ademirqueiroga / Programs.kt
Created February 22, 2023 22:12
Get channel programs function
fun getChannelPrograms(channelId: Long): List<PreviewProgram> {
val programs = ArrayList<PreviewProgram>()
context.contentResolver.query(
/* uri = */ TvContractCompat.PreviewPrograms.CONTENT_URI,
/* projection = */ PreviewProgram.PROJECTION,
/* selection = */ null,
/* selectionArgs = */ null,
/* sortOrder = */ null
).use { cursor ->
if (cursor != null) {