Have blank white screen when using Webview. I see many topics with this problem but no one solved. So i tried another one...
It's my first time project on android.
Ok i optimised my code but its still show me gray screen on emulator and white screen on device. Someine help me.
public class Video extends Activity{
private WebView video;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoview);
video = (WebView)findViewById(R.id.webshow);
video.getSettings().setJavaScriptEnabled(true);
video.getSettings().setPluginState(WebSettings.PluginState.ON);
/*video.getSettings().setPluginsEnabled(true);*/
String html = "http://www.twitch.tv/wingsofdeath";
final String temp = "<div class=\"live_site_player_container swf_container js-player-container\" data-channel=\"wingsofdeath\" id=\"standard_holder\" style=\"width: 100%; height: 211px;\">\n" +
"<object type=\"application/x-shockwave-flash\" name=\"live_site_player_flash\" data=\"http://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf\" width=\"100%\" height=\"100%\" id=\"live_site_player_flash\" style=\"visibility: visible;\"><param name=\"allowNetworking\" value=\"all\"><param name=\"allowFullScreen\" value=\"true\"><param name=\"allowScriptAccess\" value=\"always\"><param name=\"wmode\" value=\"opaque\"><param name=\"flashvars\" value=\"team=solomid&auto_play=true&hide_chat=true&publisherGuard=null&publisherTimezoneOffset=420&channel=wingsofdeath&hostname=www.twitch.tv&loadCallback=Twitch.player._twitchPlayerLoaded&backgroundImageUrl=http://static-cdn.jtvnw.net/jtv_user_pictures/anonymous_monkey-320x240.jpg\"></object>\n" +
"</div>";
video.loadDataWithBaseURL (html, temp, "application/x-shockwave-flash", "UTF-8","");
}}
what i doing wrong?? Someone talk about using webchromeclent. pls explain me about that.
(Manifest and another.. is right)
Thank you.
Can i get info about "file///android_asset" its local html file as i stand... how i can load my data there if it's possible??
Related
I have a math equation as a text WebView that I need to fit the entire screen no matter its dimensions.. my first intuition of doing this is simply shrinking the text whenever it gets out of bounds so that it remains constrained, however, I can't find any functions or methods to actually MEASURE the content of that webview, I've tried:
webview.getMeasuredHeight, webview.getHeight
but the issue with them is that they are constantly affixed on the size of the webview widget, not on the content, so I moved to:
webview.getContentHeight
which seemed to work, the problem is it works only after the text is "loaded", so it doesn't get the right answer at first, even if it's called in onPageFinished.
My questions are:
1) Is there a way to know the content size of the TEXTUAL html webview?? I would even appreciate knowing the scroll bar length that would indicate size.
2) Is there a listener function that would enable me to run code from the moment the text actually loaded? The webview declaration looks something like this:
webView = (WebView) findViewById(R.id.webView);
js = "<html><head>"
+ "<link rel='stylesheet' href='file:///android_asset/mathscribe/jqmath-0.4.3.css'>"
+ "<script src='file:///android_asset/mathscribe/jquery-1.4.3.min.js'></script>"
+ "<script src='file:///android_asset/mathscribe/jqmath-etc-0.4.3.min.js'></script>"
+ "</head><body>"
+ "<script>var s = '$$" + functext + "$$';M.parseMath(s);document.write(s);</script> </body>";
webView.loadDataWithBaseURL("", js, "text/html", "UTF-8", "");
The text does not load instantly, so the code relating to it is usually flawed.
3) Is there a webview.getContentWidth or something of the like?
EDIT:
This code may help you in fitting your wepage to webview.
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setUseWideViewPort(true);
You have to calculate the scale so that content fits on the screen.
private int getScale()
{
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
Double val = new Double(width)/new Double(Your_webpage_width);
val = val * 100d;
return val.intValue();
}
Then use
WebView web = new WebView(this);
web.setPadding(0, 0, 0, 0);
web.setInitialScale(getScale());
2) To run something after webview has completely loaded,just implement WebViewClient and extend onPageFinished() as follows:
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
I load a Google Docs' iframe into a webview in Android, this iframe is loading a PPT file (Power Point file) from a external server of Google Docs. This is the Android Code:
public class Test_iframeActivity extends Activity {
private WebView webView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView) findViewById(R.id.wv);
webView.getSettings().setJavaScriptEnabled(true);
//String customHtml = "<html><body><h1>Hello, WebView</h1></body></html>";
String customHtml = "<iframe src='http://docs.google.com/viewer?url=http://www.iasted.org/conferences/formatting/presentations-tips.ppt&embedded=true' width='100%' height='100%' style='border: none;'></iframe>";
webView.loadData(customHtml, "text/html", "UTF-8");
}}
My question is... why I can see the iframe works fine into Android 4.0 but I can't see it into Android 2.1 to 2.3? (I don't know if in Android 3 works).
SOLVED!
The mistake was the ASCII encoding... I shoud replace the #, %, /, and ? by other characters, please check http://developer.android.com/reference/android/webkit/WebView.html#loadData(java.lang.String, java.lang.String, java.lang.String) for more information.
I've managed to get a vimeo video to load and play, using the following. However the autoplay=1 as indicated in the vimeo oembed docs doesn't auto play on load. Anyone found a way to auto play (also need to catch event when video finishes)
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
// how plugin is enabled change in API 8
if (Build.VERSION.SDK_INT < 8) {
mWebView.getSettings().setPluginsEnabled(true);
} else {
mWebView.getSettings().setPluginState(PluginState.ON);
}
mWebView.loadUrl("http://player.vimeo.com/video/24577973?player_id=player&autoplay=1&title=0&byline=0&portrait=0&api=1&maxheight=480&maxwidth=800");
This answer is specific to Vimeo only. After about a dozen failed attempts, here's what I have working. Perhaps it will help somebody else. A thousand apologies to the original authors of other SO answers. I have 'borrowed' a number of patterns below -- just thought it would be handy to have all this in one place, and do not claim them for my own code.
First, I have not found a way around embedding the Vimeo player (i.e. you can't get at the mp4 stream directly -- at least not easily or reliably -- I'm pretty sure that's deliberate). Second, Vimeo offers a javascript library to instrument their player, and using it is fairly unavoidable. Beware, it requires message passing, which is a newer browser feature. This is documented on their API page. Third, as is documented elsewhere on SO, you need to be very careful to wait for parts of the stack to become ready, and to not gun-jump. Fourth, the Vimeo player includes a particularly unhelpful background image meant to convey that the plugin is missing or broken (a little frame of film, common icon for this). What is really means is that your javascript has bombed out someplace, and nothing at all is running. If you see the little bit of film on a blank screen, check your javascript.
Step 1. Set up a WebView. You have this correct above. For reference, here is what I used.
mWebView = new WebView((Context) this);
mWebView.setLayoutParams(new LayoutParams(windowWidth, windowHeight));
mWebView.getSettings().setJavaScriptEnabled(true);
// Watch the sdk level here, < 12 requires 'false
// Wanted to force HTML5/264/mp4, you may want flash
// where still available
mWebView.getSettings().setPluginState(PluginState.OFF);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setUserAgentString("Android Mozilla/5.0 AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
wcc = new MyWebChromeClient();
mWebView.setWebChromeClient(wcc);
wvc = new MyWebViewClient();
mWebView.setWebViewClient(wvc);
Step 2. You need the WebChromeClient if you want video to work on the WebView. That's documented here: http://developer.android.com/reference/android/webkit/WebView.html (See HTML Video Support).
Again, for reference here is what I used.
private class MyWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int progress) {
if(progress == 100) {
// Your page is loaded, but not visible,
// add whatever navigation elements you plan to use here.
// N.B. these are JAVA, not JS nav elements
}
}
#Override
public boolean onConsoleMessage(ConsoleMessage cm) {
// I like to watch in the console. And, since it was
// a very convenient way to monitor the javascript, I
// use it for that too. Purists will object, no doubt
if(cm.message().equalsIgnoreCase("EVENT -- Finish")) {
Log.i(TAG, "---> Finishing . . .");
// Depart the activity
finish();
} else {
Log.d(TAG, " **Console ["+cm.sourceId()+"] ("+cm.lineNumber()+") ["+cm.message()+"]");
}
return(true);
}
#Override
public View getVideoLoadingProgressView() {
// Something entertaining while the bytes arrive
Log.i(TAG, " -------------> Loading Progress . . . ");
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return(inflater.inflate(R.layout.loading_video, null));
}
#Override
public void onShowCustomView(View v, WebChromeClient.CustomViewCallback callback) {
// With great sadness, I report that this never fires.
// Neither does the 'hide'.
}
#Override
public void onHideCustomView() {
}
}
The WebViewClient looks like this:
private class MyWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String injection = injectPageMonitor();
if(injection != null) {
Log.d(TAG, " ---------------> Page Loaded . . .");
Log.d(TAG, " Injecting . . . ["+injection+"]");
view.loadUrl(injection);
}
}
}
Step 3. You need to build a tiny bit of Javascript to fire the player. I used this:
public String injectPageMonitor() {
return( "javascript:" +
"jQuery(document).ready( function() { " +
"console.log(' === Page Ready ===> Setting up');" +
"console.log(' ==== Sending PLAY Command ===');" +
"var froogaloop = $f('froog');" +
"setTimeout(function() { froogaloop.api('play'); }, 3000);" +
"});");
}
Quick explanation . . . I use jQuery in my JS, that's coming below. That's only for convenience, you can do straight JS if you want to lighten the load. Note that after everything else is ready, the script waits another 3 seconds to actually fire. In my weaker moments, I imagine that the kind folks at Vimeo have a broken "ready" callback. 3 Seconds seems to do it.
Step 4. You need some HTML and JavaScript on the page. I put it in a text file inside the resources (raw/vimeo_frame.html). The file looks like this:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript">jQuery.noConflict();</script>
<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script>
<script type="text/javascript">
jQuery(document).ready( function() {
var showing_player = false;
var froogaloop = $f('froog');
console.log(' === Page Ready ===> Setting up');
jQuery('.froog_container_class').hide();
jQuery('.console').css('height', '100%');
froogaloop.addEvent('ready', function() {
console.log('==== PLAYER READY ====> Setting Play Callback');
froogaloop.addEvent('play', function(data) {
console.log('EVENT -- Play');
/* No idea why, but if the player isn't displayed, it goes
straight to 'pause'. Probably a feature. So I give it 4x4px
to do it's thing during setup */
jQuery('.froog_container_class').show();
jQuery('.froog_container_class').css('height', '4px');
jQuery('.froog_container_class').css('width', '4px');
jQuery('.froog_container_class').css('overflow', 'hidden');
});
/* I don't want to reveal the video until it is actually
playing. So I do that here */
var showingPlayer = false;
froogaloop.addEvent('playProgress', function(data) {
if(!showingPlayer && data.percent > 0) {
showingPlayer = true;
jQuery('.froog_container_class').show();
jQuery('.froog_container_class').css('height', '_windowHeight');
jQuery('.froog_container_class').css('width', '_windowWidth');
/* Most tablets I tested aren't quick enough to make this work
but one can still hope */
jQuery('#loading').fadeOut('slow');
}
});
});
});
</script>
</head>
<body>
<style>
body {
background-image: url('http://<SomethingEntertainingToWatch>.png');
background-size: contain;
}
.mask {
float: left;
height: _windowHeight;
width: _windowWidth;
z-index: 100;
background: transparent;
display: inline;
position: absolute;
top: 0;
left: 0;
}
.froog_container_class {
position: absolute;
height: _windowHeight;
width: _windowWidth;
left: 0;
top: 0;
display: inline;
z-index: 1;
}
#froog {
display: inline;
height: _windowHeight;
width: _windowWidth;
postion: absolute;
top: 0;
left: 0;
}
</style>
<div id="loading" class="loading"><h1>Loading</h1><img class="loading_anim" src="http://foo.bar.com/assets/global/loading.gif"/>
</div>
<!-- Completely optional, I put a div in front of the player to block controls -->
<div id="mask" class="mask">
</div>
<div id="froog_container" class="froog_container_class">
<iframe id="froog" src="_targetUrl?api=1&title=0&byline=0&portrait=0&player_id=froog" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
</iframe>
</div>
</body>
</html>
And I load this html file like so:
public String genMainHTML() {
String code = null;
try {
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.vimeo_frame);
byte[] b = new byte[in_s.available()];
in_s.read(b);
code = new String(b);
} catch (Exception e) {
e.printStackTrace();
}
if(code != null) {
code = code.replaceAll("_windowHeight", "" + windowHeight + "px");
code = code.replaceAll("_windowWidth", "" + windowWidth + "px");
code = code.replaceAll("_targetUrl", targetUrl);
return(code);
} else {
return(null);
}
}
And inject it like so:
mDomain = "http://player.vimeo.com";
mWebView.requestFocus(View.FOCUS_DOWN);
targetUrl = extras.getString("URL");
String meat = genMainHTML();
mWebView.loadDataWithBaseURL(mDomain, meat, "text/html", "utf-8", null);
setContentView(mWebView);
Whew! When the WebView is ready, then the html and js go in, including the iframe with the Vimeo player. When the document is loaded, then we wait for the player to become ready. When the player is ready, we add some listeners. And 3 seconds later, we fire the api 'play' method.
Those apple-polishers in the audience may be wondering, for completeness, how does one stop the video? Two bits. First, when it ends, I stop it by watching the console output for a message I display. Thus:
public String injectPageFinisher() {
return( "javascript:" +
"jQuery(document).ready( function() { " +
"console.log(' === Page Ready ===> Tearing down');" +
"console.log(' ==== Sending PAUSE Command ===');" +
"var froogaloop = $f('froog');" +
"froogaloop.api('pause');" +
"jQuery('#froog_container').html('');" +
"});");
}
Which can be inserted like so:
#Override
public void onPause() {
super.onPause();
if(isFinishing()){
// Unload the page
if(mWebView != null) {
Log.i(TAG, " ------> Destroying WebView");
mWebView.destroy();
}
}
finish();
}
The second bit is where the video completes its little self. Thus, in the vimeo_frame.html above, just after the 'play' callback, I put:
froogaloop.addEvent('finish', function(data) {
console.log('EVENT -- Finish');
});
And in the Activity, I put a bit to watch for this -- see above in the onConsoleMessage override.
HOWEVER -- as of this writing, I still have not sorted one nagging problem. The MediaPlayer lives on after the WebView and all its progeny are gone. I'm sure this creates some problems, but I haven't identified them yet.
We've come across the same issue and it seems that Android WebView's (as well as those on iOS) are not programmed to allow auto-start of videos since it's possible that it would eat into someones data plan. You have to actually tap on it unless you want to take Google's WebView as a starting point and roll your own. It's not as easy as it sounds, we tried!
Here is the Simple Solution
Step1- Ensure you have minSdkVersion 17
Step2- mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false); Paste this line on the Vimeo Class.
I had the same issue, I think that you could use this one to make it happen:
public abstract void setMediaPlaybackRequiresUserGesture (boolean
require)
Added in API level 17 Sets whether the WebView requires a user gesture
to play media. The default is true.
Parameters require whether the WebView requires a user gesture to play
media
Hope to help you at least a little!
Hope it might help someone new to this.
Please try the below settings to your webview.
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAppCacheEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(false);
And append autoplay=1 with your Vimeo video url
webView.loadUrl(resLink + "?autoplay=1");
Here the resLink will look like "https://player.vimeo.com/video/your_video_id"
I want to display local html file on a WebView. (Android 2.3.3)
The HTML contains Hebrew text. I want the text to be justified, so in my css file I do the following:
body
{
text-align: justify; direction: rtl;
}
But for some reason the text end up being messed up:
And this is definitely not "justified" but more aligned to the left.
Any idea how can overcome this problem?
It's working perfectly fine on any other browser than the WebView. (Including WebKit based ones)
This code worked for me:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings settings = myWebView.getSettings();
settings.setDefaultTextEncodingName("utf-8");
String webtext = "שלום";
String summary = "<html lang=\"he\"><body><p dir=\"rtl\">" + webtext + "</p></body></html>";
myWebView.loadData(summary, "text/html", null);
}
In some web browsers, huge images are automatically resized to fit the screen.
Is it possible to do the same in an Android WebView?
The web page just contains the image, maybe adding some JavaScript could do the trick?
Anybody has already done this?
Note: I don't know the size of the image in advance.
Yes, it's possible. You can try setting the WebView Layout using the code below. It resizes all Images (Greater than the Device Screen Width) to the Screen Width. This works for both Orientations (Portrait and Landscape)
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
You can add extra margins/padding later to get the spacing right.
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
works but is deprecated. This is another solution without LayoutAlgorithm.SINGLE_COLUMN, using CSS:
#SuppressLint("NewApi")
private openWebView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING);
} else {
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
}
String data = "<div> your HTML content </div>";
webView.loadDataWithBaseURL("file:///android_asset/", getHtmlData(data), "text/html", "utf-8", null);
}
private String getHtmlData(String bodyHTML) {
String head = "<head><style>img{max-width: 100%; width:auto; height: auto;}</style></head>";
return "<html>" + head + "<body>" + bodyHTML + "</body></html>";
}
You could use this:
WebView webView = (WebView) findViewById(R.id.myWebView);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
Found this solution here:
How to set the initial zoom/width for a webview
You can have the browser resize the image for you to fit the maximum width of the screen:
<img src="huge-image.jpg" width="100%" />
Resizing its height to WebView's viewport is possible too:
<img src="huge-image.jpg" height="100%" />
However, resizing both width and height would result in a stretched image. To either resize the width or height depending of what side fits best you may consider a bit of JavaScript, like this:
<img src="huge-image.jpg" onload="resize(this);" />
<script type="text/javascript">
function resize(image)
{
var differenceHeight = document.body.clientHeight - image.clientHeight;
var differenceWidth = document.body.clientWidth - image.clientWidth;
if (differenceHeight < 0) differenceHeight = differenceHeight * -1;
if (differenceWidth < 0) differenceWidth = differenceWidth * -1;
if (differenceHeight > differenceWidth)
{
image.style['height'] = document.body.clientHeight + 'px';
}
else
{
image.style['width'] = document.body.clientWidth + 'px';
}
// Optional: remove margins or compensate for offset.
image.style['margin'] = 0;
document.body.style['margin'] = 0;
}
</script>
I faced the same problem and used Jsoup to help me out and add the required respected CSS. You can easily add attributes or CSS. I my case, I download from many sources various different HTML files, save them and then display them in a Webview. Here is how I parse the HTML before I save it to the database with Kotlin:
// Parse your HTML file or String with Jsoup
val doc = Jsoup.parse("<html>MY HTML STRING</html>")
// doc.select selects all tags in the the HTML document
doc.select("img").attr("width", "100%") // find all images and set with to 100%
doc.select("figure").attr("style", "width: 80%") // find all figures and set with to 80%
doc.select("iframe").attr("style", "width: 100%") // find all iframes and set with to 100%
// add more attributes or CSS to other HTML tags
val updatedHTMLString = doc.html()
// save to database or load it in your WebView
Add Jsoup to your project
Have fun!
If your WebView width is fill_parent then you can use this code:
Display display=getWindowManager().getDefaultDisplay();
int width=display.getWidth();
String data="<img src='http://example.com/image.jpg' style='width:"+width+"px' />";
webView.loadData(data, "text/html", "utf-8");
And zoom still working!
Same method if height is fill_parent.
My favorite's :
String data = "<html><body ><img id=\"resizeImage\" src=\""+PictureURL+"\" width=\"100%\" alt=\"\" align=\"middle\" /></body></html>";
webview.loadData(data, "text/html; charset=UTF-8", null);
You could send the size you want in the request parameters and let the server set the width/height in the img element for you.