I am trying to play html5 video and youtube video within android webview, but can't display video on android webview screen. and play this video.
I have used below code snippet...
layout xml file naming: test.xml contains below code snipet:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:id="#+id/rltvLayoutTest"
android:layout_height="fill_parent">
<WebView android:id="#+id/webViewTest" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
and Activity Class name: Test.java contains code given below:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
WebView mWebView = (WebView)findViewById(R.id.webViewTest);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setPluginsEnabled(true);
mWebView.setWebChromeClient(new chromeClient());
mWebView.setWebViewClient(new WebViewClient(){
});
mWebView.loadUrl("http://broken-links.com/tests/video/");
}
public class chromeClient extends WebChromeClient implements OnCompletionListener, OnErrorListener{
private WebView wv;
private VideoView mVideoView;
private LinearLayout mContentView;
private FrameLayout mCustomViewContainer;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, Gravity.CENTER);
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (view instanceof FrameLayout) {
wv = (WebView)findViewById(R.id.webViewTest);
mCustomViewContainer = (FrameLayout) view;
mCustomViewCallback = callback;
mContentView = (LinearLayout)findViewById(R.id.rltvLayoutTest);
if (mCustomViewContainer.getFocusedChild() instanceof VideoView) {
mVideoView = (VideoView) mCustomViewContainer.getFocusedChild();
// frame.removeView(video);
mContentView.setVisibility(View.GONE);
mCustomViewContainer.setVisibility(View.VISIBLE);
setContentView(mCustomViewContainer);
mVideoView.setOnCompletionListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.start();
}
}
}
public void onHideCustomView() {
if (mVideoView == null)
return;
// Hide the custom view.
mVideoView.setVisibility(View.GONE);
// Remove the custom view from its container.
mCustomViewContainer.removeView(mVideoView);
mVideoView = null;
mCustomViewContainer.setVisibility(View.GONE);
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
mContentView.setVisibility(View.VISIBLE);
}
public void onCompletion(MediaPlayer mp) {
mp.stop();
mCustomViewContainer.setVisibility(View.GONE);
onHideCustomView();
setContentView(mContentView);
}
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
setContentView(mContentView);
return true;
}
}
I used html5webview to solve this problem.Download and put it into your project then you can code just like this.
private HTML5WebView mWebView;
String url = "SOMEURL";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView = new HTML5WebView(this);
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
mWebView.loadUrl(url);
}
setContentView(mWebView.getLayout());
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mWebView.saveState(outState);
}
To make the video rotatable, put android:configChanges="orientation" code into your Activity
for example (Androidmanifest.xml)
<activity android:name=".ui.HTML5Activity" android:configChanges="orientation"/>
and override the onConfigurationChanged method.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
you haven't added mCustomViewContainer to your view hierarchy
if you are running it on tablet... you add hardwareaccelerated= true in your manifest file and it will certainly work.. also change the sdk version to 11
It worked for me. May help you as well play html videos
Related
In My activity I have a Webview at the top which plays the video inside it.
below the Webview I have a list of videos to select. For Android versions before Oreo when I select the new video it always plays in the Webview. But in Oreo it doesn't work, It always plays the first video Which i Selected. I have read the document of Oreo it says that
Calling clearFormData() no longer has any effect.
I am looking for some alternative but couldn't find any solution. Below is the my work which I have done so for
private void initViews() {
toolbar = findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(getString(R.string.app_name));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
recyclerView = findViewById(R.id.recycler_view);
progressBar = findViewById(R.id.progressBar3);
initWebView();
if (recyclerView != null) {
initRecyclerView(model);
}
AdView adView= findViewById(R.id.ad_view);
admobUtils.loadBannerAd(adView);
}
public void initWebView() {
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setSaveFormData(false);
webView.clearFormData();
webView.clearCache(true);
webView.clearHistory();
webView.setWebViewClient(new WebViewClient() {
#Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
view.clearHistory();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
RXEventBusUtils.getInstance().postEvent(new MediaPlayerEvent());
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
webView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
}
});
webView.getSettings().setBuiltInZoomControls(false);
webView.getSettings().setDisplayZoomControls(false);
String htmlData;
if (Constants.isFullScreen) {
htmlData = getHtmlDataLanscape(model.getVideo_url());
} else {
htmlData = getHtmlData(model.getVideo_url());
}
webView.loadData(htmlData, "text/html", null);
}
This is where I am selecting the video from list.
public void selectVideo(){
progressBar.setVisibility(View.VISIBLE);
model = new MyModel();
model = ((SelectVideoEvent) event).getModel();
if (model.getVideo_url() != null && !model.getVideo_url().isEmpty()) {
initRecyclerView(model);
initWebView();
Bundle bundleFire = new Bundle();
Application.getFireBaseInstance().logEvent("video_from_list",bundleFire);
}
}
Please can anybody tell me how to change the webview content in Android Oreo
As clearFormData() no longer has any effect in android version Oreo. The best way is to create a Webview as a new view. For that purpose you should use a frameLayout inside xml file, and inside java file, create webview dynamically and add that webview in framelayout as a view.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<FrameLayout
android:id="#+id/myWeb"
android:layout_width="match_parent"
android:layout_height="200dp"
android:alwaysDrawnWithCache="true" />
</RelativeLayout>
public class TestActivity extends AppCompatActivity {
FrameLayout frameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
frameLayout = findViewById(R.id.myWeb);
setWebView();
/*setWebViewToLoadData*/
}
public void setWebView(){
frameLayout.removeAllViews();
WebView webView = new WebView(this);
webView.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
frameLayout.addView(webView);
}
}
And indside your selectVideo method call again setWebView
I am working in an Android app and I want to preload splash screen while the webView is loading the webpage BUT i have a local .mp4 video instead of a picture.
So once the user clicks the app, the .mp4 will start playing (4 seconds). During that 4 seconds the webView should pre-load the webpage SO when the video is finished show my web page (if the web page is already loaded), otherwise wait in the splash screen until the webpage is ready and then load it.
Here is my MainActivity:
public class MainActivity extends AppCompatActivity {
private WebView webView;
public static final Object SPLASH_LOCK = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
String myURL = "https://www.testpage.com";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
/** tell the webView to enable javascript execution */
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
/** Load the HTML page */
webView.loadUrl(myURL);
/** Call the JavaScriptInterface within the WebView */
webView.addJavascriptInterface(this, "jsinterface");
startActivity(new Intent(this, AnimationScreenActivity.class));
/** Enable Javascript in WebView
/ callback for browser events */
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished (WebView webView, String url) {
synchronized (SPLASH_LOCK) {
SPLASH_LOCK.notifyAll();
}
}
});
}
}
Here is the AnimationScreenActivity:
public class AnimationScreenActivity extends AppCompatActivity{
private static String TAG = AnimationScreenActivity.class.getName();
private static long MAX_SPLASH_TIME = 10000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animation_screen);
try {
VideoView videoHolder = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoHolder.setVideoURI(video);
videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
jump();
}
});
videoHolder.start();
} catch (Exception ex) { jump(); }
}
private void jump() {
new Thread() {
#Override
public void run() {
synchronized (MainActivity.SPLASH_LOCK) {
// wait for notify or time-out
try {
MainActivity.SPLASH_LOCK.wait(MAX_SPLASH_TIME);
} catch (InterruptedException ignored) {}
}
finish();
}
}.start();
}
}
Here is the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Here is the animation_screen_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/animation_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test.AnimationScreenActivity">
<VideoView
android:id="#+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
And finally the Manifest.xml where i set MainActivity as LAUNCHER:
<activity android:name=".MainActivity"
android:theme="#style/FullScreenTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AnimationScreenActivity"
android:theme="#style/FullScreenTheme"
android:screenOrientation="portrait"/>
So what i have until now is that once the user starts the app, the .mp4 starts and when the .mp4 finish THEN it waits for 10 seconds in the AnimationScreenActivity and THEN it loads the webpage.
Any help will be appreciated!
You can have a single Activity that has what you have on the 2 Activities, by having a ViewSwitcher (or ViewAnimator) to switch between the layouts.
This will also remove the need for the SPLASH_LOCK object.
While loading, switch the ViewSwitcher (or ViewAnimator) to the layout of the video, and when you are done loading the page, switch it to the layout of the WebView.
I've made a simple code to make it easier to switch between view. If you wish, you can use it:
public static void setViewToSwitchTo(#NonNull final ViewAnimator viewAnimator, #NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
public static void setViewToSwitchTo(#NonNull final ViewAnimator viewAnimator, #IdRes final int viewIdToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView().getId() == viewIdToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i).getId() == viewIdToSwitchTo) {
if (viewAnimator.getDisplayedChild() == i)
return;
viewAnimator.setDisplayedChild(i);
return;
}
}
Usage:
setViewToSwitchTo(viewSwitcher, R.id.webViewLayout);
or:
setViewToSwitchTo(viewSwitcher, webViewLayout);
You can even have an animation when switching between the views, using "inAnimation" and "outAnimation" attributes.
And, if the code gets too large, you can have fragments instead of views. One for the WebView, and another for the video.
About onPageFinished being called multiple times, you need to check which of them is the one that you consider as really being finished. Since each website is different, and can have multiple frames, you will have to add this logic. If you want, you can monitor onPageStarted, as shown here:
https://forums.xamarin.com/discussion/15293/why-is-onpagefinished-firing-off-three-times-for-one-url-load-request
https://stackoverflow.com/a/25547544/878126
BTW, if you change the orientation in the manifest, do note that since you have a WebView, you will have to think what to do with orientation change, because it doesn't restore its state well.
EDIT:
Here's the layout file:
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<VideoView
android:id="#+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" />
</ViewSwitcher>
in the onCreate, use the code of both of your activities, and add this to go to the video :
setViewToSwitchTo(viewSwitcher, R.id.videoView1);
and this to go to the webView (when it has done loading, in your case) :
setViewToSwitchTo(viewSwitcher, R.id.webView);
After a lot of help from #android developer (many thanks!) and stackoverflow posts, I have combined both activities MainActivity, AnimationScreenActivity in one activity (MainActivity).
Here is the code:
public class MainActivity extends AppCompatActivity {
private String myURL = "https://www.testpage.com";
VideoView videoView;
ViewSwitcher viewSwitcher;
private WebView webView;
private boolean hasFinishedLoadingPage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoView.setVideoURI(video);
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (hasFinishedLoadingPage)
setViewToSwitchTo(viewSwitcher, webView);
// else webView.reload();
setViewToSwitchTo(viewSwitcher, webView);
}
});
videoView.start();
} catch (Exception ex) {
}
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
webView.setWebViewClient(new WebViewClient() {
boolean isRedirected;
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!isRedirected) {
setViewToSwitchTo(viewSwitcher, videoView);
}
isRedirected = true;
}
#Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
hasFinishedLoadingPage = true;
}
});
/** Callback for web events */
webView.setWebChromeClient(new WebChromeClient() {
});
webView.loadUrl(myURL);
}
public static void setViewToSwitchTo(#NonNull final ViewAnimator viewAnimator, #NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
}
My suggestion would be to avoid having 2 activities, I suspect that's one of your problems.
Have only one Activity with the VideoView and the WebView both inside a RelativeLayout so that VideoView is above the WebView.
When the WebView is ready, simply VideoView.setVisibity(View.GONE)
I use following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_web_view_play_youtube);
WebView w = (WebView) findViewById(R.id.w);
w.setWebChromeClient(new WebChromeClient());
w.setWebViewClient(new WebViewClient());
w.getSettings().setJavaScriptEnabled(true);
w.loadUrl("https://www.youtube.com/watch?v=gY-HZg1Uwpc");
}
i get following screenshot
In this screenshot, I could not see "fullScreen" button.
In your case, you have to first add FrameLayout in your XML file. After that
you have to implement two methods onShowCustomView and onHideCustomView of WebChromeClient as shown below:
FrameLayout customViewContainer = findViewById(R.id.customViewContainer);
webView.setWebChromeClient(new WebChromeClient() {
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
super.onShowCustomView(view,callback);
webView.setVisibility(View.GONE);
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.addView(view);
}
public void onHideCustomView () {
super.onHideCustomView();
webView.setVisibility(View.VISIBLE);
customViewContainer.setVisibility(View.GONE);
}
});
I should custom WebChromeClient#onShowCustomView and #onHideCustomView, following code will show fullscreen button:
public class TestWebViewPlayYoutube extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_web_view_play_youtube);
WebView w = (WebView) findViewById(R.id.w);
w.setWebChromeClient(new CrmClient());
w.setWebViewClient(new WebViewClient());
w.getSettings().setJavaScriptEnabled(true);
w.getSettings().setMediaPlaybackRequiresUserGesture(false);
w.loadUrl("https://www.youtube.com/watch?v=gY-HZg1Uwpc&autoplay=1");
}
class CrmClient extends WebChromeClient {
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
}
#Override
public void onHideCustomView() {
super.onHideCustomView();
}
}
}
update
i improve my code, it will show fullscreen and hide fullscreen for html5 (for ex youtube video player), to use this code, you must make sure main/assets/test.mp4 exist
public class TestFullscreen2 extends Activity {
WebView w;
RelativeLayout container;
float dp;
static FrameLayout fullscreenV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_fullscreen2);
dp = getDp(this);
container = (RelativeLayout) findViewById(R.id.container);
w = (WebView) findViewById(R.id.w);
if (fullscreenV != null && fullscreenV.getParent() == null) {
w.setVisibility(GONE);
container.addView(fullscreenV);
}
w.setWebChromeClient(new CrmClient(this));
w.setWebViewClient(new WebViewClient());
w.getSettings().setJavaScriptEnabled(true);
w.getSettings().setMediaPlaybackRequiresUserGesture(false);
w.loadDataWithBaseURL("file:///android_asset/", "<video width='100%' height='auto' src='test.mp4' controls autoplay/>", "text/html", "utf-8", null);
}
#Override
protected void onDestroy() {
super.onDestroy();
w = null;
}
class CrmClient extends WebChromeClient {
Activity a;
public CrmClient(Activity a) {
this.a = a;
}
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
fullscreenV = (FrameLayout) view;
a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
#Override
public void onHideCustomView() {
super.onHideCustomView();
fullscreenV = null;
a.startActivity(new Intent(a, TestFullscreen2.class) {{
setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}});
}
}
}
Update
I have updated my question to hide confidential code.
If still there is some confusion pls msg me in comments.
Question
I have written an custom Webview for playing youtube video embedded in my website to go full Screen.
But its still not Working..
.
kindly Help
public class MainActivity extends Activity implements OnClickListener {
final Context context = this;
private WebView webView;
private ImageButton btnrefresh;
private TextView txtrefresh;
private myWebChromeClient mWebChromeClient;
private Menu optionsMenu;
private WebChromeClient.CustomViewCallback customViewCallback;
private View mCustomView;
private FrameLayout customViewContainer;
#SuppressWarnings("deprecation")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Tushar
customViewContainer = (FrameLayout) findViewById(R.id.customViewContainer);
//Tushar
//define button
btnrefresh = (ImageButton) findViewById(R.id.imageButton1);
btnrefresh.setOnClickListener(this);
btnrefresh.setVisibility(View.GONE);
//define textView
txtrefresh = (TextView)findViewById((R.id.textView1));
txtrefresh.setVisibility(View.GONE);
if(isConnected())
{
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setRenderPriority(RenderPriority.HIGH);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setSaveFormData(true);
// webView.getSettings().setPluginState(PluginState.ON);
webView.setWebViewClient(new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("mailto:")) {
sendEmail(url.substring(7));
return true;
}
return false;
}
});
initWebView(webView);
webView.loadUrl("http://Example.com/");
}
else
{
RelativeLayout rel = (RelativeLayout)findViewById(R.id.relativelayout1);
rel.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
refresh();
}
});
btnrefresh.setVisibility(View.VISIBLE);
txtrefresh.setVisibility(View.VISIBLE);
Toast.makeText(getBaseContext(), "No Internet Connection !!", Toast.LENGTH_SHORT).show();
}
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
#Override
protected void onPause() {
super.onPause(); //To change body of overridden methods use File | Settings | File Templates.
webView.onPause();
}
#Override
protected void onResume() {
super.onResume(); //To change body of overridden methods use File | Settings | File Templates.
webView.onResume();
}
#Override
protected void onStop() {
super.onStop(); //To change body of overridden methods use File | Settings | File Templates.
if (inCustomView()) {
hideCustomView();
}
}
//tushar
class myWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
#Override
public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
onShowCustomView(view, callback); //To change body of overridden methods use File | Settings | File Templates.
}
#Override
public void onShowCustomView(View view,CustomViewCallback callback) {
// if a view already exists then immediately terminate the new one
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
webView.setVisibility(View.GONE);
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.addView(view);
customViewCallback = callback;
}
#Override
public View getVideoLoadingProgressView() {
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
mVideoProgressView = inflater.inflate(R.layout.video_progress, null);
}
return mVideoProgressView;
}
#Override
public void onHideCustomView() {
super.onHideCustomView(); //To change body of overridden methods use File | Settings | File Templates.
if (mCustomView == null)
return;
webView.setVisibility(View.VISIBLE);
customViewContainer.setVisibility(View.GONE);
// Hide the custom view.
mCustomView.setVisibility(View.GONE);
// Remove the custom view from its container.
customViewContainer.removeView(mCustomView);
customViewCallback.onCustomViewHidden();
mCustomView = null;
}
}
To achieve this you should:
Implement showCustomView and hideCustomView methods of WebChromeClient.
Set android:hardwareAccelerated="true" to your MainActivity in AndroidManifest.xml.
There are two classes that inherit the WebChromeClient in your code (myWebChromeClient and MyWebChromeClient). The first implements showCustomView and hideCustomView methods and it seems fully working with full-screen video. The second one don't. But you (accidentally?) set the second as WebChromeClient to your WebView.
To fix this just change the line
webView.setWebChromeClient(new MyWebChromeClient());
to
mWebChromeClient = new myWebChromeClient();
webView.setWebChromeClient(mWebChromeClient);
in your initWebView() method.
UPD:
To lock orientation on portrait in normal (not full-screen) mode add following line into onHideCustomView() method:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
To let the system decide the best orientation in full-screen mode add this line to onShowCustomView(View view, CustomViewCallback callback) method:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Working Perfectly.
Tested on Android 9.0 version
This is the final thing worked
Set The setWebChromeClient on webview
mWebView.setWebChromeClient(new MyChrome());
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
public class MainActivity extends AppCompatActivity {
WebView mWebView;
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webView);
mWebView.setWebViewClient(new WebViewClient());
mWebView.setWebChromeClient(new MyChrome()); // here
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAppCacheEnabled(true);
if (savedInstanceState == null) {
mWebView.loadUrl("https://www.youtube.com/");
}
}
private class MyChrome extends WebChromeClient {
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
protected FrameLayout mFullscreenContainer;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
MyChrome() {}
public Bitmap getDefaultVideoPoster()
{
if (mCustomView == null) {
return null;
}
return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
}
public void onHideCustomView()
{
((FrameLayout)getWindow().getDecorView()).removeView(this.mCustomView);
this.mCustomView = null;
getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
setRequestedOrientation(this.mOriginalOrientation);
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
}
public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
{
if (this.mCustomView != null)
{
onHideCustomView();
return;
}
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
this.mOriginalOrientation = getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;
((FrameLayout)getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
getWindow().getDecorView().setSystemUiVisibility(3846 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mWebView.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mWebView.restoreState(savedInstanceState);
}
}
In AndroidManifest.xml
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize" />
Solution Original Source
Referring to the code Sheharyar Ejaz has posted, I replaced 2 lines to improve the result.
THe first line I replaced is in onShowCustomView, so when user click Youtube fullscreen option of a video, the video will automatically expand into lansdcape fullscreen like native Youtube.
To achieve that, I replaced this line :
this.mOriginalOrientation = getRequestedOrientation();
with this line :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
The second line I replaced is in onHideCustomView, so when user minimize the fullscreen video, it will revert into the phone's present layout.
What I do is I replaced this line :
this.mOriginalOrientation = getRequestedOrientation();
with this line :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
But, quite different with the suggestion by erakitin, I did not set android:hardwareAccelerated="true" to my MainActivity/WebView Activity in AndroidManifest.xml.
I am succeeded to play streamed Youtube video from HTML5 content in Webview in Android but now problem is that video plays only first time. After that VideoView only goes to end of the video file.
I tried clearing cache as suggested here but no luck.
What could be the possible solution for this problem?
Please try following code to run Video, this has been using some suggestions given on stackoverflow.com
WebView webView = (WebView) findViewById(R.id.product_details_webview);
WebSettings webSettings = webView.getSettings();
webSettings.setPluginState(WebSettings.PluginState.ON);
webSettings.setJavaScriptEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webView.setWebChromeClient(new chromeClient());
webView.setWebViewClient(new WebViewClient(){
});
webView.loadUrl(url);
public class chromeClient extends WebChromeClient implements OnCompletionListener,
OnErrorListener{
private WebView wv;
private VideoView mVideoView;
private LinearLayout mContentView;
private FrameLayout mCustomViewContainer;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER = new
FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (view instanceof FrameLayout) {
wv = (WebView)findViewById(R.id.product_details_webview);
mCustomViewContainer = (FrameLayout) view;
mCustomViewCallback = callback;
mContentView = (LinearLayout)findViewById(R.id.linearlayout1);
if (mCustomViewContainer.getFocusedChild() instanceof VideoView) {
mVideoView = (VideoView) mCustomViewContainer.getFocusedChild();
// frame.removeView(video);
mContentView.setVisibility(View.GONE);
mCustomViewContainer.setVisibility(View.VISIBLE);
setContentView(mCustomViewContainer);
mVideoView.setOnCompletionListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.start();
}
}
}
public void onHideCustomView() {
if (mVideoView == null){
return;
}else{
// Hide the custom view.
mVideoView.setVisibility(View.GONE);
// Remove the custom view from its container.
mCustomViewContainer.removeView(mVideoView);
mVideoView = null;
mCustomViewContainer.setVisibility(View.GONE);
mCustomViewCallback.onCustomViewHidden();
// Show the content view.
mContentView.setVisibility(View.VISIBLE);
}
}
public void onCompletion(MediaPlayer mp) {
mp.stop();
mCustomViewContainer.setVisibility(View.GONE);
onHideCustomView();
setContentView(mContentView);
}
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
setContentView(mContentView);
return true;
}
}
Add in your chrome client :
#Override public void onPrepared(MediaPlayer mp) {
customViewCallback.onCustomViewHidden();
}
where customViewCallback = callback;
You got a video working inside a WebView with HTML5? Congrats! I failed trying to do that :(
To fix my issue I ended up leaving a place holder in the HTML and handling the video from native code using the MediaPlayer class.
I had this problem as well.
I had to add a seek(0).
Seems like the next video played from exactly where the last video ended.
So I had to go to the beginning of the video before playing.