I have a webview on my 4.1.2 Android, which I load with
public class FullscreenActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
final WebView wv=(WebView)findViewById(R.id.webView1);
String sHTML="Webviewtest";
for(int i=0;i<500;i++){
sHTML=sHTML+"Line " + i + "<br>";
}
wv.loadData(sHTML, "text/html", null);
wv.setScrollY(1500);
wv.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
wv.setScrollY(500);
Toast.makeText(getApplicationContext(), "Done! " + wv.getScrollY(), Toast.LENGTH_SHORT).show();
}
});
}
}
I like the webview to scroll down to a specific postition, but it stays on the top.
any ideas ?
When setScrollY() with a button it works, but I like to set the position after laoding the HTML. I also tried to do it with a Handler, which I call in onPageFinished. This does not work too.
I created a very simple Android project, where everyone can download and test:
https://drive.google.com/folderview?id=0B7yz_IQ1CMblUU03cGd5cEotTVE&usp=sharing
This time it is not android's fault,it has provided us with another approach.
try:
public void onPageFinished(WebView v, String url) {
v.evaluateJavascript("window.scrollTo(0,"+expectedPos/a.getResources().getDisplayMetrics().density+");", null);
super.onPageFinished(v, url);
}
My Solution. I don't like it, but it works. All this mess because of the android framework, that doesn't work like expected...
I added a AsyncTask:
private class Waitforloaded extends AsyncTask<String, Integer, Long> {
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Long result) {
}
#Override
protected Long doInBackground(String... params) {
// TODO Auto-generated method stub
boolean bgo=true;
int iTries=0;
while(bgo){
iTries=iTries+1;
if(iTries>20 || wv.getContentHeight()>0){
bgo=false;
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
wv.setScrollY(1500);
return null;
}
}
Then calling it in
wv.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Waitforloaded wfl=new Waitforloaded();
wfl.execute("");
}
WebView.setScrollY works for me only when I give it some delay with a timer after the WebView is loaded:
webView.loadData(sHtmlTemplate, "text/html", "utf-8");
Timer t = new Timer(false);
t.schedule(new TimerTask() {
#Override
public void run() {
MainActivity.mainactivity.runOnUiThread(new Runnable() {
public void run() {
webView.setScrollY(500);
}
});
}
}, 300); // 300 ms delay before scrolling
Related
Earlier webbview works fine but today strange problem came that showing this when I load url..
Code for this is....
public class ShowSubjectListItemsInWebView extends ActionBarActivity {
private WebView webView;
private Toolbar mToolbar;
private SessionManager sessionManager;
private Security security;
private ProgressDialog dialog;
private String url;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_subject_list_items_in_web_view);
this.initViews();
this.setToolBar();
try{
sessionManager = new SessionManager(getApplicationContext());
security = new Security(getApplicationContext());
boolean isInternetPresent = security.isConnectingToInternet();
if (isInternetPresent) {
//I hide url due to some privacy contents
loadWebView(url);
} else {
showCustomToast("Internet not available \n Please check your internet connection");
}
}catch(Exception ex){
showCustomToast("Something went wrong");
}
}
//initializes all views
private void initViews() {
webView = (WebView) findViewById(R.id.filesWebView);
}
//show Url in WebView
public class myWebClient extends WebViewClient {
#JavascriptInterface
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
dialog = new ProgressDialog(ShowSubjectListItemsInWebView.this);
dialog.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
dialog.setCancelable(false);
dialog.setMessage(Constant.KEY_PLEASE_WAIT);
dialog.show();
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
public void loadWebView(String decryptedUrl) {
webView.setWebViewClient(new myWebClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setDomStorageEnabled(true);
webView.setVisibility(View.VISIBLE);
webView.loadUrl(decryptedUrl);
}
}
I tested this code on lenovo, moto and MI devices...works fine but when I choose nexus device for loading url it gives the above stated error.
First time webview loads, thread is called after x seconds, When clicking on a url inside the webview why is the thread not fired again. The thread in pageStart is loading only once, but it needs to fire everytime a url is clicked inside webview.
public class MyAppWebViewClient extends WebViewClient {
public MyAppWebViewClient() {
timeout = true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
showProgressDialog();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(Constants.DELAYMILIS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(timeout) {
// do what you want
systemUtils.dismissProgressDialog(activity.getResources().getString(R.string.app_name),activity.getResources().getString(R.string.chargement_message_dialog));
}
}
}).start();
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
super.shouldOverrideUrlLoading(view, url);
webContainer.loadUrl(url);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(Constants.DELAYMILIS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(timeout) {
// do what you want
systemUtils.dismissProgressDialog(activity.getResources().getString(R.string.app_name),activity.getResources().getString(R.string.chargement_message_dialog));
}
}
}).start();
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
timeout = false;
cancelCurrentLoading();
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
Log.e("ERROR_LOADING_CODE: ", description);
timeout = false;
noConnection();
}
}
/*
Mehtod to dismiss loading spinner
*/
public static void cancelCurrentLoading() {
showWebView();
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
/*
Method to show and hide webview
*/
public static void showWebView(){
webContainer.setVisibility(View.VISIBLE);
}
public static void hideWebView(){
webContainer.setVisibility(View.GONE);
}
To create a webView recently I was using webViewClient. mWebView.setWebViewClient(new WebViewClient());
But I need to implement a progress bar. When user clicks a link, this progress bar will be visible. After page complete, progressbar will be hidden and webView will be visible. Regarding to this and this, So I added a WebChromeClient. But it loads first URL, but when I click a button inside my web page, a dialog opens and asks to open URL with which application.
I read that I should override shouldOverrideUrlLoading() method. but I get an error that "shouldOverrideUrlLoading" can't be overriden for WebChromeClient.
I would be happy if you can give an example that has progressbar and webView, also opens new URLs inside the same webView.
public class WebActivity extends Activity {
WebView mWebView;
ProgressBar mProgress;
Context mContext;
ProgressBar mProgressBar;
#Override
public void onCreate(Bundle savedInstanceState) {
this.mContext = getApplicationContext();
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebChromeClient(new myWebChromeClient());
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setUserAgentString("myApp");
mProgressBar = (ProgressBar) findViewById(R.id.webProgressBar);
mProgressBar.setMax(100);
}
public class myWebChromeClient extends WebChromeClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
#Override
public void onProgressChanged(WebView view, int newProgress) {
//WebActivity.this.setValue(newProgress);
super.onProgressChanged(view, newProgress);
}
}
}
try with this code
webView = (WebView) view.findViewById(R.id.transcationwebview);
progressdialog = ProgressDialog.show(mContext, "",
mContext.getString(R.string.please_wait));
progressdialog.setCancelable(true);
progressdialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
webView.stopLoading();
// webView.clearView();
}
});
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new MyChromeClient());
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
if (progressdialog != null && progressdialog.isShowing()) {
progressdialog.dismiss();
} else {
}
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
});
webView.loadUrl("url");
webView.getSettings().setBuiltInZoomControls(true);
public class MyChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int newProgress) {
try {
if (progressdialog.isShowing()) {
progressdialog.setMessage(getString(R.string.loading)
+ newProgress + " %");
} else {
/*
* webView.stopLoading(); webView.clearView();
*/
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
you can extends WebViewClient instead of WebChromeClient and override the onPageStarted to show the ProgressBar and dismiss it in onPageReceived
I made some changes in the Activity.
use WebViewClient instead of WebChromeClient
and also use ProgressDialog instead of ProgressBar
public class WebActivity extends Activity {
WebView mWebView;
Context mContext;
ProgressDialog mProgressBar;
private static final int DIALOG2_KEY = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
this.mContext = getApplicationContext();
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebViewClient(new MyWebChromeClient());
mWebView.getSettings().setBuiltInZoomControls(true);
showDialog(DIALOG2_KEY); }
#Override
protected void onResume() {
super.onResume();
mWebView.loadUrl("YOUR_URL");
}
private final class MyWebChromeClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
dismissDialog(DIALOG2_KEY);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("file")) {
return false;
} else{
view.loadUrl(url);
return true;
}
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id)
{
case DIALOG2_KEY:
{
mProgressBar.setMessage("Loading");
mProgressBar.setIndeterminate(true);
mProgressBar.setCancelable(false);
return mProgressBar;
}
}
return null;
}
}
Hope this help you
I am getting error as The Web Page at file:///#/android_asset/webpage.htm could not be loaded as: Is a directory. in the emulator.
but my code is webView.loadUrl("file:///android_asset/webpage.htm");
First the page renders perfectly but again after rendering refreshes the page and does not get loaded and will get the web page not available.
If we could carefully see the url that has been given out by the android emulator there are two extra characters before android_asset.
Below is the code.
public class Catalog extends Activity {
final Activity activity = this;
WebView webView;
ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);//used for rendering percentage of loading
setContentView(R.layout.catalog_layout);
try{
webView = (WebView) findViewById(R.id.browserwebview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
activity.setTitle("Loading...");
activity.setProgressBarVisibility(true);
activity.setProgress(progress * 100);
if(progress == 100){
activity.setTitle(R.string.app_name);
}
}
});
webView.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
Toast.makeText(activity, "Oh no!"+ description, Toast.LENGTH_SHORT).show();
}
#Override
public void onLoadResource (WebView view, String url) {
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
return true;
}
});
webView.loadUrl("file:/android_asset/web/webpage.html");
}
catch (Exception e) {
e.printStackTrace();
}
ImageButton btnBack = (ImageButton)this.findViewById(R.id.buttonBackCatalog);
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(webView.canGoBack()){
webView.goBack();
}else{
Intent myIntent = new Intent(view.getContext(), FCFActivity.class);`
`startActivityForResult(myIntent, 0);
}
}
});
/*
* Actions for footer Buttons
*
*/
ImageButton buttonFooterMainHome = (ImageButton)findViewById(R.id.footerMainBtnHome);
buttonFooterMainHome.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), FCFActivity.class);
startActivityForResult(myIntent, 0);
}
});
LinearLayout homeLinearLayout=(LinearLayout)this.findViewById(R.id.footerLayoutHome);
homeLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), FCFActivity.class);
startActivityForResult(myIntent, 0);
}
});
}
#Override
public void onConfigurationChanged(final Configuration newConfig)
{
// Ignore orientation change to keep activity from restarting
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
}
}
}
Looking forward to your reply.
thanks.
Oh this caused me headaches, and they changed how it worked for one of the android versions, but can't remember which. Here is what I do:
webView.loadUrl("file:/android_asset/webpage.html");
and if your static webpage has images you use this link:
file:///android_asset/yourimage.png
Edit try this: https://stackoverflow.com/a/8737547/969325, clean project and check if asset file is at path.
- `You are using only htm use html`
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new myWebClient());
webview.loadurl();
and
public class myWebClient extends WebViewClient
{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
}
I'm working with PhoneGap and Android and have my .html and js files on an external server. When I use the following code, the app loads my external .html files and everything works fine:
this.setIntegerProperty("loadUrlTimeoutValue", 60000);
this.loadUrl("http://www.myserver.com");
However, when work via a WebView I can't seem to set the loadURLTimeoutValue for a WebView:
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
webView = (WebView) findViewById(R.id.webview);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.loadUrl("http://www.myserver.com");
}
This doesn't work. How can I set the timeout value on the WebView?
This is a workaround to simulate the described behavior. You can use a WebViewClient, and override the onPageStarted method:
public class MyWebViewClient extends WebViewClient {
boolean timeout;
public MyWebViewClient() {
timeout = true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
new Thread(new Runnable() {
#Override
public void run() {
timeout = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(timeout) {
// do what you want
}
}
}).start();
}
#Override
public void onPageFinished(WebView view, String url) {
timeout = false;
}
}
If timeout, you can load, for example, an error page...
To add the WebViewClient to you WebView, just do this:
webView.setWebViewClient(new MyWebViewClient());
I used this to set a time out for my WebView:
public class MyWebViewClient extends WebViewClient {
boolean timeout = true;
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Runnable run = new Runnable() {
public void run() {
if(timeout) {
// do what you want
showAlert("Connection Timed out", "Whoops! Something went wrong. Please try again later.");
}
}
};
Handler myHandler = new Handler(Looper.myLooper());
myHandler.postDelayed(run, 5000);
}
#Override
public void onPageFinished(WebView view, String url) {
timeout = false;
}
}
The correct way to change the default timeout is using tag <preference /> in config.xml file, for example:
<preference name="loglevel" value="DEBUG" />
<preference name="loadUrlTimeoutValue" value="60000" />
<preference name="errorUrl" value="file:///android_asset/www/connection_error.html" />
For more preference options, refer to Android Configuration.
If you extend CordovaWebView, which you should in order to get the phonegap API, you can just use the following:
this.getIntent().putExtra("loadUrlTimeoutValue", 60000);
Internally, CordovaWebView implements a timeout mechanism similar to the ones proposed in the previous post (default timeout = 2000).
Mind that this is not a documented interface, so it might break in the future.
WebView mWebView = findViewById(R.id.web_view);
mWebView.setWebViewClient(new WebViewClient() {
private volatile boolean timeout;
private volatile String timeoutOnPageStartedURL;
private volatile String timeoutCurrentURL;
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
timeout = true;
timeoutOnPageStartedURL = url;
timeoutCurrentURL = view.getUrl();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (timeout) {
view.post(new Runnable() {
#Override
public void run() {
String currentURL = view.getUrl();
if ((timeoutOnPageStartedURL.hashCode() == currentURL.hashCode()) ||
(timeoutCurrentURL.hashCode() == currentURL.hashCode())) {
// do what you want with UI
}
}
});
}
}
}).start();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
timeout = false;
}
});
The use of Thread class bothers me calling the WebView from the run function will lead to an exception as the WebView is created and used in another thread.
I would perform this with an AsyncTask.
In this example, I use an AsyncTask to load an error file into the WebView if the timeout was reached. If the page loads properly I cancel the AsyncTask.
The onPostExecute runs in the UI thread so there is no thread safety problem to interact with the WebView:
private class CustomWebViewClient extends WebViewClient {
boolean mPageLoaded;
final int mTimeoutLength = 20000;
WebView mView;
TimeoutCheck timeoutCheckTask;
public CustomWebViewClient()
{
super();
mPageLoaded = false;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
mView = view;
timeoutCheckTask = new TimeoutCheck();
timeoutCheckTask.execute(null,null);
}
public void onPageFinished(WebView view, String url) {
mPageLoaded = true;
timeoutCheckTask.cancel(true);
}
private class TimeoutCheck extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
long count = 0;
while (count < mTimeoutLength)
{
try
{
Thread.sleep( 1000 );
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
// Escape early if cancel() is called
if (isCancelled()) break;
count += 1000;
}
return null;
}
protected void onPostExecute(Void result) {
if(!mPageLoaded) {
mbLoadedErrFile = true;
//load error file into the webview
mView.loadUrl("file:///android_asset/url_err_timeout.html");
}
}
}