Android TV -5.3- Managing User Interaction
来源:互联网 发布:java培训就业前景 编辑:程序博客网 时间:2024/06/05 18:50
Managing User Interaction
This lesson teaches you to
- Integrate Player with Surface
- Use an Overlay
- Control Content
- Handle Track Selection
Try It Out
- TV Input Service sample app
In the live TV experience the user changes channels and is presented with channel and program information briefly before the information disappears. Other types of information, such as messages ("DO NOT ATTEMPT AT HOME"), subtitles, or ads may need to persist. As with any TV app, such information should not interfere with the program content playing on the screen.
Also consider whether certain program content should be presented, given the content's rating and parental control settings, and how your app behaves and informs the user when content is blocked or unavailable. This lesson describes how to develop your TV input's user experience for these considerations.
Integrate Player with Surface
Your TV input must render video onto a Surface
object, which is passed by theTvInputService.Session.onSetSurface()
method. Here's an example of how to use a MediaPlayer
instance for playing content in the Surface
object:
@Overridepublic boolean onSetSurface(Surface surface) { if (mPlayer != null) { mPlayer.setSurface(surface); } mSurface = surface; return true;}@Overridepublic void onSetStreamVolume(float volume) { if (mPlayer != null) { mPlayer.setVolume(volume, volume); } mVolume = volume;}
Similarly, here's how to do it using ExoPlayer:
@Overridepublic boolean onSetSurface(Surface surface) { if (mPlayer != null) { mPlayer.sendMessage(mVideoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } mSurface = surface; return true;}@Overridepublic void onSetStreamVolume(float volume) { if (mPlayer != null) { mPlayer.sendMessage(mAudioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME, volume); } mVolume = volume;}
Use an Overlay
Use an overlay to display subtitles, messages, ads or MHEG-5 data broadcasts. By default, the overlay is disabled. You can enable it when you create the session by callingTvInputService.Session.setOverlayViewEnabled(true)
, as in the following example:
@Overridepublic final Session onCreateSession(String inputId) { BaseTvInputSessionImpl session = onCreateSessionInternal(inputId); session.setOverlayViewEnabled(true); mSessions.add(session); return session;}
Use a View
object for the overlay, returned from TvInputService.Session.onCreateOverlayView()
, as shown here:
@Overridepublic View onCreateOverlayView() { LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.overlayview, null); mSubtitleView = (SubtitleView) view.findViewById(R.id.subtitles); // Configure the subtitle view. CaptionStyleCompat captionStyle; float captionTextSize = getCaptionFontSize(); captionStyle = CaptionStyleCompat.createFromCaptionStyle( mCaptioningManager.getUserStyle()); captionTextSize *= mCaptioningManager.getFontScale(); mSubtitleView.setStyle(captionStyle); mSubtitleView.setTextSize(captionTextSize); return view;}
The layout definition for the overlay might look something like this:
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.exoplayer.text.SubtitleView android:id="@+id/subtitles" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="32dp" android:visibility="invisible"/></FrameLayout>
Control Content
When the user selects a channel, your TV input handles the onTune()
callback in the TvInputService.Session
object. The system TV app's parental controls determine what content displays, given the content rating. The following sections describe how to manage channel and program selection using the TvInputService.Session
notify
methods that communicate with the system TV app.
Make Video Unavailable
When the user changes the channel, you want to make sure the screen doesn't display any stray video artifacts before your TV input renders the content. When you call TvInputService.Session.onTune()
, you can prevent the video from being presented by calling TvInputService.Session.notifyVideoUnavailable()
and passing the VIDEO_UNAVAILABLE_REASON_TUNING
constant, as shown in the following example.
@Overridepublic boolean onTune(Uri channelUri) { if (mSubtitleView != null) { mSubtitleView.setVisibility(View.INVISIBLE); } notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING); mUnblockedRatingSet.clear(); mDbHandler.removeCallbacks(mPlayCurrentProgramRunnable); mPlayCurrentProgramRunnable = new PlayCurrentProgramRunnable(channelUri); mDbHandler.post(mPlayCurrentProgramRunnable); return true;}
Then, when the content is rendered to the Surface
, you callTvInputService.Session.notifyVideoAvailable()
to allow the video to display, like so:
@Overridepublic void onDrawnToSurface(Surface surface) { mFirstFrameDrawn = true; notifyVideoAvailable();}
This transition lasts only for fractions of a second, but presenting a blank screen is visually better than allowing the picture to flash odd blips and jitters.
See also, Integrate Player with Surface for more information about working with Surface
to render video.
Provide Parental Control
To determine if a given content is blocked by parental controls and content rating, you check theTvInputManager
class methods, isParentalControlsEnabled()
andisRatingBlocked(android.media.tv.TvContentRating)
. You might also want to make sure the content'sTvContentRating
is included in a set of currently allowed content ratings. These considerations are shown in the following sample.
private void checkContentBlockNeeded() { if (mCurrentContentRating == null || !mTvInputManager.isParentalControlsEnabled() || !mTvInputManager.isRatingBlocked(mCurrentContentRating) || mUnblockedRatingSet.contains(mCurrentContentRating)) { // Content rating is changed so we don't need to block anymore. // Unblock content here explicitly to resume playback. unblockContent(null); return; } mLastBlockedRating = mCurrentContentRating; if (mPlayer != null) { // Children restricted content might be blocked by TV app as well, // but TIF should do its best not to show any single frame of blocked content. releasePlayer(); } notifyContentBlocked(mCurrentContentRating);}
Once you have determined if the content should or should not be blocked, notify the system TV app by calling the TvInputService.Session
method notifyContentAllowed()
or notifyContentBlocked()
, as shown in the previous example.
Use the TvContentRating
class to generate the system-defined string for the COLUMN_CONTENT_RATING
with theTvContentRating.createRating()
method, as shown here:
TvContentRating rating = TvContentRating.createRating( "com.android.tv", "US_TV", "US_TV_PG", "US_TV_D", "US_TV_L");
Handle Track Selection
The TvTrackInfo
class holds information about media tracks such as the track type (video, audio, or subtitle) and so forth.
The first time your TV input session is able to get track information, it should callTvInputService.Session.notifyTracksChanged()
with a list of all tracks to update the system TV app. When there is a change in track information, call notifyTracksChanged()
again to update the system.
The system TV app provides an interface for the user to select a specific track if more than one track is available for a given track type; for example, subtitles in different languages. Your TV input responds to theonSelectTrack()
call from the system TV app by calling notifyTrackSelected()
, as shown in the following example. Note that when null
is passed as the track ID, this deselects the track.
@Overridepublic boolean onSelectTrack(int type, String trackId) { if (mPlayer != null) { if (type == TvTrackInfo.TYPE_SUBTITLE) { if (!mCaptionEnabled && trackId != null) { return false; } mSelectedSubtitleTrackId = trackId; if (trackId == null) { mSubtitleView.setVisibility(View.INVISIBLE); } } if (mPlayer.selectTrack(type, trackId)) { notifyTrackSelected(type, trackId); return true; } } return false;}
- Android TV -5.3- Managing User Interaction
- android tv-Managing User Interaction
- DB2 managing user & privilege
- how to install CA certificate programmatically on Android without user interaction
- codesign returns User Interaction is not allowed
- Android TV
- Android TV
- Android TV-Handling TV Hardware
- Android TV-Creating TV Navigation
- android TV-Recommending TV Content,
- android tv-Building TV Games
- android tv-TV Apps Checklist
- android-Managing Audio Playback
- Android-《Managing Audio Playback》
- Printing documents to Microsoft XPS Document Writer without user interaction
- How to change user habits with interaction design
- 【FAQ】xcodebuild 签名,提示User interaction is not allowed?
- xcode打包出错:User interaction is not allowed
- Exploring Miscellaneous Capabilities探索各种功能
- n-1位数
- 读王垠《编程的智慧》笔记
- Android TV -5.2- Working with Channel Data
- 界面元素构件查询SQL的生成
- Android TV -5.3- Managing User Interaction
- POJ 2785_4 Values whose Sum is 0
- C、C++中命名规范
- p39最大子数组问题o(lgn)
- u-boot-2016.01移植笔记之支持dm9000
- 天声人語 20160210 公平中立をめぐる空気
- html5 时钟
- 日经春秋 20160210
- Centos6.5分区及安装系统准备