Inject external JS file in Android WebView and call it - javascript

I am trying to inject my external JS file (contained in assets dir) into WebView and call it afterwards.
This is the code I use for injecting it:
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView.loadUrl("javascript: (function() { "
+ "var script=document.createElement('script');"
+ "script.type='text/javascript';script.src='file://android_asset/js_demo.js';"
+ "document.getElementsByTagName('head').item(0).appendChild(script);"
+ "})()");
webView.loadUrl("javascript: jsDemo()");
}
});
When I print the entire content of my WebView, I can see that script tag with src='file://android_asset/js_demo.js' is indeed inserted, but calling function jsDemo does nothing.
NOTE: Function jsDemo is contained in js_demo.js and does nothing clever, just changes some span's color. It work ok since I tested it in browser.
I am convinced I made mistake giving the path to the js file, but I am not sure how to change it in order to make it work. Any help will be appreciated.

Why not just read in the file and execute it directly via loadUrl("javascript:...)?

Here is how i ended up doing it. I used the Content:// protocol and set up a contentprovider to handle returning a file descriptor to the system
Here is my fileContentProvider:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
public class FileContentProvider extends ContentProvider {
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode) {
Log.d("FileContentProvider","fetching: " + uri);
ParcelFileDescriptor parcel = null;
String fileNameRequested = uri.getLastPathSegment();
String[] name=fileNameRequested.split("\\.");
String prefix=name[0];
String suffix=name[1];
// String path = getContext().getFilesDir().getAbsolutePath() + "/" + uri.getPath();
//String path=file:///android_asset/"+Consts.FILE_JAVASCRIPT+"
/*check if this is a javascript file*/
if(suffix.equalsIgnoreCase("js")){
InputStream is = null;
try {
is = getContext().getAssets().open("www/"+Consts.FILE_JAVASCRIPT);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
File file = stream2file(is,prefix,suffix);
try {
parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
} catch (FileNotFoundException e) {
Log.e("FileContentProvider", "uri " + uri.toString(), e);
}
}
return parcel;
}
/*converts an inputstream to a temp file*/
public File stream2file (InputStream in,String prefix,String suffix) {
File tempFile = null;
try {
tempFile = File.createTempFile(prefix, suffix);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tempFile.deleteOnExit();
FileOutputStream out = null;
try {
out = new FileOutputStream(tempFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
IOUtils.copy(in, out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tempFile;
}
#Override
public boolean onCreate() {
return true;
}
#Override
public int delete(Uri uri, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
#Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("Not supported by this provider");
}
#Override
public Uri insert(Uri uri, ContentValues contentvalues) {
throw new UnsupportedOperationException("Not supported by this provider");
}
#Override
public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
throw new UnsupportedOperationException("Not supported by this provider");
}
#Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
}
in the manifest i defined the provider:
<provider android:name="com.example.mypackage.FileContentProvider"
android:authorities="com.example.fileprovider"
/>
Here is the javascript i inject into the webview:
webView.loadUrl("javascript:(function() { "
+ "var script=document.createElement('script'); "
+ " script.setAttribute('type','text/javascript'); "
+ " script.setAttribute('src', 'content://com.example.fileprovider/myjavascriptfile.js'); "
/* + " script.onload = function(){ "
+ " test(); "
+ " }; "
*/ + "document.body.appendChild(script); "
+ "})();");
and here is the myjavascriptfile.js (as an example):
function changeBackground(color) {
document.body.style.backgroundColor = color;
}

Thanks for the feedback guys. I tried most of the suggestions and here's how I got to inject a .js file for every webpage webkit loads.
Read a local js file to a string.
Append that string to script.text after creating a document element with type text/javascript
Call javascript: (function() { <programmatically formatted string dynamically creating webpage script element >})()" inside an overridden webview onPageFinished.
Verified working on Android 4.0.3–4.0.4 Ice Cream Sandwich (API level 15)

You need three slashes after "file:"

Related

How set to show the name of music and it on my phone

I have a question now i try create a music app on my phone. now I can see my file song But the name shown in the app is the file address instead. and if i want to play the file music in this app. What code do I need to add for get the name of music and play it on my phone? thank a lot
#Override
public void onClick(View view) {
mp.pause();
play.setEnabled(true);
stop.setEnabled(true);
pause.setEnabled(false);
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mp != null) {
mp.stop();
try {
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//mp.release()
play.setEnabled(true);
play.setEnabled(true);
stop.setEnabled(false);
}
}
});
send.setOnClickListener(new View.OnClickListener() {
//List<Intent> intentShareList = new ArrayList<Intent>();
#Override
public void onClick( View view ) {
msgs = msg.getText().toString();
System.out.print("msgs " + msgs);
// make line message
Log.d(TAG, "Txt " + msgs);
Intent shareIntent = new Intent();
String userId = "";
String sendText = "line://ti/p/~" + userId;
//shareIntent = null;
try {
shareIntent = Intent.parseUri(sendText,
Intent.URI_INTENT_SCHEME);
} catch (URISyntaxException e) {
e.printStackTrace();
}
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_TEXT,msgs);
shareIntent.setType("text/plain");
startActivity(shareIntent);
}
});
}
AND
public class Songs {
//private
private String songTitle;
private String songAddress;
public Songs(String title){
//songID = id;
songTitle = title;
}
/*public long getSongID(){
return songId;
*/
public String getSongTitle(){
return songTitle;
}
}
now I can see my file song But the name shown in the app is the file
address instead
I think you are referring to the "Path" of the file, for example:
/storage/emulated/0/song.mp3 (Unix style path)
C:\Songs\song.mp3 (Window style path)
If you would like to parse (find out) the name of the file, use the following code:
String filePath = "/storage/emulated/0/song.mp3";
File f = new File(filePath);
String fileName = f.getName();
// fileName == "song.mp3"
In your case:
public class Songs {
private String title; // renamed from "songTitle"
private String path; // renamed from "songAddress"
private String fileName; // the file name of the song
public Songs(String title, String path){
this.title = title;
this.path = path;
File file = new File(path);
String fileName = f.getName();
this.fileName = fileName;
}
public String getTitle(){
return title;
}
public String getPath(){
return path;
}
public String getFileName(){
return fileName;
}
}

Can't load images and videos inside Webview with JavaScript enabled

I'm loading data from website to a webview in my application.And i need to make the video plays inside the webview.my problem is when i don't use setJavaScriptAsEnable the images and the video loads just fine but i can't play the video inside the webview it gives me the following error
An error occurred. try watching this video on youtube or enabe JavaScript.
however when i use setJavaScriptAsEnable(true) all the images and videos inside the webview disappears like the following image.
here's my code for the webview
void setupWebView(final WebView webView) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
} else {
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
}
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
// add padding to the html page
webView.loadUrl("javascript:(function(){ document.body.style.paddingBottom = '30px'})();");
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String request) {
if (request.contains("http")) {// TODO: 14/08/2017 use regs
Log.d("url", request);
new CheckIfImageAsyncTask().execute(request);
return true;
}
return false;
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
if (url.contains("http")) {
new CheckIfImageAsyncTask().execute(url);
return true;
}
return false;
}
});
// settings
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setPluginState(WebSettings.PluginState.ON_DEMAND);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
String data = "<div>" + post.getContent() + " </div>";
webView.loadDataWithBaseURL("file:///android_asset/", getHtmlData(data), "text/html", "utf-8", null);
}
private class CheckIfImageAsyncTask extends AsyncTask<String, Void, Boolean> {
private String url;
#Override
protected Boolean doInBackground(String... strings) {
url = strings[0];
URLConnection connection = null;
boolean isImage = false;
try {
connection = new URL(url).openConnection();
String contentType = connection.getHeaderField("Content-Type");
isImage = contentType.startsWith("image/");
} catch (IOException e) {
e.printStackTrace();
}
return isImage;
}
#Override
protected void onPostExecute(Boolean isImage) {
try {
if (isImage) {
Intent intent = new Intent(PostDetailsActivity.this, FullScreenImageActivity.class);
intent.putExtra("coverImage", url);
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
} catch (Exception e) {
Log.e("Error", e.getMessage());
FirebaseCrash.report(new Exception(e.getMessage()));
}
}
}
i searched a lot and i can't figure it out. any help will be appreciated. thanks in advance.

Unable to send value from Javascript file to Android Activity

I am trying to pass a value from a custom javascript file I have included after loading a URL in a webview.
I have checked this reference but it doesn't work when I am loading a website apart from a local index.html file.
Here is my activity code where I have created the Javacript Interface:
public class MainActivity extends AppCompatActivity {
public static String URL = "https://www.ornativa.com";
private WebView mWebView;
private RelativeLayout mLoader;
private Toolbar mToolbar;
JSInterface JSI = new JSInterface(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createWebView();
}
#SuppressLint("SetJavaScriptEnabled")
public void createWebView(){
mWebView = (WebView)findViewById(
R.id.webView);
mToolbar = (Toolbar)findViewById(R.id.toolbar);
mToolbar.setTitle(getResources().getString(R.string.app_name)+" | "+getResources().getString(R.string.app_name_hindi));
mLoader = (RelativeLayout) findViewById(R.id.loader);
// Add javascript support to the webview
mWebView.getSettings().setJavaScriptEnabled(true);
// Enable pinch zoom controls on webview
mWebView.getSettings().setBuiltInZoomControls(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
// Add a WebViewClient
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
// Inject CSS when page is done loading
injectCSS();
injectJS();
super.onPageFinished(view, url);
mLoader.setVisibility(View.GONE);
}
});
mWebView.addJavascriptInterface(JSI, "Android");
// Load a webpage
mWebView.loadUrl(URL);
}
public void injectCSS(){
try {
InputStream inputStream = getAssets().open("styles.css");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
mWebView.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var style = document.createElement('style');" +
"style.type = 'text/css';" +
// Tell the browser to BASE64-decode the string into your script !!!
"style.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(style)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
private void injectJS() {
try {
InputStream inputStream = getAssets().open("script.js");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
mWebView.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)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(R.string.app_name);
builder.setMessage("Do you really want to Exit?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//if user pressed "yes", then he is allowed to exit from application
finish();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//if user select "No", just cancel this dialog and continue with app
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
public class JSInterface {
private Context mContext;
public JSInterface(Context c) {
mContext = c;
}
#JavascriptInterface
public void showToast(String message) {
Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
}
}
}
And this is my script.js file:
document.getElementById("aadhaarNo").type= 'tel';
var myElem = document.getElementById('actionMessages');
Android.showToast("Hello World!");
if (myElem === null) {
console.log('does not exist');
}
else{
if (myElem.classList.contains('success')){
console.log('success');
}
}
I am trying to call the function from the script file to send the value to the Toast but the Toast doesn't appear.
Change "Context" to "Activity" in class JSInterface. Check the below edited code..
public class JSInterface {
private Activity mContext;
public JSInterface(Activity c) {
mContext = c;
}
#JavascriptInterface
public void showToast(String message) {
Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
}
}

Inject javascript file to my site with webview in android

I want to inject javascript file to my site. My site is a simple html page that is on server. I have injected css file. (with Manish's help)
So I can manage my simple html site with CSS now. But I want to manage it with javascript too. My jscript.js file is in asset folder. I want to have full access of javascript on my site. (Remember that, it is MY site) . please write the correct codes for me. Thankx.
Here is my MainActivity.java file:
package com.example.z5070.myapplication;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Base64;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.InputStream;
public class MainActivity extends ActionBarActivity {
WebView webView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = new WebView(this);
setContentView(webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
injectCSS();
super.onPageFinished(view, url);
}
});
webView.loadUrl("http://www.example.com/");
}
private void injectCSS() {
try {
InputStream inputStream = getAssets().open("style.css");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
webView.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var style = document.createElement('style');" +
"style.type = 'text/css';" +
"style.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(style)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Add a new method to inject javascript file.
private void injectJS() {
try {
InputStream inputStream = getAssets().open("jscript.js");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
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)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}
Call both methods: injectCSS() and injectJS() after page finishes loading.
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
injectCSS();
injectJS();
super.onPageFinished(view, url);
}
});
I hope this solves the problem.
Be wary of how onload events defined inside inject js file would behave.
Some refinements to previous answer. Suppose we use Cyrillic words. Result would be a garbaged strings. It's not good. With code below you can use non-english chars in content. Just add additional url-encoding/decoding to your code and you good to go. Reedited version below.
private void injectJS() {
try {
InputStream inputStream = getAssets().open("jscript.js");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
// preserve non-english letters
String uriEncoded = URLEncoder.encode(new String(buffer, "UTF-8"), "UTF-8").replace("+", "%20");
String encoded = Base64.encodeToString(uriEncoded.getBytes(), Base64.NO_WRAP);
webView.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var script = document.createElement('script');" +
"script.type = 'text/javascript';" +
// don't forget to use decodeURIComponent after base64 decoding
"script.innerHTML = decodeURIComponent(window.atob('" + encoded + "'));" +
"parent.appendChild(script)" +
"})()");
} catch (Exception e) {
e.printStackTrace();
}
}

LoadUrl Javascript not loading at all

could someone please help me. I'm having difficulty with LoadUrl and javascript.
The code below seems to work sorta ok (killing the app then trying again makes it work) on my old HTC running 2.3 however, my Xperia Z which runs the latest Android gets stuck on "Attempting to get Comments".
The section of code it is sticking on is InjectJavaScript() wherein this fails to LoadUrl (I know this as onPageFinished is never called). The strange thing is statistics part of the code works fine and its identical.
Sorry its pretty messy code...
#SuppressLint("SetJavaScriptEnabled")
public class MyIceland extends SherlockActivity {
private static class FetchMyIceland extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
setDialog("Checking Farera for WoW Data....",2);
switch(FETCHFROMMYICELAND){
case 0: //contact Farera for information.
Log.i("IcePlan","Farera Check/Empathica Front Page Retrieval...");
MyIceland.url = MainActivity.BASE_URL+"android_get.php?action=myiceland&store="+MainActivity.STORE;
try {
String Result = HTTPGET();
if(Result.startsWith("no")){ //content for today?
setDialog("No WoW Data Available for Today\nAbout to contact Empathica.com....",2);
activity.runOnUiThread(new Runnable(){#Override public void run() {MyIceland.FetchFromEmpathica("http://www.iceland.empathica.com/LogonIceland.aspx");;}}); }
else{FETCHFROMMYICELAND = 100;} //we do have content...
} catch (IOException e1) {Log.i("IcePlan",e1.toString());} catch (Exception e1) {Log.i("IcePlan",e1.toString());
} //we have data for today, so download and sort it.
break;
case 1: //get comments
setDialog("About to Contact Empathica.com for Comments....",2);
try {Thread.sleep(1000);} catch (InterruptedException e) {Log.i("IcePlan",e.toString());}
activity.runOnUiThread(new Runnable(){#Override public void run() {MyIceland.FetchFromEmpathica("http://v2.empathica.com/Reporting1/ClientReporting/LiveDataReporting.aspx?RID=1&PID=Comments&TID=1a");}});
break;
case 2: //POST data
setDialog("Posting all data to Farera.com \n So we don't have to do this again today....",2);
List<NameValuePair> params = new ArrayList<NameValuePair>();
try {params.add(new BasicNameValuePair("frontpage", URLEncoder.encode(FRONTPAGE, "utf-8")));} catch (UnsupportedEncodingException e) {Log.e("IcePlan",e.toString());}
try {params.add(new BasicNameValuePair("comments", URLEncoder.encode(COMMENTS, "utf-8")));} catch (UnsupportedEncodingException e) {Log.e("IcePlan",e.toString());}
MyIceland.url = MainActivity.BASE_URL+"android_get.php?action=store_myiceland&store="+MainActivity.STORE;
String POST = HTTPPOST(params);
if(POST != null){FETCHFROMMYICELAND = 100; }
break;
}
return null;
}
#Override
protected void onPreExecute(){super.onPreExecute();}
#Override
protected void onPostExecute(Void arg0){
if(FETCHFROMMYICELAND == 100) new MyIceland.DisplayMyIceland().execute();
}
}
//------------------------------------------------------
//-----------------------------------------------------
//-----------------------------------------------------
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_iceland);
ctx = getApplicationContext();
activity = this;
//webView2 = (WebView) findViewById(R.id.myIwebview2_widget);
/********************************************************/
/****************** ABS ********************************/
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().show();
// This is a workaround for http://b.android.com/15340 from
// http://stackoverflow.com/a/5852198/132047
BitmapDrawable bg = (BitmapDrawable) getResources().getDrawable(
R.drawable.bg_striped);
bg.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
getSupportActionBar().setBackgroundDrawable(bg);
BitmapDrawable bgSplit = (BitmapDrawable) getResources().getDrawable(
R.drawable.bg_striped);
bgSplit.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
getSupportActionBar().setSplitBackgroundDrawable(bgSplit);
/************************************************************/
try {
ov_e = (TextView) findViewById(R.id.overall_exp_tx);
ov_r= (TextView) findViewById(R.id.overall_rank_tx);
s_e= (TextView) findViewById(R.id.storeexp_tx);
st_e= (TextView) findViewById(R.id.staffexp_tx);
t_e= (TextView) findViewById(R.id.tillexp_tx);
res= (TextView) findViewById(R.id.responses_tx);
res_r= (TextView) findViewById(R.id.resp_rank_tx);
MyIceland.list = (ListView) findViewById(R.id.wow_lv); // set list
MyIceland.adapter = new SeparatedListAdapter(ctx, false); // initialise adapter
//authenticate
CookieSyncManager.createInstance(this);
SetUp(); //Set up webView
setDialog("Loading MyIceland data...\n Please be Patient...",0);
new FetchMyIceland().execute(); //get data
} catch (Exception e) {
// TODO Auto-generated catch block
Log.i("IcePlan",e.toString());
}
}
private static String HTTPPOST(List<NameValuePair> params){
String Resp = null;
try {
HttpClient client = new DefaultHttpClient();
String postURL = MyIceland.url;
HttpPost post = new HttpPost(postURL);
//List<NameValuePair> params = new ArrayList<NameValuePair>();
//params.add(new BasicNameValuePair("user", "kris"));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params,HTTP.UTF_8);
post.setEntity(ent);
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
if (resEntity != null) {
Resp = "not null";
}
} catch (Exception e) {
Log.e("IcePlan HTTPPOST",e.toString());
}
return Resp;
}
private static String HTTPGET() throws Exception, IOException{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
str.append(line);
}
in.close();
Log.i("IcePlan",str.toString());
return str.toString();
}
private void SetUp(){
webView = (WebView) findViewById(R.id.myIwebview_widget); //load custom webview
webView.clearView(); //clear view of browser
webView.clearFormData(); //clear form data
webView.setNetworkAvailable(MainActivity.isOnline(ctx)); //set network state
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setPluginsEnabled(false); //no flash
webView.getSettings().setJavaScriptEnabled(true); // enable javascript
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webView.getSettings().setSavePassword(false); //don't show password dialog
webView.setVerticalScrollBarEnabled(false); //no scrolling!
webView.setHorizontalScrollBarEnabled(false); //no scrolling!
webView.getSettings().setLoadsImagesAutomatically(false); // NO Images
webView.getSettings().setSaveFormData(false); //Don't save form data
//webView.setVisibility(View.VISIBLE);
return;
}
private static void FetchFromEmpathica(String EmpathURL){
/*****************************************************
* setWebViewClient to load pages
*****************************************************
*****************************************************
*/
webView.loadUrl(EmpathURL);
MyIceland.page = 0;
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Log.i("IcePlan",url);
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.i("IcePlan","Starting...");
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url) {
Log.i("IcePlan","Loaded...");
switch(FETCHFROMMYICELAND){
case 0:
if(MyIceland.page == 0){
MyIceland.page=1;
try {Thread.sleep(500);}catch (InterruptedException e) {Log.e("IcePlan",e.toString());}
view.loadUrl("javascript: {" +
"document.forms[0].elements['userNameBox'].value = 'xxx.xxxxx';" +
"setTimeout(function(){document.forms[0].elements['passwordBox'].value = 'xxxxxxx';},300);" +
"setTimeout(function(){document.forms[0].elements['loginButton'].click();},300); };");
}else if(MyIceland.page == 1){
MyIceland.page=2;
try {Thread.sleep(1000);}catch (InterruptedException e) {Log.e("IcePlan",e.toString());}
String oAuthUrl=("v2.empathica.com");
if(url.indexOf(oAuthUrl) > -1)
{
Log.i("Contains","Auth URL");
InjectJavaScript(view);
}else{view.loadUrl("javascript:{};");}
}else if (MyIceland.page ==2){
if(MyIceland.FRONTPAGE == null){
Log.i("IcePlan","Inject");
InjectJavaScript(view);
}else{MyIceland.page=3;}
}
break;
case 1:
if(MyIceland.COMMENTS == null){
Log.i("IcePlan","Inject Comments");
InjectJavaScript(view);
}else{MyIceland.page=100;} //else end
break;
}
super.onPageFinished(view, url);
}
});
return;
}
}
private static void setDialog(final String msg, final int dothis){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
switch(dothis){
case 0: //set up and show
if (dlg == null) {
dlg = new ProgressDialog(activity);
dlg.setTitle("Loading...");
dlg.setMessage(msg);
dlg.setCancelable(activity.isFinishing());
dlg.show();
}
break;
case 1: //remove and reset to null
if (dlg.isShowing() || dlg!=null) {
dlg.hide();
dlg = null;
}
break;
case 2:
if (dlg.isShowing() || dlg!=null) {
dlg.setMessage(msg);
}
}
}});
return;
}
/*********************************************************
* HACK - Inject Javascript to get the HTML we want!
*********************************************************/
private static void InjectJavaScript(WebView view){
switch(FETCHFROMMYICELAND){
case 0: //get front page
setDialog("Attempting to get Statistics...",2);
view.loadUrl("javascript:{" +
"var element = document.getElementById('ReportDivFPRank');"+
"if (typeof(element) != 'undefined' && element != null)"+
"{" +
"var e=document.getElementById(\"ReportDivFPCR\");"+
"var content=e.innerHTML;"+
"window.HTMLOUT.processHTML(content);"+// exists.
"}" +
"};");
break;
case 1: //get comments
setDialog("Attempting to get Comments....",2);
view.loadUrl("javascript:{" +
"var element = document.getElementById('AddNPSDetails');"+
"if (typeof(element) != 'undefined' && element != null)"+
"{" +
"var e=document.getElementById(\"_ctl1_ReportDiv\");"+
"var content=e.innerHTML;"+
"window.HTMLOUT.processHTML(content);"+// exists.
"}" +
"};");
break;
}
return;
}
/*********************************************************
* Class injected into Empathica website to get HTML
* Continues onto our controlling AsyncTask
* #author Vince
*
********************************************************/
public static class MyJavaScriptInterface
{
public void processHTML(final String html)
{
setDialog("Caught RAW data....",2);
if(html != ""){
//MyIceland.webView2.loadDataWithBaseURL("notreal/", html, "text/htm", "utf-8",null);
if(FETCHFROMMYICELAND == 0){ setDialog("Retrieved Area Statistics....",2); MyIceland.FRONTPAGE = html;}
else if(FETCHFROMMYICELAND == 1){ setDialog("Retrieved Area Comments....",2); MyIceland.COMMENTS = html;}
FETCHFROMMYICELAND++;
new MyIceland.FetchMyIceland().execute();
}
return;
}
}
}
I see that FetchFromEmpathica is going to be called again when you load the second page, and you set again a new WebViewClient() to the webview, put it on the setup() method so it is going to be called once.
Make sure that your Xperia is 4.1.2, nonetheless look what is mentioned on
Reference: JavascriptInterface methods in WebViews must now be annotated
Beginning in Android 4.2, you will now have to explicitly annotate public methods with #JavascriptInterface in order to make them accessible from hosted JavaScript. Note that this also only takes effect only if you have set your app's minSdkVersion or targetSdkVersion to 17 or higher.
Add it and import android.webkit.JavascriptInterface
So the code will be up-to-date to last versions.
#JavascriptInterface
public void processHTML(final String html)
{
//code
}

Categories