JavaScript doesn't work on ICS - java

I am working on EPUB reader for the company using JavaScript, the application runs well on Android 2.2, but when i try it on ICS & HoneyCom, the JavaScript doesn't work well. The first problem i faced, the WebView doesn't load JS files (Unknown Error -6), so i used this solution:
#TargetApi(11)
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
Log.d("shouldInterceptRequest", url);
InputStream stream = inputStreamForAndroidResource(url);
if (stream != null) {
return new WebResourceResponse("text/javascript", "utf-8", stream);
}
return super.shouldInterceptRequest(view, url);
}
private InputStream inputStreamForAndroidResource(String url) {
final String ANDROID_ASSET = "file:///android_asset/";
if (url.contains(ANDROID_ASSET)) {
// url = url.replaceFirst(ANDROID_ASSET, "");
String[] f = url.split("/");
url = "epub/"
+ f[f.length - 1]
.substring(0, f[f.length - 1].indexOf("'"));
try {
AssetManager assets = mActivity.getAssets();
Uri uri = Uri.parse(url);
return assets
.open(uri.getPath(), AssetManager.ACCESS_STREAMING);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
and now i don't have this error, but the JS still doesn't work. Does anyone have a solution?

the only solution I found is the same as the question....

Might be a stupid thing i'm saying here. But it's late and i'm tired ...
Have you tried enabling Javascript in the WebView?
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

u can add one property android:hardwareAccelerated="true" in application tag of your manifest.xml as well u can add some settings in on create
wvMain.getSettings().setSupportZoom(true);
wvMain.getSettings().setBuiltInZoomControls(true);
wvMain.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
wvMain.setScrollbarFadingEnabled(true);
wvMain.getSettings().setLoadsImagesAutomatically(true);
wvMain.getSettings().setJavaScriptEnabled(true);
wvMain.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wvMain.getSettings().setPluginsEnabled(true);
wvMain.getSettings().setSupportZoom(false);
wvMain.getSettings().setCacheMode(wvMain.getSettings().LOAD_NO_CACHE);
webSettings8.setPluginState(WebSettings.PluginState.ON);
wvMain.setWebViewClient(new WebViewClient());
wvMain.addJavascriptInterface(this, "Android");
wvMain.getSettings().setSupportMultipleWindows(true);
wvMain.getSettings().setPluginsEnabled(true);
wvMain.getSettings().setUseWideViewPort(true);
wvMain.getSettings().setLoadWithOverviewMode(true);
i hope this helps.but note, hardwareaccelerated property supports after 3.0.

Related

How to open pdf file inside my app (android studio, JAVA) from firebase storage link

I have pdf file stored on my firebase storage, and its link in firebase real-time database, how can I open it inside my android app (android studio, JAVA). Not using INTENT , but directly inside my app.
You can use android-pdfView, see this blog post.
It demonstrates the basic usage of the library to display pdf onto the view with vertical and horizontal swipe.
pdfView = (PDFView) findViewById(R.id.pdfView);
pdfView.fromFile(new File("/storage/sdcard0/Download/pdf.pdf")).defaultPage(1).enableSwipe(true).onPageChange(this).load();
There are also other libraries like Android PDF Viewer,
VuDroid etc.
Also Android API 19 provides feasibility now to present pdf content inside an app and thus no need of 3rd party SDKs.
you can find details here.
If you want to load the file using a URL then you can use a webview.
WebView webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
String pdf = "http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf";
webview.loadUrl("http://docs.google.com/gview?embedded=true&url=" + pdf);
Found the answer with little research :-
no need of webview or Intent which opens another app
Library :-
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
xml code :-
<com.github.barteksc.pdfviewer.PDFView
android:visibility="visible"
android:id="#+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
JAVA code :-
{
String pdfurl="firebase_access_token_of_pdf_file";
pdfView = (PDFView) findViewById(R.id.pdfView);
new RetrivePDFfromUrl().execute(pdfUrl);
}
// create an async task class for loading pdf file from URL.
class RetrivePDFfromUrl extends AsyncTask<String, Void, InputStream> {
#Override
protected InputStream doInBackground(String... strings) {
// we are using inputstream
// for getting out PDF.
InputStream inputStream = null;
try {
URL url = new URL(strings[0]);
// below is the step where we are
// creating our connection.
HttpURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
// response is success.
// we are getting input stream from url
// and storing it in our variable.
inputStream = new BufferedInputStream(urlConnection.getInputStream());
}
} catch (IOException e) {
// this is the method
// to handle errors.
e.printStackTrace();
return null;
}
return inputStream;
}
#Override
protected void onPostExecute(InputStream inputStream) {
// after the execution of our async
// task we are loading our pdf in our pdf view.
pdfView.fromStream(inputStream).load();
}
}
}

No Preview available when I load without .pdf content webview

I try to load my contant as PDF in webview android but it display No Preview Available How can i solve
My Code is Here :-
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setPluginState(WebSettings.PluginState.ON);
webview.setWebChromeClient(new WebChromeClient());
String URLPATH = "http://myaccount365.in/public/oddeve78/report/ledger/11/summaryLedger?fromDate=01/11/2019&toDate=09/12/2019";
String url = "https://docs.google.com/gview?embedded=true&url=" + URLPATH;
webview.loadUrl(url);
The problem is clearly this:
You have two URLs - the URL of the PDF and the URL of google docs. Since you want to pass one URL to the other URL as a GET parameter (?embedded=true&url=) and the URL that you try to pass contains GET parameters as well: ?fromDate= and &toDate=, the seconds URL has to be URLEncoded.
So please just call
String url = "https://docs.google.com/gview?embedded=true&url=" + URLEncoder.encode(URLPATH, "ISO-8859-1");
and try again.
Caution: when working with URLEncoder.encode: you always have this problem: you can either call the #Deprecated method URLEncoder.encode(String s) without a specific encoding or the preferred method with URLEncoder.encode(String s, String enc) where you can specifiy the encoding, but this method has throws UnsupportedEncodingException in its signature :-O
Anyhow, both URLEncoder.encode(url) and URLEncoder.encode(url, "UTF-8") or URLEncoder.encode(url, "ISO-8859-1") will yield the same result since you have no UTF-8 or ISO-8859-1 specific characters in the URL:
https://docs.google.com/gview?embedded=true&url=http%3A%2F%2Fmyaccount365.in%2Fpublic%2Foddeve78%2Freport%2Fledger%2F11%2FsummaryLedger%3FfromDate%3D01%2F11%2F2019%26toDate%3D09%2F12%2F2019
I'm using this and works for me: Check Here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView=new WebView(MainActivity.this);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
//---you need this to prevent the webview from
// launching another browser when a url
// redirection occurs---
webView.setWebViewClient(new Callback());
String pdfURL = "http://www.expertagent.co.uk/asp/in4glestates/{16D968D6-198E-4E33-88F4-8A85731CE605}/{05c36123-4df0-4d7d-811c-8b6686fdd526}/external.pdf";
webView.loadUrl(
"http://docs.google.com/gview?embedded=true&url=" + pdfURL);
setContentView(webView);
}
private class Callback extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(
WebView view, String url) {
return(false);
}
}
OR Try
I think Exact Problem is in URL encoding which we concat with "http://docs.google.com/gview?url=". This means we have to replace all special character(:, /, & etc) of url with unicode. Uri.encode("") do the trick for us.
Like this
String url = Uri.encode("your link");
String finalUrl = "http://docs.google.com/viewer?url=" + url + "&embedded=true";
I think it is your pdf file URL problem, please check your URLPATH it wether return a pdf URL like this https://www.tutorialspoint.com/css/css_tutorial.pdf
I use this URL it render normal
String URLPATH = "https://www.tutorialspoint.com/css/css_tutorial.pdf";
String url = "https://docs.google.com/gview?embedded=true&url=" + URLPATH;
//url:https://docs.google.com/gview?embedded=true&url=https://www.tutorialspoint.com/css/css_tutorial.pdf
webview.loadUrl(url);
I think your URLPATH is a dynamic url, it return a file url according to the params. but now it may be not return a correct url. it can to check it, or you change the URLPATH to a url which has http://host:port/path/.pdf . use it to test your code.
String URLPATH = "http://www.pdf995.com/samples/pdf.pdf";
String url = "https://docs.google.com/gview?embedded=true&url=" + URLPATH;
webview.loadUrl(url);

Android Webview cannot render the pdf sometimes and shows blank/white page instead

Open the pdf in the webview using google docs
Open the same pdf or different pdf again and again.
Sometimes it will show the blank/white page in the android untill we refresh the webpage again for 1 or 2 times.
I have made the sample on the pdf. The link for the project is shown below:
https://github.com/gopalawasthi123/PdfWebView
Hope this will help you Better.
public void SetWebView(WebView webview,string externalUrl){
webview.Tag = "webview";
webview.Settings.JavaScriptEnabled = true;
webview.Settings.SupportZoom ();
webview.Settings.SetAppCacheEnabled(true);
webview.Settings.DomStorageEnabled = true;
webview.ZoomOut ();
webview.ZoomIn ();
webview.Settings.BuiltInZoomControls = true;
webview.Settings.LoadWithOverviewMode = true;
webview.Settings.UseWideViewPort = true;
//webview.Settings.SetSupportZoom (true);
webview.Settings.SetPluginState (WebSettings.PluginState.On);
webview.Settings.GetPluginState ();
if (externalUrl.StartsWith("http://") || externalUrl.StartsWith("https://"))
webview.LoadUrl (externalUrl);
webview.SetWebViewClient (new MonkeyWebViewClient (imgViewBack, imgViewForward, imgRefresh));
webview.SetWebChromeClient (new WebChromeClient ());
}
You can reload the page until it displays the pdf in this way:
public void onPageFinished(WebView view, String url) {
if (view.getTitle().equals(""))
view.reload();
}
After testing second PDF URL file, WebView seems like that can not load large PDF file.
Reason:
WebView display HTML. The fact that this works at all is by a hack- google will convert simple PDFs into HTML. It doesn't seem like they support anything that big. Even if they did, I would expect loading a large page PDF converted to HTML would be so large I highly doubt you'd be able to load it without going OOM. Use an appropriate PDF library, make a real PDF rendering view, and make sure not to render more of the PDF at a time than you need (or else you'll go OOM anyway). In other words, don't rely on hacky solutions you never should have relied on in the first place.
Solution:
You should try alternatives like PDF.js running locally in your device, instead of a service like Google Docs preview.(Or download PDF first to local file path)
Put it in your assets folder and tweak the example:
wv.loadUrl("file:///android_asset/web/viewer.html");
Also, you can have Out Of Memory situations. An alternative to try is a native viewer like AndroidPdfViewer.
We can solve the Problem in the two ways.
1. One is to use the Js.Pdf Plugin on the server end. It surely solve the problem but if we have multiple pdf's in the Fragment then it may cause the out of memory situations
and app can crash.
2. Second option is we can recursively called the function to load webview. This will also cause the issue but with less frequency Below is the code:
private void showPdf(final String imageString) {
pdfView.invalidate();
pdfView.getSettings().setJavaScriptEnabled(true);
pdfView.getSettings().setSupportZoom(true);
pdfView.loadUrl("http://docs.google.com/gview?embedded=true&url=" + imageString);
pdfView.setWebViewClient(new WebViewClient() {
boolean checkhasOnPageStarted = false;
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
checkhasOnPageStarted = true;
}
#Override
public void onPageFinished(WebView view, String url) {
if (checkhasOnPageStarted ) {
pdfView.loadUrl(removePdfTopIcon);
} else {
showPdf(imageString);
}
}
});
}
I was having the exact same issue and found that there was always a chance the WebView would not load on the first load attempt, especially if the pdf was on the larger side. The code I put together below works 100% of the time. From my beginner's understanding, it safely utilizes a separate thread to loop through and test the load status of the WebView, re-attempting a load of the view until successful. As this question was posted a year ago, I have generalized my solution to best benefit new viewers.
public class WebViewActivity extends AppCompatActivity {
String PDFView;
WebView webView;
String PDFBrowserView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get the intended "PDFView"
PDFView = getIntent().getExtras().get("PDFView").toString();
//Have to manually encode (?) the url to display it
try {
PDFView = URLEncoder.encode(PDFView, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Full display url
PDFBrowserView = "https://docs.google.com/gview?embedded=true&url=" + PDFView;
//Initialize a new "WebView" instance
webView = new WebView(WebViewActivity.this);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
//This handles callbacks (?)
webView.setWebChromeClient(new WebChromeClient());
//Call this to load page if page is blank with pdf url until page is not blank
checkPageFinished();
}
public void checkPageFinished() {
//If view is blank:
if (webView.getContentHeight() == 0) {
//Run off main thread to control delay
webView.postDelayed(new Runnable() {
#Override
public void run() {
//Load url into the "WebView"
webView.loadUrl(PDFBrowserView);
}
//Set 1s delay to give the view a longer chance to load before
// setting the view (or more likely to display blank)
}, 1000);
//Set the view with the selected pdf
setContentView(webView);
webView.postDelayed(new Runnable() {
#Override
public void run() {
//If view is still blank:
if (webView.getContentHeight() == 0) {
//Loop until it works
checkPageFinished();
}
}
//Safely loop this function after 1.5s delay if page is not loaded
}, 1500);
}
}
}
There are some ways through which we can identify whether a Page/URL is loaded properly or not from onPageFinished() method of the Webview and based on that reload() url.
Option 1 : To check with contentHeight of the webview.
override fun onPageFinished(view: WebView?, url: String?) {
if(view?.contentHeight == 0){
view?.reload()
return
}
super.onPageFinished(view, url)
}
Option 2 : To check with title of the webview.
override fun onPageFinished(view: WebView?, url: String?) {
if(view?.title.isNullOrEmpty()){
view?.reload()
return
}
super.onPageFinished(view, url)
}
Tested in multiple devices and working within API 29
in Kotlin
val webSettings: WebSettings = webview.settings
webSettings.javaScriptEnabled = true
webSettings.useWideViewPort = true
webSettings.loadWithOverviewMode = true
webSettings.domStorageEnabled = true
webview.webViewClient = AppWebViewClients()
// val TERM_CONDITION_URL = "http://docs.google.com/gview?embedded=true&url="
// + "YOUR_DOC_URL_HERE"
bindind?.webview?.loadUrl(TERM_CONDITION_URL)
and here AppWebViewClients class
class AppWebViewClients : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean {
view.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView?, url: String?) {
if (view?.contentHeight == 0)
view?.reload();
else {
super.onPageFinished(view, url)
}
}
}
I think you should do as below:
public void onPageFinished(WebView view, String url) {
if (!view.getUrl().equals(url)) {
view.loadUrl(url);
return;
}
}

How to get direct link of remote video from embedded url within a url in Android using JSoup?

I had asked the question previously about how to retrieve the embedded url for a video file and have successfully done so. Now I have a different issue. The json response for a WUnderground API webcam response gives the following url:
https://www.wunderground.com/webcams/cadot1/902/show.html
Using JSoup and per the answer to my initial issue I was able to get this embedded link:
https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4
While trying to "stream" the video from that url to a VideoView, I kept getting the error "cannot play video". Upon looking at the source for that link I noticed that the video file that needs to be played is not referenced in html but rather javascript. How can I get the direct link for the video file that needs to be played? Using JSoup or other process?
The source for the url https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4 shows the following for the needed video file within a <script> bracket:
url: "//icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1480377508"
I am using JSoup to get the embedded url for the video from the response url like so:
private class VideoLink extends AsyncTask<Void, Void, Void> {
String title;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setTitle("JSOUP Test");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
// for avoiding javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
System.setProperty("jsse.enableSNIExtension", "false");
// WARNING: do it only if security isn't important, otherwise you have
// to follow this advices: http://stackoverflow.com/a/7745706/1363265
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType){}
public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}
// Connect to the web site
Document doc = Jsoup.connect(TEST_URL).get();
Elements elements = doc.getElementsByClass("videoText");
// Get the html document title
for (Element link : elements) {
String linkHref = link.attr("href");
// linkHref contains something like video.html?month=11&year=2016&filename=current.mp4
// TODO check if linkHref ends with current.mp4
title = linkHref;
}
} catch (IOException e) {
e.printStackTrace();
mProgressDialog.dismiss();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Set title into TextView
resultTxt.setText(title);
String resVid = TEST_URL;
Log.d(TAG, "URL: " + resVid);
Uri resUri = Uri.parse(resVid);
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(
MainActivity.this);
mediacontroller.setAnchorView(resultVidVw);
// Get the URL from String VideoURL
Uri video = Uri.parse(resVid);
resultVidVw.setMediaController(mediacontroller);
resultVidVw.setVideoURI(video);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
resultVidVw.requestFocus();
resultVidVw.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mProgressDialog.dismiss();
resultVidVw.start();
}
});
}
}
Please note that I need to do this on every JSONObject in the response array.
This is how you can GET the file:
(Notice: the Extraction part only works with current html of the site and if that changes, it may not work correctly!)
String url = "https://www.wunderground.com/webcams/cadot1/902/video.html";
int timeout = 100 * 1000;
// Extract video URL
Document doc = Jsoup.connect(url).timeout(timeout).get();
Element script = doc.getElementById("inner-content")
.getElementsByTag("script").last();
String content = script.data();
int indexOfUrl = content.indexOf("url");
int indexOfComma = content.indexOf(',', indexOfUrl);
String videoUrl = "https:" + content.substring(indexOfUrl + 6, indexOfComma - 1);
System.out.println(videoUrl);
[Output: https://icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1481246112]
Now you can get the file by specifying .ignoreContentType(true) in order to avoid org.jsoup.UnsupportedMimeTypeException and .maxBodySize(0) to remove the limit on file size.
// Get video file
byte[] video = Jsoup.connect(videoUrl)
.ignoreContentType(true).timeout(timeout).maxBodySize(0)
.execute().bodyAsBytes();
I don't know if you can play it in Android or not but I think you can save it using org.apache.commons.io.FileUtils (I tested it in Java SE but not Android development environment.)
// Save video file
org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video);

Block videos in android webview - Alternative to shouldInterceptRequest()

I have created a web browser using webview in android. My aim is to control the content of the webview before it is loaded. Whenever the content of the webview makes a request to any domain server, it has to pass through shoulInterceptRequest(). If the url is pointing to any video uploading sites(youtube.com, vimeo.com), I can change it to some Access Denied url so that video will not be loaded.
#Override
public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
try {
if (access.permission(url)) {
return super.shouldInterceptRequest(view, url);
}
} catch (Exception e) {
e.printStackTrace();
}
return getResponseData();
}
private WebResourceResponse getResponseData() {
try {
String str = "Access Denied";
InputStream data = new ByteArrayInputStream(str.getBytes("UTF-8"));
return new WebResourceResponse("text/css", "UTF-8", data);
} catch (IOException e) {
return null;
}
}
But shoulInterceptRequest() is availabe from API 11. I NEED it to work from API 8.
Is there any alternative way to implement it ? I need to block the url if it is potinting to any video uploading sites BEFORE LOADING ANY DATA.
How about using the http://developer.android.com/reference/android/webkit/WebViewClient.html#shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String) event?
You can block the url and then call http://developer.android.com/reference/android/webkit/WebView.html#loadUrl(java.lang.String) to show anything you want (and even run arbitrary javascript with the "javascript:do_something()" notation)

Categories