I have an application which is basically a webview app. The website is based on angular js. Problem is the website takes a lot of time to start rendering. So I tried loading js from the asset folder. I used WebResourceResponse in my webviewclient
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if(url.startsWith("https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.min.js")){
return loadFromAssets(url, "angular.min.js", "application/javascript", "");
}
return null;
}
private WebResourceResponse loadFromAssets( String url,
String assetPath, String mimeType, String encoding){
AssetManager assetManager = this.activity.getAssets();
InputStream input = null;
try {
Log.d(LOG_TAG, "Loading from assets: " + assetPath);
input = assetManager.open("/" + assetPath);
WebResourceResponse response =
new WebResourceResponse(mimeType, encoding, input);
return response;
} catch (IOException e) {
Log.e("WEB-APP", "Error loading " + assetPath + " from assets: " +
e.getMessage(), e);
}
return null;
}
But I keep getting the filenotfound exception
07-26 17:19:21.662 20883-21536/com.exun.brinjal D/﹕ Loading from assets: angular.min.js
07-26 17:19:21.663 20883-21536/com.exun.brinjal E/WEB-APP﹕ Error loading angular.min.js from assets: /angular.min.js
java.io.FileNotFoundException: /angular.min.js
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:335)
at android.content.res.AssetManager.open(AssetManager.java:309)
at com.exun.brinjal.HelloWebViewClient.loadFromAssets(HelloWebViewClient.java:85)
at com.exun.brinjal.HelloWebViewClient.shouldInterceptRequest(HelloWebViewClient.java:37)
at com.android.webview.chromium.WebViewContentsClientAdapter.shouldInterceptRequest(WebViewContentsClientAdapter.java:283)
at com.android.org.chromium.android_webview.AwContents$IoThreadClientImpl.shouldInterceptRequest(AwContents.java:244)
at dalvik.system.NativeStart.run(Native Method)
07-26 17:19:21.666 20883-21536/com.exun.brinjal D/﹕ Loading from assets: angular-route.min.js
07-26 17:19:21.669 20883-21536/com.exun.brinjal E/WEB-APP﹕ Error loading angular-route.min.js from assets: /angular-route.min.js
java.io.FileNotFoundException: /angular-route.min.js
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:335)
at android.content.res.AssetManager.open(AssetManager.java:309)
at com.exun.brinjal.HelloWebViewClient.loadFromAssets(HelloWebViewClient.java:85)
at com.exun.brinjal.HelloWebViewClient.shouldInterceptRequest(HelloWebViewClient.java:40)
at com.android.webview.chromium.WebViewContentsClientAdapter.shouldInterceptRequest(WebViewContentsClientAdapter.java:283)
at com.android.org.chromium.android_webview.AwContents$IoThreadClientImpl.shouldInterceptRequest(AwContents.java:244)
at dalvik.system.NativeStart.run(Native Method)
I have tried to change assetManager.open("/" + assetPath); to file:/// and /assets but it doesn't help. All the js and css files I need are in the assets folder. I also want to know how will I get to load all those files also.
After some brainstorming, the answer was to remove "/" from assetManager.open("/" + assetPath);
So finally just put assetManager.open(assetPath); in the code and voila!
Related
I am injecting a javascript file to the WebView and that javascript file needs to load more files from the app assets folder.
i used to load the files from remote server, but now i need to load them locally.
I am getting "not allowed to load local resource".
is this even possible? i can't find any solution here or using google.
example:
...
webView.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
"script.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(script)" +
"})()");
this injects a "script.js" file into the webview.
inside the script.js file i want to inject css background image that is located inside the app assets folder. when im trying to access "file:///android_asset" i get the "not allowed to load local resource" error.
if you want load your local html page and resources to the web view you should use webView.loadDataWithBaseURL
public void loadLocalHtmlToWebView() throws IOException {
WebView mWebView = findViewById(R.id.my_webview);
File publicDir = new File(getCacheDir(), "public");
if (publicDir.exists() == false) {
publicDir.mkdirs();
String[] ls = getAssets().list("public");
for (int i = 0; i < ls.length; i++) {
InputStream inputStream = getAssets().open("public/" + ls[i]);
File outFileLocation = new File(publicDir, ls[i]);
outFileLocation.createNewFile();
Log.e("AMIR", "Wrinting to : " + outFileLocation.getPath());
FileOutputStream fileOutputStream = new FileOutputStream(outFileLocation);
byte[] buffer = new byte[1024];
while (inputStream.read(buffer) != -1) {
fileOutputStream.write(buffer);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
}
}
String indexHtml="";
BufferedReader bufferedReader=new BufferedReader(new FileReader(new File(publicDir,"index.html")));
String ln="";
while((ln=bufferedReader.readLine())!=null){
indexHtml+=ln;
}
bufferedReader.close();
Log.e("AMIR","Html : "+indexHtml);
String baseUrl = "file://" + publicDir.getPath() + "/";
mWebView.loadDataWithBaseURL(baseUrl, indexHtml, "text/html", "UTF-8", null);
}
Assets folder :
my index.html code :
<html>
<head>
<title>Hello</title>
<head>
<body>
Hello
<img src="./img.jpg"/>
<body>
</html>
and this is a good and well explained tutorial for webView :
http://tutorials.jenkov.com/android/android-web-apps-using-android-webview.html
I have trouble with load page File.html. I want to load my map in html but emulator not shows. I got error :
" [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///android_asset/HTMLPage1.html", source: data:text/html,chromewebdata (0) "
" I/chromium(11080): [INFO:CONSOLE(0)] "Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png", source: data:text/html,chromewebdata (0) "
On emulator page shows "WebPage not available"
Xaml file:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Mapaht"
x:Class="Mapaht.Mapahet">
<WebView
x:Name="webviewjava"></WebView>
</ContentPage>
Page file
public Mapahet()
{
InitializeComponent();
webviewjava.Source = "file:///android_asset/HTMLPage1.html";
}
I have trouble with load page File.html.
Doing the following steps and it works fine on my side :
XAML :
<WebView
x:Name="webviewjava"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
/>
Interface in your PCL :
public interface IBaseUrl
{
string Get();
}
Implement this interface in Android :
[assembly: Dependency(typeof(BaseUrl_Android))]
namespace FormsWebview.Droid
{
public class BaseUrl_Android : IBaseUrl
{
public string Get()
{
return "file:///android_asset/";
}
}
}
Load local resource file in Assets folder :
public MainPage()
{
InitializeComponent();
var baseUrl = DependencyService.Get<IBaseUrl>().Get();
string Url = $"{baseUrl}local.html";
webviewjava.Source = Url;
}
You are getting the WebView before setting the Content view so the wv is probably null.
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (Resource.Layout.webview);
WebView wv;
wv = FindViewById<WebView>(Resource.Id.webviewjava);
wv.LoadUrl("file:///android_asset/HTMLPage1.html");
}
}
You need to have permissions in AndroidMainfest.xml file that has access to the internet:
<uses-permission android:name="android.permission.INTERNET" />
How to scrape 'handlerbars.js' javascript template in htmlunit 2.21? I try to execute this, but this message shown:
'text/x-javascript-template' is not javascript.
and script does not execute. I execute command page.asXml().
Output text is nothing. Do you know dependency for execute javascript template in Htmlunit? Please help.
This Code
HtmlUnit Config
webClient = new WebClient(BrowserVersion.CHROME);
webClient.getBrowserVersion().setBrowserLanguage("ko-kr");
ConfirmHandler okHandler = new ConfirmHandler() {
#Override
public boolean handleConfirm(Page page, String message) {
logger.info("[Confirm] " + message);
return true;
}
};
AlertHandler alertHandler = new AlertHandler() {
#Override
public void handleAlert(Page page, String message) {
logger.info("[Alert] " + message);
}
};
webClient.setRefreshHandler(new ImmediateRefreshHandler());
webClient.getOptions().setGeolocationEnabled(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(script);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setTimeout(0);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.setConfirmHandler(okHandler);
webClient.setAlertHandler(alertHandler);
page move code
page = webClient.getPage("https://promotions.expediapartnercentral.com/promotions/manageroomandrate.html?htid=" + siteIdx);
webClient.waitForBackgroundJavaScript(1000);
page.asXml() repsonse is empty(script is not execute)
I am trying to load a page into webview. Normally, when i call
webview.loadUrl(url);
it works fine. The url has a javascript code that redirects the page. Here is the jacascript code:
<script type="text/javascript">
if (!document.cookie || document.cookie.indexOf('AVPDCAP=') == -1)
{ document.write('<scr'+'ipt src="http://some_link_here+Math.floor(89999999*Math.random()+10000000)+'&millis='+new Date().getTime()+'&referrer='+encodeURIComponent(document.location)+'" type="text/javascript"></scr'+'ipt>'); }
</script>
When i try to load that javascript code into my webview like the following:
String data = javascript_code_above;
topBannerWV.loadDataWithBaseURL("", data, "text/html", "UTF-8", null);
where data is this javascript code, it does not load the page. I also tried following:
topBannerWV.loadDataWithBaseURL("", data, "text/javascript", "UTF-8", null);
but this time that text is loaded into webview. Can anyone help me with this?
Thanks.
I am doing something like this and it works perfectly:
webView.loadUrl("file:///android_asset/html.html");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
try {
webView.loadUrl("javascript:init('" + some parameter + "')");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
script in html file is:
<script type="text/javascript">
function init(val){
document.getElementById('content').innerHTML=val;
}
window.addEventListener('load',function(){
console.log("Window Loader");
init();
});
</script>
I found the solution.
Instead of directly giving the string to webview to load, i first wrote it into a file and then gave that file to webview to load.
getContext().getApplicationContext().deleteFile("data.html");
Writer output = null;
File dir = getContext().getApplicationContext().getFilesDir();
File file = new File(dir.getAbsolutePath() + File.separator + "data.html");
file.createNewFile();
output = new BufferedWriter(new FileWriter(file));
output.write(WVdata);
output.close();
topBannerWV.loadUrl("file:///" + getContext().getApplicationContext().getFilesDir() + "/data.html");
I do not know why this happens, actually i do not change the data string, just put it into a file.
I am trying to load data into android webview using
webview.loadDataWithBaseURL("", htmlcontent, "text/html", null, "");
a method returns htmlContent from a StringBuilder which populates html data.
I have enabled javascript and set webChromeClient as follows
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient());
webview.addJavascriptInterface(new JSClass(), "Android");
my interface to javascript:
class JSClass {
public void getHTMLContent(String html)
{
Log.i(Global.TAG, "HTMLContentReceived: "+html);
}
}
and my javascript in html page:
<script type="text/javascript">
var ele = document.getElementsByClassName('test');
for(var i=0;i<ele.length;i++){
ele[i].onclick = function(){
window.Android.getHTMLContent(this.innerHTML);
}
}
</script>
but somehow the javascript is not returning any value.
It works fine with loadData(url) where url is a simple webpage in assets folder
Please help
Thanks in advance
You don't have any baseURL to use, since you're loading a dynamical generated HTML.
For this reason webview.loadData(htmlcontent, "text/html", null); should be more than enough.
Javascripts don't throw any exceptions in Java code. Remember that JS is not that type-safe/strict as Java code ... My way of doing is to put logs between sensitive Javascript calls to see if that line passes and to check values. Since you didn't provide the HTML, I would setup the WebChomeClient and override the onConsoleMessage:
webview.setWebChromeClient(new MyChromeClient());
private class MyChromeClient extends WebChromeClient {
#Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
String message = consoleMessage.message() + " -- line " + consoleMessage.lineNumber();
switch (consoleMessage.messageLevel()) {
case ERROR:
logErrorMessage(message);
break;
default:
logInfoMessage(message);
break;
}
return true;
}
private void logInfoMessage(String message) {
Log.i("JSTag", message);
}
private void logErrorMessage(String message) {
Log.e("JSTag", message);
}
}
From your JavaScript you would then call for example: console.log('check my value:' + (ele != null)). More info on this here.
Looking at your JavaScript code, I can't understand to what points this.innerHTML.