i read the article Android WebView: handling orientation changes
and follow the tip i build a project MainActivity
package com.example.testvideo1;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.WebView;
import android.os.Build;
@SuppressLint("NewApi")
public class MainActivity extends ActionBarActivity {
private VideoEnabledWebView webView;
private VideoEnabledWebChromeClient webChromeClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set layout
setContentView(R.layout.activity_main);
// Save the web view
webView = (VideoEnabledWebView) findViewById(R.id.webView);
// Initialize the VideoEnabledWebChromeClient and set event handlers
View nonVideoLayout = findViewById(R.id.nonVideoLayout);
// Your own view,
//Your own view,
ViewGroup videoLayout = (ViewGroup) findViewById(R.id.videoLayout);
View loadingView = null; // Your own view, read class comments
webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout,
videoLayout, loadingView, webView) // See all available
// constructors...
{
// Subscribe to standard events, such as onProgressChanged()...
@Override
public void onProgressChanged(WebView view, int progress) {
// Your code...
}
};
webChromeClient
.setOnToggledFullscreen(new VideoEnabledWebChromeClient.ToggledFullscreenCallback() {
@Override
public void toggledFullscreen(boolean fullscreen) {
// Your code to handle the full-screen change, for
// example showing and hiding the title bar. Example:
if (fullscreen) {
WindowManager.LayoutParams attrs = getWindow()
.getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
getWindow().setAttributes(attrs);
if (android.os.Build.VERSION.SDK_INT >= 14) {
getWindow()
.getDecorView()
.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
} else {
WindowManager.LayoutParams attrs = getWindow()
.getAttributes();
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
getWindow().setAttributes(attrs);
if (android.os.Build.VERSION.SDK_INT >= 14) {
getWindow().getDecorView()
.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_VISIBLE);
}
}
}
});
webView.setWebChromeClient(webChromeClient);
// Navigate everywhere you want, this classes have only been tested on
// YouTube's mobile site
webView.loadUrl("http://app.vlooks.cn/webchat/html5/2300/home");
}
@Override
public void onBackPressed() {
// Notify the VideoEnabledWebChromeClient, and handle it ourselves if it
// doesn't handle it
if (!webChromeClient.onBackPressed()) {
if (webView.canGoBack()) {
webView.goBack();
} else {
// Close app (presumably)
super.onBackPressed();
}
}
}
}
follow is VideoEnabledWebChromeClient.java
package com.example.testvideo1;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;
/**
* This class serves as a WebChromeClient to be set to a WebView, allowing it to
* play video. Video will play differently depending on target API level
* (in-line, fullscreen, or both).
*
* It has been tested with the following video classes: -
* android.widget.VideoView (typically API level <11) -
* android.webkit.HTML5VideoFullScreen$VideoSurfaceView/VideoTextureView
* (typically API level 11-18) -
* com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView
* (typically API level 19+)
*
* Important notes: - For API level 11+, android:hardwareAccelerated="true" must
* be set in the application manifest. - The invoking activity must call
* VideoEnabledWebChromeClient's onBackPressed() inside of its own
* onBackPressed(). - Tested in Android API levels 8-19. Only tested on
* http://m.youtube.com.
*
* @author Cristian Perez (http://cpr.name)
*
*/
public class VideoEnabledWebChromeClient extends WebChromeClient implements
OnPreparedListener, OnCompletionListener, OnErrorListener {
public interface ToggledFullscreenCallback {
public void toggledFullscreen(boolean fullscreen);
}
private View activityNonVideoView;
private ViewGroup activityVideoView;
private View loadingView;
private VideoEnabledWebView webView;
private boolean isVideoFullscreen; // Indicates if the video is being
// displayed using a custom view
// (typically full-screen)
private FrameLayout videoViewContainer;
private CustomViewCallback videoViewCallback;
private ToggledFullscreenCallback toggledFullscreenCallback;
/**
* Never use this constructor alone. This constructor allows this class to
* be defined as an inline inner class in which the user can override
* methods
*/
@SuppressWarnings("unused")
public VideoEnabledWebChromeClient() {
}
/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView
* A View in the activity's layout that contains every other view
* that should be hidden when the video goes full-screen.
* @param activityVideoView
* A ViewGroup in the activity's layout that will display the
* video. Typically you would like this to fill the whole layout.
*/
@SuppressWarnings("unused")
public VideoEnabledWebChromeClient(View activityNonVideoView,
ViewGroup activityVideoView) {
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = null;
this.webView = null;
this.isVideoFullscreen = false;
}
/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView
* A View in the activity's layout that contains every other view
* that should be hidden when the video goes full-screen.
* @param activityVideoView
* A ViewGroup in the activity's layout that will display the
* video. Typically you would like this to fill the whole layout.
* @param loadingView
* A View to be shown while the video is loading (typically only
* used in API level <11). Must be already inflated and without a
* parent view.
*/
@SuppressWarnings("unused")
public VideoEnabledWebChromeClient(View activityNonVideoView,
ViewGroup activityVideoView, View loadingView) {
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = loadingView;
this.webView = null;
this.isVideoFullscreen = false;
}
/**
* Builds a video enabled WebChromeClient.
*
* @param activityNonVideoView
* A View in the activity's layout that contains every other view
* that should be hidden when the video goes full-screen.
* @param activityVideoView
* A ViewGroup in the activity's layout that will display the
* video. Typically you would like this to fill the whole layout.
* @param loadingView
* A View to be shown while the video is loading (typically only
* used in API level <11). Must be already inflated and without a
* parent view.
* @param webView
* The owner VideoEnabledWebView. Passing it will enable the
* VideoEnabledWebChromeClient to detect the HTML5 video ended
* event and exit full-screen. Note: The web page must only
* contain one video tag in order for the HTML5 video ended event
* to work. This could be improved if needed (see Javascript
* code).
*/
public VideoEnabledWebChromeClient(View activityNonVideoView,
ViewGroup activityVideoView, View loadingView,
VideoEnabledWebView webView) {
this.activityNonVideoView = activityNonVideoView;
this.activityVideoView = activityVideoView;
this.loadingView = loadingView;
this.webView = webView;
this.isVideoFullscreen = false;
}
/**
* Indicates if the video is being displayed using a custom view (typically
* full-screen)
*
* @return true it the video is being displayed using a custom view
* (typically full-screen)
*/
public boolean isVideoFullscreen() {
return isVideoFullscreen;
}
/**
* Set a callback that will be fired when the video starts or finishes
* displaying using a custom view (typically full-screen)
*
* @param callback
* A VideoEnabledWebChromeClient.ToggledFullscreenCallback
* callback
*/
public void setOnToggledFullscreen(ToggledFullscreenCallback callback) {
this.toggledFullscreenCallback = callback;
}
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (view instanceof FrameLayout) {
// A video wants to be shown
FrameLayout frameLayout = (FrameLayout) view;
View focusedChild = frameLayout.getFocusedChild();
// Save video related variables
this.isVideoFullscreen = true;
this.videoViewContainer = frameLayout;
this.videoViewCallback = callback;
// Hide the non-video view, add the video view, and show it
activityNonVideoView.setVisibility(View.INVISIBLE);
activityVideoView.addView(videoViewContainer, new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
activityVideoView.setVisibility(View.VISIBLE);
if (focusedChild instanceof android.widget.VideoView) {
// android.widget.VideoView (typically API level <11)
android.widget.VideoView videoView = (android.widget.VideoView) focusedChild;
// Handle all the required events
videoView.setOnPreparedListener(this);
videoView.setOnCompletionListener(this);
videoView.setOnErrorListener(this);
} else {
// Other classes, including:
// - android.webkit.HTML5VideoFullScreen$VideoSurfaceView, which
// inherits from android.view.SurfaceView (typically API level
// 11-18)
// - android.webkit.HTML5VideoFullScreen$VideoTextureView, which
// inherits from android.view.TextureView (typically API level
// 11-18)
// -
// com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView,
// which inherits from android.view.SurfaceView (typically API
// level 19+)
// Handle HTML5 video ended event only if the class is a
// SurfaceView
// Test case: TextureView of Sony Xperia T API level 16 doesn't
// work fullscreen when loading the javascript below
if (webView != null
&& webView.getSettings().getJavaScriptEnabled()
&& focusedChild instanceof SurfaceView) {
// Run javascript code that detects the video end and
// notifies the Javascript interface
String js = "javascript:";
js += "var _ytrp_html5_video_last;";
js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];";
js += "if (_ytrp_html5_video != undefined && _ytrp_html5_video != _ytrp_html5_video_last) {";
{
js += "_ytrp_html5_video_last = _ytrp_html5_video;";
js += "function _ytrp_html5_video_ended() {";
{
js += "_VideoEnabledWebView.notifyVideoEnd();"; // Must
// match
// Javascript
// interface
// name
// and
// method
// of
// VideoEnableWebView
}
js += "}";
js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";
}
js += "}";
webView.loadUrl(js);
}
}
// Notify full-screen change
if (toggledFullscreenCallback != null) {
toggledFullscreenCallback.toggledFullscreen(true);
}
}
}
@Override
@SuppressWarnings("deprecation")
public void onShowCustomView(View view, int requestedOrientation,
CustomViewCallback callback) // Available in API level 14+,
// deprecated in API level 18+
{
onShowCustomView(view, callback);
}
@Override
public void onHideCustomView() {
// This method should be manually called on video end in all cases
// because it's not always called automatically.
// This method must be manually called on back key press (from this
// class' onBackPressed() method).
if (isVideoFullscreen) {
// Hide the video view, remove it, and show the non-video view
activityVideoView.setVisibility(View.INVISIBLE);
activityVideoView.removeView(videoViewContainer);
activityNonVideoView.setVisibility(View.VISIBLE);
// Call back (only in API level <19, because in API level 19+ with
// chromium webview it crashes)
if (videoViewCallback != null
&& !videoViewCallback.getClass().getName()
.contains(".chromium.")) {
videoViewCallback.onCustomViewHidden();
}
// Reset video related variables
isVideoFullscreen = false;
videoViewContainer = null;
videoViewCallback = null;
// Notify full-screen change
if (toggledFullscreenCallback != null) {
toggledFullscreenCallback.toggledFullscreen(false);
}
}
}
@Override
public View getVideoLoadingProgressView() // Video will start loading, only
// called in the case of
// VideoView (typically API
// level 10-)
{
if (loadingView == null) {
return super.getVideoLoadingProgressView();
} else {
loadingView.setVisibility(View.VISIBLE);
return loadingView;
}
}
@Override
public void onPrepared(MediaPlayer mp) // Video will start playing, only
// called in the case of
// android.widget.VideoView
// (typically API level <11)
{
if (loadingView != null) {
loadingView.setVisibility(View.GONE);
}
}
@Override
public void onCompletion(MediaPlayer mp) // Video finished playing, only
// called in the case of
// android.widget.VideoView
// (typically API level <11)
{
onHideCustomView();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) // Error while
// playing
// video, only
// called in the
// case of
// android.widget.VideoView
// (typically
// API level
// <11)
{
return false; // By returning false, onCompletion() will be called
}
/**
* Notifies the class that the back key has been pressed by the user. This
* must be called from the Activity's onBackPressed(), and if it returns
* false, the activity itself should handle it. Otherwise don't do anything.
*
* @return Returns true if the event was handled, and false if was not
* (video view is not visible)
*/
public boolean onBackPressed() {
if (isVideoFullscreen) {
onHideCustomView();
return true;
} else {
return false;
}
}
}
and VideoEnabledWebView.java
package com.example.testvideo1;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import java.util.Map;
/**
* This class serves as a WebView to be used in conjunction with a
* VideoEnabledWebChromeClient. It makes possible: - To detect the HTML5 video
* ended event so that the VideoEnabledWebChromeClient can exit full-screen.
*
* Important notes: - Javascript is enabled by default and must not be disabled
* with getSettings().setJavaScriptEnabled(false). - setWebChromeClient() must
* be called before any loadData(), loadDataWithBaseURL() or loadUrl() method.
*
* @author Cristian Perez (http://cpr.name)
*
*/
public class VideoEnabledWebView extends WebView {
public class JavascriptInterface {
@android.webkit.JavascriptInterface
public void notifyVideoEnd() // Must match Javascript interface method
// of VideoEnabledWebChromeClient
{
// This code is not executed in the UI thread, so we must force that
// to happen
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (videoEnabledWebChromeClient != null) {
videoEnabledWebChromeClient.onHideCustomView();
}
}
});
}
}
private VideoEnabledWebChromeClient videoEnabledWebChromeClient;
private boolean addedJavascriptInterface;
public VideoEnabledWebView(Context context) {
super(context);
addedJavascriptInterface = false;
}
@SuppressWarnings("unused")
public VideoEnabledWebView(Context context, AttributeSet attrs) {
super(context, attrs);
addedJavascriptInterface = false;
}
@SuppressWarnings("unused")
public VideoEnabledWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addedJavascriptInterface = false;
}
/**
* Indicates if the video is being displayed using a custom view (typically
* full-screen)
*
* @return true it the video is being displayed using a custom view
* (typically full-screen)
*/
public boolean isVideoFullscreen() {
return videoEnabledWebChromeClient != null
&& videoEnabledWebChromeClient.isVideoFullscreen();
}
/**
* Pass only a VideoEnabledWebChromeClient instance.
*/
@Override
@SuppressLint("SetJavaScriptEnabled")
public void setWebChromeClient(WebChromeClient client) {
getSettings().setJavaScriptEnabled(true);
if (client instanceof VideoEnabledWebChromeClient) {
this.videoEnabledWebChromeClient = (VideoEnabledWebChromeClient) client;
}
super.setWebChromeClient(client);
}
@Override
public void loadData(String data, String mimeType, String encoding) {
addJavascriptInterface();
super.loadData(data, mimeType, encoding);
}
@Override
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl) {
addJavascriptInterface();
super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}
@Override
public void loadUrl(String url) {
addJavascriptInterface();
super.loadUrl(url);
}
@Override
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
addJavascriptInterface();
super.loadUrl(url, additionalHttpHeaders);
}
private void addJavascriptInterface() {
if (!addedJavascriptInterface) {
// Add javascript interface to be called when the video ends (must
// be done before page load)
addJavascriptInterface(new JavascriptInterface(),
"_VideoEnabledWebView"); // Must match Javascript interface
// name of
// VideoEnabledWebChromeClient
addedJavascriptInterface = true;
}
}
}
and the layout file
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="@+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.VideoEnabledWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- View that will be shown while the fullscreen video loads (maybe include a spinner and a "Loading..." message) -->
<View
android:id="@+id/videoLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="invisible" />
</RelativeLayout>
the project can't work, and i want when fullscreen , let the program go LandScape mode. but i failed.
thanks.......
I've been facing the same issue. Although this question is quite old, I have come to a simple solution which I could not find on stack overflow.
Just enforce Landscape when going full screen:
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
And revert this, when going back.
In context:
public class BaseWebChromeClient extends WebChromeClient
{
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
{
[...]
act.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
[...]
@Override
public void onHideCustomView(View view, WebChromeClient.CustomViewCallback callback)
{
[...]
act.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// use SCREEN_ORIENTATION_SENSOR, if you don't to enforce portrait mode.
[...]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With