Upload
amazon-web-services
View
416
Download
5
Embed Size (px)
Citation preview
MAR IO V IV IAN IT E C H N O L O G Y E V A N G E L I S T , A M A Z O N A P P S T O R E U K
@mariuxtheone http ://www. l inked in .com/ in/ mariov iv iani
ANDRO ID
DEVELOPMENT
ON AMAZ ON F IRE TV
I T ’ S A - M E !
M a r i o V i v i a n i
Technology Evangelist, Amazon Appstore UK
@mariuxtheone
Android Developer from 201095+ apps published12,000,000+ downloadsGoogle Developer Expert 2013-15Startup Founder, Co-WorkerSpeaker at: Droidcon, Android Dev Days, Google I/O 2015
Android is Not Just for
Mobile Devices
Android
Android TV Apps based on
Fire OS
Fire TV Apps based on
OS 5Based on
Android
Lollipop
Android
Studio
TV 4K & TV STICK
bit.ly/firetvspecs
TV TV Stick
4K compatible FullHDQuad-core CPU Dual-core CPU
2 GB RAM 1 GB RAM
(2160p)(1080p)
WiFi – Bluetooth 4.1 WiFi – Bluetooth 3.0
8 GB Internal Storage(actual formatted capacity will be less)
8 GB Internal Storage(actual formatted capacity will be less)
USB-A and MicroSD slot MicroUSB (power only)
TV APPS
Development on Fire TV
ADB Setup
Development on Fire TVConnect ADB via WiFi
adb connect <ipaddress>
- + xTerminal
Development on Fire TV
Project Setup:Media Streaming App
TV APPS DEVELOPMENT
Fire TV SDK add-on
v17 Leanback Library
Fire TV SDK add-on
Android Studio Project Setup
Android Studio Project Setup
dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])compile 'com.android.support:recyclerview-v7:23.1.1'compile 'com.android.support:leanback-v17:23.1.1'compile 'com.android.support:appcompat-v7:23.1.1'compile 'com.github.bumptech.glide:glide:3.4.+'
}
Gradle Dependencies
Browse
For
Content
Read
Description
&
Details
Play
TV Interaction Model
Browse
Fragment
Details
Fragment
Playback
Overlay
Fragment
TV App Model
Development on Fire TV
BrowseFragment
BrowseFragment
HeadersFragment RowsFragment
BrowseFragment
ListRowAdapter
HeaderItem
Movie Movie Movie
public class MainFragment extends BrowseFragment {
private void loadRows() {List<Movie> list = MovieList.setupMovies();
CardPresenter cardPresenter = new CardPresenter();
//Create the adapter for the row and add all the moviesArrayObjectAdapter listRowAdapter
= new ArrayObjectAdapter(cardPresenter);for (Movie movie:list) {
listRowAdapter.add(movie);}
//Create the header of this row HeaderItem header = new HeaderItem(0, "Category Name");
...
ListRowAdapter
RowsAdapter
public class MainFragment extends BrowseFragment {
...
//add the ListRowAdapter to the RowsAdapterArrayObjectAdapter rowsAdapter
= new ArrayObjectAdapter(new ListRowPresenter());
rowsAdapter.add(new ListRow(header, listRowAdapter));
setAdapter(mRowsAdapter);
}}
TitleDescription
TitleDescription
ImageCardView
public ViewHolder onCreateViewHolder(ViewGroup parent) {...
ImageCardView cardView = new ImageCardView(parent.getContext);cardView.setFocusable(true);cardView.setFocusableInTouchMode(true);return new ViewHolder(cardView);
...}
public class CardPresenter extends Presenter {
CardPresenter
CardPresenter
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {Movie movie = (Movie) item;ImageCardView cardView = (ImageCardView) viewHolder.view;
if (movie.getCardImageUrl() != null) {cardView.setTitleText(movie.getTitle());cardView.setContentText(movie.getDescription());Glide.with(viewHolder.view.getContext())
.load(movie.getCardImageUrl())
.centerCrop()
.into(cardView.getMainImageView());}
}
Development on Fire TV
DetailsFragment
TitleSubtitleDescription
ACTION ACTION
DetailsFragment
TitleSubtitleDescription
ACTION ACTION
private void setupDetailsOverviewRow() {
final DetailsOverviewRow row = new DetailsOverviewRow(mSelectedMovie);
...row.setImageDrawable(R.drawable.default_background));row.addAction(new Action(ACTION_WATCH_TRAILER,
“Watch Trailer”, “FREE”)));
mAdapter.add(row);}
DetailsOverviewRow
public class DetailsDescriptionPresenterextends AbstractDetailsDescriptionPresenter {
@Overrideprotected void onBindDescription(ViewHolder viewHolder, Object item) {
Movie movie = (Movie) item;
if (movie != null) {viewHolder.getTitle().setText(movie.getTitle());viewHolder.getSubtitle().setText(movie.getStudio());viewHolder.getBody().setText(movie.getDescription());
}}
}
DescriptionPresenter
public class DetailsDescriptionPresenterextends AbstractDetailsDescriptionPresenter {
@Overrideprotected void onBindDescription(ViewHolder viewHolder, Object item) {
Movie movie = (Movie) item;
if (movie != null) {viewHolder.getTitle().setText(movie.getTitle());viewHolder.getSubtitle().setText(movie.getStudio());viewHolder.getBody().setText(movie.getDescription());
}}
}
DescriptionPresenter
Development on Fire TV
Video Overlay
VideoView
PlaybackOverlayFragment
playback_controls.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent">
<VideoViewandroid:id="@+id/videoView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center" />
<fragmentandroid:id="@+id/playback_controls_fragment"android:name="PlaybackOverlayFragment"android:layout_width="match_parent"android:layout_height="match_parent" />
</FrameLayout>
PlaybackOverlayActivity - Components
public class PlaybackOverlayActivity extends Activity implements
PlaybackOverlayFragment.OnPlayPauseClickedListener {
private VideoView mVideoView;
private LeanbackPlaybackState mPlaybackState;
private MediaSession mSession;
PlaybackOverlayActivity - MediaSession
@Overridepublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.playback_controls);...
mSession = new MediaSession(this, "LeanbackSampleApp");mSession.setCallback(new MediaSessionCallback());mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS
| MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
mSession.setActive(true);
}
PlaybackOverlayActivity – Remote
@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) {
PlaybackOverlayFragment playbackOverlayFragment = findFragmentById(R.id.playback_controls_fragment);
switch (keyCode) {...case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (mPlaybackState == LeanbackPlaybackState.PLAYING) {playbackOverlayFragment.togglePlayback(false);
} else {playbackOverlayFragment.togglePlayback(true);
}return true;
...}
}
PlaybackOverlayActivity – Play/Pause
public void onFragmentPlayPause(Movie movie, int position, Boolean playPause) {
mVideoView.setVideoPath(movie.getVideoUrl());
...
if (mPlaybackState != LeanbackPlaybackState.PLAYING) {mPlaybackState = LeanbackPlaybackState.PLAYING;if (position > 0) {
mVideoView.seekTo(position);mVideoView.start();
}...
updatePlaybackState(position);updateMetadata(movie);
}
The Final
Result
CREATE
NEW EXPERIENCES
ON FIRE TV
Support for Game Controller
Amazon
Fling bit.ly/amazonfling
DIALDIscovery And Launch
Fire TV Catalogue Integration
developer.amazon.com/appstore