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();
}
}
Related
I need to get a link address from a webpage that is generated by javascript clicking on a button.
I click on the link in this way
webView.loadUrl("javascript:(function(){" +
"var All = document.getElementsByTagName('img');\n" +
"for (var i = 0; i < All.length; i++) {\n" +
"if (All[i].getAttribute('title') == 'Download') {\n" +
"var imgButton=All[i];\n" +
"e=document.createEvent('HTMLEvents');\n" +
"e.initEvent('click',true,true);\n" +
"imgButton.dispatchEvent(e);\n" +
"}\n" +
"}})()");
the problem is that after running this code, the event OnPageFinished is never called. I had try with OnProgressChanged using WebChromeClient but I had the same result.
I need to obtain the html code of the webpage after that the javascript is runned Any idea about how can I do it?
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressDialog = new ProgressDialog(Activity.this);
progressDialog.setMessage("Loading...Please wait");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
view.loadUrl("javascript:window.HTMLOUT.showHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "Oh no! "+description , Toast.LENGTH_SHORT).show();
super.onReceivedError(view, errorCode, description,failingUrl);
}
});
Here is the method
#SuppressWarnings("unused")
class MyJavaScriptInterface {
private Context ctx;
MyJavaScriptInterface(Context ctx) {
this.ctx = ctx;
}
#Keep
#JavascriptInterface
public void showHTML(String html) {
try {
Log.d("html",html);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
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.
I have a code here where I want to retrieve an element from the webview of android and I can't seems to figure out what's wrong. It might be some silly mistakes but I just can't see why and what's wrong. Thanks.
private void retrieveContentWebView(String address){
Log.d("Web Download"," Inside ");
Log.d("Web Download ","address : " + address);
WebView webView;
webView = new WebView(context);
webView.loadUrl(address);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(this, "myjava");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.getSettings().setDomStorageEnabled(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.d("Web Download"," Inside Page Started");
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d("Web Download"," Inside Page Finished");
view.loadUrl("javascript: {" +
"var titleTexts = document.getElementsByTagName('title')[0]" +
"myjava.onData(titleTexts.text);}");
}
});
}
//This method will be registered as a JavaScript interface
#JavascriptInterface
#SuppressWarnings("unused")
public void onData(final String value){
Log.d("Web Download"," Inside Handler");
final String getValue = value;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do something after 5s = 5000ms
Log.d("Web Download HTML :",getValue);
}
}, 5000);
}
Try adding this to your WebView:
webView.setWebChromeClient(new MyCustomChromeClient(this));
Create the MyCustomChromeClient for yourself.
I am developing the hybrid application in android. In this application I am trying to get the image (either from camera or gallery) as user profile picture. Here is the code that i use to get the image.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView) findViewById(R.id.webview);
try {
WebSettings webSettings = webView.getSettings();
webSettings.setDatabaseEnabled(true);
webSettings.setDatabasePath("/data/data/"
+ getApplicationContext().getPackageName() + "/databases");
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setLoadsImagesAutomatically(true);
webSettings.setRenderPriority(RenderPriority.HIGH);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webSettings.setSupportZoom(false);
webSettings.setBuiltInZoomControls(false);
webSettings.setDisplayZoomControls(false);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(false);
webView.addJavascriptInterface(_jsInterface, "JSInterface");
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
webView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onJsAlert(WebView view, String url,
String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
#SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
private void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType) {
mUploadMessage = uploadMsg;
try {
File imageStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"AndroidImageFolder");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
File file = new File(imageStorageDir + File.separator
+ "CAPTURE_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Intent chooserIntent = Intent.createChooser(i,
"Pick your avatar");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
new Parcelable[] { captureIntent });
startActivityForResult(chooserIntent,
REQUEST_CODE_FILE_CHOOSER);
} catch (Exception e) {
}
}
});
if (savedInstanceState == null) {
webView.loadUrl("file:///android_asset/index.html");
}
} catch (Exception ex) {
Log.d(TAG, ex.getCause().toString());
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
webView.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
webView.restoreState(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_CANCELED) {
//Intent returnIntent = new Intent();
//setResult(RESULT_CANCELED, returnIntent);
} else if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case REQUEST_CODE_FILE_CHOOSER:
if (null == mUploadMessage)
return;
Uri result = (data == null || resultCode != RESULT_OK) ? mCapturedImageURI
: data.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
if (result != null) {
String imagePath = "";
String[] imgData = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor imgCursor = managedQuery(result, imgData, null,
null, null);
if (imgCursor != null) {
int index = imgCursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
imgCursor.moveToFirst();
imagePath = imgCursor.getString(index);
} else {
imagePath = result.getPath();
}
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
bitmap = ExifUtil.rotateBitmap(imagePath, bitmap);
// Here goes the bitmap to base64 conversion
try {
handler.post(new Runnable() {
public void run() {
webView.loadUrl("javascript:myJSFunction()"); // Here I return the base64 code (after bitmap conversion)
}
});
} catch (Exception Ex) {
}
}
break;
}
}
} catch (Exception ex) {
}
}
It successfully open the 'FileChooser' window with Camera and Gallery option. If I choose the image then the application works perfectly. The problem is, when i coming back to app without choosing any file (via back press or click the screen on app) then the application is stuck (Not able to click any of the link in webview).
For test purpose (Whether webview Activity is in active state) i tried to call the JS function in RESULT_CANCELED condition. Here is my test code
if(resultCode == Activity.RESULT_CANCELED){
try {
handler.post(new Runnable() {
public void run() {
webView.loadUrl("javascript:myJSFunction()");
}
});
} catch (Exception Ex) {
}
}
else if(resultCode == Activity.RESULT_OK){
..... // Rest of the code
}
This function is also not called. (but function is called when the resultCode is RESULT_OK)
Test Device OS version: Android JB 4.3
I stuck in this situation. Can you guys please help me to handle the RESULT_CANCELED situation and mark this problem solved. Thanks in advance.
You still need to call mUploadMessage.onReceiveValue when you get RESULT_CANCELLED.
I think you can pass null in this case.
I have developed the gui with html and javascript. I want to load that in my webview and call a javascript function when a URL is called. I have written the following code. But my javascript function is not called at all. I have tried various options. Please help.
public class HelloWebView extends Activity {
WebView webview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setPluginState(PluginState.ON);
webview.getSettings().setDomStorageEnabled(true);
webview.addJavascriptInterface(new JavaScriptHandler(this), "Android");
webview.loadUrl("file:///android_asset/index.html");
webview.setWebViewClient( new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
System.out.println( "shouldOverrideUrlLoading [" + url + "]" );
webview.loadUrl( "javascript:sendData()" );
return true;
}
public void onPageFinished(WebView view, String url) {
System.out.println( "onPageFinished [" + url + "]" );
webview.loadUrl( "javascript:function sendData(){}" );
}
});
webview.setWebChromeClient(new WebChromeClient() {
#Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
/* Do whatever you need here */
return super.onJsAlert(view, url, message, result);
}
});
}
public class JavaScriptHandler {
Context mContext;
public JavaScriptHandler(Context context) {
mContext = context;
}
#JavascriptInterface
public void returnResult() {
}
}
}
Javascript:
sendData : function()
{
alert("Inside SendData()");
if( this.sendQueue.length > 0 )
{
var url = this.sendQueue[0];
this.sendQueue.splice( 0, 1 );
window.location = url;
}
}