Back to project page webview-gm.
The source code is released under:
Apache License
If you think the Android project webview-gm listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright 2012 Werner Bayer//from w w w . j a va2 s .c o m * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.pardus.android.webview.gm.store.ui; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.content.Context; import android.graphics.Bitmap; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.webkit.DownloadListener; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import at.pardus.android.webview.gm.model.Script; import at.pardus.android.webview.gm.run.WebViewClientGm; import at.pardus.android.webview.gm.run.WebViewGm; import at.pardus.android.webview.gm.store.ScriptStore; import at.pardus.android.webview.gm.util.UnicodeReader; import at.pardus.webview.gm.R; /** * Combines an address field and a WebView intercepting .user.js file downloads * to add them to a provided script store. */ public class ScriptBrowser { private static final String TAG = ScriptBrowser.class.getName(); protected ScriptManagerActivity activity; protected ScriptStore scriptStore; private String startUrl; protected View browser; protected WebViewGm webView; protected EditText addressField; /** * Installs a new script. * * Not to be run on the UI thread. * * @param url * the location of the script to install */ protected void installScript(String url) { makeToastOnUiThread(activity.getString(R.string.starting_download_of) + " " + url, Toast.LENGTH_SHORT); String scriptStr = downloadScript(url); if (scriptStr == null) { makeToastOnUiThread( activity.getString(R.string.error_downloading_from) + " " + url, Toast.LENGTH_LONG); return; } Script script = Script.parse(scriptStr, url); if (script == null) { Log.d(TAG, "Error parsing script:\n" + scriptStr); makeToastOnUiThread(activity.getString(R.string.error_parsing_at) + " " + url, Toast.LENGTH_LONG); return; } scriptStore.add(script); makeToastOnUiThread(activity.getString(R.string.added_new_script) + " " + script, Toast.LENGTH_LONG); } /** * Downloads and returns a file as String. * * Not to be run on the UI thread. * * @param url * the http address to get * @return the downloaded file as String or null on any error */ protected String downloadScript(String url) { StringBuilder out = new StringBuilder(); Reader in = null; HttpURLConnection con = null; char[] buffer = new char[4096]; try { URL u = new URL(url); con = (HttpURLConnection) u.openConnection(); con.setReadTimeout(5000); con.setRequestMethod("GET"); con.setUseCaches(false); con.connect(); InputStream is = con.getInputStream(); in = new UnicodeReader(is, con.getContentEncoding()); int bytesRead = 0; while ((bytesRead = in.read(buffer, 0, 4096)) != -1) { if (bytesRead > 0) { out.append(buffer, 0, bytesRead); } } } catch (MalformedURLException e) { Log.e(TAG, Log.getStackTraceString(e)); return null; } catch (IOException e) { Log.e(TAG, Log.getStackTraceString(e)); try { InputStream errorStream = con.getErrorStream(); if (errorStream != null) { in = new UnicodeReader(errorStream, null); int bytesRead = 0; StringBuilder errorStr = new StringBuilder(); while ((bytesRead = in.read(buffer, 0, 4096)) != -1) { if (bytesRead > 0) { errorStr.append(buffer, 0, bytesRead); } } in.close(); Log.e(TAG, errorStr.toString()); } } catch (Exception e1) { } return null; } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); return null; } finally { try { in.close(); } catch (Exception e) { } if (con != null) { con.disconnect(); } } return out.toString(); } /** * Inflates the WebViewGm from XML and sets up its WebViewClient, * WebChromeClient and DownloadListener. Also inflates and sets up the * address field EditText component. */ private void init() { browser = (View) activity.getLayoutInflater().inflate( R.layout.script_browser, null); webView = (WebViewGm) browser.findViewById(R.id.webView); webView.setScriptStore(scriptStore); addressField = (EditText) browser.findViewById(R.id.addressField); addressField .setOnEditorActionListener(new EditText.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_GO || actionId == EditorInfo.IME_NULL) { webView.loadUrl(v.getText().toString()); webView.requestFocus(); ((InputMethodManager) activity .getSystemService(Context.INPUT_METHOD_SERVICE)) .hideSoftInputFromWindow( v.getWindowToken(), 0); return true; } return false; } }); webView.setWebViewClient(new ScriptBrowserWebViewClientGm(scriptStore, webView.getWebViewClient().getJsBridgeName(), webView .getWebViewClient().getSecret(), this)); webView.setDownloadListener(new ScriptBrowserDownloadListener(this)); webView.setWebChromeClient(new ScriptBrowserWebChromeClient(this)); loadUrl(startUrl); } /** * Load the given URL. * * @param url * the address to load */ public void loadUrl(String url) { addressField.setText(url); webView.loadUrl(url); } /** * @return the browser's last loaded address */ public String getUrl() { return webView.getUrl(); } /** * Constructor. * * @param activity * the application's activity * @param scriptStore * the database to use */ public ScriptBrowser(ScriptManagerActivity activity, ScriptStore scriptStore, String startUrl) { this.activity = activity; this.scriptStore = scriptStore; this.startUrl = startUrl; init(); } /** * Goes back to the previous browser page. * * @return false if the browser history is empty */ public boolean back() { if (webView.canGoBack()) { webView.goBack(); return true; } return false; } /** * Stops any browser activity. */ public void pause() { webView.stopLoading(); webView.pauseTimers(); } /** * Resumes browser timers. */ public void resume() { webView.resumeTimers(); } /** * @return the browser view group */ public View getBrowser() { return browser; } /** * @return the webView */ public WebViewGm getWebView() { return webView; } /** * Displays a message created on the UI thread. * * @param message * the message to show * @param length * the duration (use Toast.LENGTH_ constants) */ private void makeToastOnUiThread(final String message, final int length) { activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, message, length).show(); } }); } /** * WebViewClientGm component for the ScriptBrowser intercepting .user.js * downloads. */ public static class ScriptBrowserWebViewClientGm extends WebViewClientGm { private ScriptBrowser scriptBrowser; /** * Constructor. * * @param scriptStore * the script database to query for scripts to run when a * page starts/finishes loading * @param jsBridgeName * the variable name to access the webview GM functions from * javascript code * @param secret * a random string that is added to calls of the GM API * @param scriptBrowser * reference to its enclosing ScriptBrowser */ public ScriptBrowserWebViewClientGm(ScriptStore scriptStore, String jsBridgeName, String secret, ScriptBrowser scriptBrowser) { super(scriptStore, jsBridgeName, secret); this.scriptBrowser = scriptBrowser; } @Override public boolean shouldOverrideUrlLoading(WebView view, final String url) { if (url.endsWith(".user.js")) { // TODO ask before installing new script new Thread() { public void run() { scriptBrowser.installScript(url); } }.start(); return true; } return false; } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { scriptBrowser.addressField.setText(url); super.onPageStarted(view, url, favicon); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Toast.makeText( scriptBrowser.activity, scriptBrowser.activity .getString(R.string.error_while_loading) + " " + failingUrl + ": " + errorCode + " " + description, Toast.LENGTH_LONG).show(); } } /** * DownloadListener for .user.js downloads. */ public static class ScriptBrowserDownloadListener implements DownloadListener { private ScriptBrowser scriptBrowser; /** * Constructor. * * @param scriptBrowser * reference to its enclosing ScriptBrowser */ public ScriptBrowserDownloadListener(ScriptBrowser scriptBrowser) { this.scriptBrowser = scriptBrowser; } @Override public void onDownloadStart(final String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { if (url.endsWith(".user.js")) { // TODO ask before installing new script new Thread() { public void run() { scriptBrowser.installScript(url); } }.start(); } } } /** * WebChromeClient setting the app's title and progress. */ public static class ScriptBrowserWebChromeClient extends WebChromeClient { private ScriptBrowser scriptBrowser; /** * Constructor. * * @param scriptBrowser * reference to its enclosing ScriptBrowser */ public ScriptBrowserWebChromeClient(ScriptBrowser scriptBrowser) { this.scriptBrowser = scriptBrowser; } @Override public void onProgressChanged(WebView view, int progress) { scriptBrowser.activity.setProgress(progress * 100); } @Override public void onReceivedTitle(WebView view, String title) { scriptBrowser.activity.setTitle(title); } } }