I have a very complex bug: in my application, I use in webview that display local images. until version '76.0.3809.111' of the webview, everything was work perfectly but from this version when I'm trying to display those images I get "Failed to load resource: net::ERR_UNKNOWN_URL_SCHEME". This error occurs only in the first run when I close the application and restart it everything is working fine.
Additionally when I set settings.setAppCacheEnabled(false) also everything is working perfectly.
When I debug my application I noticed that in the first time (that the images not loaded) the "shouldInterceptRequest" methods not calling.
this is my settings of the webview :
WebSettings settings = wv.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
wv.addJavascriptInterface(jsHandler, "cpjs");
settings.setDomStorageEnabled(true);
String PACKAGE_NAME = ctx.getPackageName();
settings.setDatabaseEnabled(true);
settings.setDatabasePath("/data/data/" + PACKAGE_NAME + "/databases/");
settings.setAppCacheMaxSize(1024 * 1024 * 16);
settings.setAppCachePath(ctx.getCacheDir().getAbsolutePath());
settings.setAllowFileAccess(true);
settings.setAppCacheEnabled(true);
settings.setLightTouchEnabled(false);
settings.setSupportZoom(false);
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//Allow to redirect https to http for downloading content
if (Build.VERSION.SDK_INT >= 21) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
KsLog.i(TAG, "WebView settings, MIXED_CONTENT_ALWAYS_ALLOW set");
}
settings.setSavePassword(false);
settings.setLightTouchEnabled(false);
settings.setSupportZoom(false);
wv.setScrollContainer(false);
wv.setHorizontalScrollBarEnabled(false);
wv.setVerticalScrollBarEnabled(false);
wv.setLongClickable(false);
wv.cancelLongPress();
and this is the override of the "shouldInterceptRequest" method:
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
try {
if (url.startsWith(Constants.KS_LOCAL_PREFIX)) {
// In case url starts with our proprietary protocol handle the request.
// Images are located in the external files directory under "images" folder
String fileName = url.substring(url.lastIndexOf(Constants.URL_SLASH));
String filePath = FileUtils.getImagesLocalFolder(getAppContext()) + fileName;
File imagefile = new File(filePath);
FileInputStream fis = new FileInputStream(imagefile);
Bitmap bi = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (bi != null) {
bi.compress(Bitmap.CompressFormat.PNG, 100, baos);
}
byte[] data = baos.toByteArray();
InputStream is = new ByteArrayInputStream(data);
return new WebResourceResponse("text/html", "UTF-8", is);
}
} catch (FileNotFoundException e) {
KsLog.d(TAG, e.toString());
} catch (NullPointerException nullEx) {
KsLog.d(TAG, nullEx.toString());
}
return super.shouldInterceptRequest(view, url);
}
This is an example of bad image :
This is an example of good image :
Thanks to everyone and I hope I explained myself well.
Related
What is the best way to load a jpeg from an install-time asset pack and show it on a WebView?
I got it working in case the jpeg is a regular asset, however, I couldn't get it working optimally with install-time assets:
WebView webView = this.findViewById(R.id.webView);
String sHtmlTemplate = "<img src='file:///android_asset/files/"+file+".jpg' width='100%'/>";
webView.loadDataWithBaseURL("file:///android_asset/files/", sHtmlTemplate, "text/html", "utf-8", null);
UPDATE:
The solution below works, but it is slow. Is there a way to load images directly from InputStream or install-time assets?
AssetManager assetManager = getAssets();
InputStream is = assetManager.open(songNo + ".jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024000];
int count;
while(-1 != (count = is.read(buffer, 0, buffer.length))) {
baos.write(buffer, 0, count);
}
baos.flush();
byte[] imageRaw = baos.toByteArray();
baos.close();
is.close();
String image64 = Base64.encodeToString(imageRaw, Base64.DEFAULT);
String html = String.format("<img width='100%%25' src='data:image/jpeg;base64,%s' />", image64);
webView.loadData(html, "text/html; charset=UTF-8", null);
Thanks
Perhaps the WebView is not the most optimal way to show a jpg in this case. I ended up using another control:
com.ortiz.touchview.TouchImageView touchView = this.findViewById(R.id.touchImageView);
try {
AssetManager assetManager = getAssets();
InputStream is = assetManager.open(songNo + ".jpg");
Drawable d = Drawable.createFromStream(is,"src");
touchView.setImageDrawable(d);
}catch(Exception e){
Log.i("xxx", e.getMessage());
}
I am able to download and view from url ending with *.pdf with the below code
private static final int MEGABYTE = 1024 * 1024;
public static void downloadFile(String fileUrl, File directory){
try {
URL url = new URL(fileUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
//urlConnection.setRequestMethod("GET");
//urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(directory);
int totalSize = urlConnection.getContentLength();
byte[] buffer = new byte[MEGABYTE];
int bufferLength = 0;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
but I have tried to download PDF file with url ending with .aspx as its generate PDF dynamically and its not working .
I have also tried to embed with webview with google doc url "http://docs.google.com/viewer?url="+URL but its also not working.
Can anyone help in this?
'.aspx' Is ASP.NET page that is actually web form.
Web forms are contained in files with a ".aspx" extension; these files
typically contain static (X)HTML markup or component markup.
So what you are loading is a simple HTML page rendered on server side. So you cannot use it to view PDF - in PDF viewer.
Instead of openning '.aspx' from file load this url into WebView - this will work only if there are no additional security on the site you are pointing to.
In case of Google Docs the link you are providing to the WebView should be sharing links like following:
https://drive.google.com/file/d/xx-xxxxxxxxxxxxxxx/view?usp=sharing
Where x's are part of hash. To get this link - click on Share option for the document and then get shareable link.
Before WebView reaches pdf document it could receive few redirects that potentially will be handled by Android itself. To avoid this you need to override WebViewClient#shouldOverrideUrlLoading like in following example:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
});
mWebView.loadUrl("https://drive.google.com/file/d/xx-xxxxxxxxxxxxxxx/view?usp=sharing");
Also you could get direct link to the file using sharable url you get above:
change this:
https://drive.google.com/file/d/xx-xxxxxxxxxxxxxxx/view?usp=sharing
to this:
https://drive.google.com/uc?export=download&id=xx-xxxxxxxxxxxxxxx
or to this:
https://docs.google.com/document/d/xx-xxxxxxxxxxxxxxx/export?format=pdf
I am developing an app in that I wanted to display a pdf file from asset. I did so much google and also tried number of permutations and combinations but not working.
CODE:
private void CopyReadAssets()
{
AssetManager assetManager = getActivity().getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/abc.pdf");
try
{
in = assetManager.open("abc.pdf");
out = getActivity().openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
when I click on list, I call CopyReadAssets() function then it prompts me in which viewer you want to open then I click on AdobeReader then it shows following error.
I have check your code There are some mistake that you have to change and May be you have copied code from here.
Replace
AssetManager assetManager = getAssets();
Instead of AssetManager assetManager = getActivity().getAssets();
Direct Use File file = new File(getFilesDir(), "abc.pdf");
Instead of
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/abc.pdf");
Hope its works for you.!!!
You can do this By using web view-
webview = (WebView) findViewById(R.id.prayertimes_webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setPluginsEnabled(true);
webview.getSettings().setSupportZoom(true);
webview.getSettings().setBuiltInZoomControls(true);
String urll = "http://docs.google.com/gview?embedded=true&url=" + url;
webview.setWebViewClient(new WebViewClient());
webview.loadUrl(urll);
The PDF file cannot be seen from the PDF reader because anything inside of your assets are private to your app. You have to make it public in some way. There are several ways for this.
The most sophisticated way is to implement a public ContentProvider and override the openAssetFile method in it. Pass the URL for the file through Intent, and the PDF reader should be able to use ContentResolver and get the PDF file by openAssetFileDescriptor method.
Here's a link.
- http://www.nowherenearithaca.com/2012/03/too-easy-using-contentprovider-to-send.html
In my app I am using a webview to navigate through to a site, automatically fill in a web form using javascript then submit to obtain a link to a CSV export file.
The link looks like this: XYZ.com/TEST/index/getexport?id=130.
I'd like to download the file this URL points to, then when complete read it into a local database but I'm having trouble downloading the linked file.
If I simply try to open the URL in webview I get an error from the webpage telling me no such file exists.
If I use the Download Manager to download it myself, the source code is downloaded as an html file, not the associated .csv file.
I can open the url with an ACTION_VIEW intent and a browser (chrome) downloads the correct file, but this way I have no notification of when the download completes.
Any ideas of how to download my .CSV file?
To download a file from webview use this :
mWebView.setDownloadListener(new DownloadListener(){
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength){
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
Hope this helps.
You could resort to manually downloading the file from the url using an AsyncTask.
Here id the background part:
#Override
protected String doInBackground(Void... params) {
String filename = "inputAFileName";
HttpURLConnection c;
try {
URL url = new URL("http://someurl/" + filename);
c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
} catch (IOException e1) {
return e1.getMessage();
}
File myFilesDir = new File(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/Download");
File file = new File(myFilesDir, filename);
if (file.exists()) {
file.delete();
}
if ((myFilesDir.mkdirs() || myFilesDir.isDirectory())) {
try {
InputStream is = c.getInputStream();
FileOutputStream fos = new FileOutputStream(myFilesDir
+ "/" + filename);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
} catch (Exception e) {
return e.getMessage();
}
if (file.exists()) {
return "File downloaded!";
} else {
Log.e(TAG, "file not found");
}
} else {
Log.e(TAG, "unable to create folder");
}
}
Perhaps it would make sense to refactor it so that the file is returned. Then you get the file as an argument in onPostExecute as soon as the download is complete.
I've got the following
String urlStr = "http://example.com/my.jpg"
String mimeType = "image/jpeg";
String encoding = null;
String pageData = ""; // This is data read in from an HttpURLConnection
webview.loadDataWithBaseURL(urlStr, pageData, mimeType, encoding, urlStr);
but when I run this, all I see is a blue question mark instead of my image. What is the proper way to handle displaying an image in a WebView with loadData?
Edit:
Is there a way to do this without passing pageData as <img src="http://example.com/my.jpg/"> ? It seems silly that loadData takes a mime-type if it can only handle "text/html". Especially since the javadoc lists "image/jpeg" as an example mime-type that you might pass in.
It is possible to embedd the base64 encoded imagedata direct into the <img>-tag:
<img src="data:image/jpeg;base64,base64DataHere" />
Here an example for creating the <img>-tag (I use an byte-array instead the String for raw-data, because in my tests an String as source didn't work - I assume that String can't handle binary-data):
byte[] imageRaw = yourImage;
String image64 = Base64.encodeToString(imageRaw, Base64.DEFAULT);
String pageData = "<img src=\"data:image/jpeg;base64," + image64 + "\" />";
The Base64-class was introduced with API v.2.2 - for older API-versions you can copy the sourcefile from git and integrate it in your app. It should work with older API-versions.
Or you can use one of the alternative classes for base64-encoding like Base64Coder.
And here the complete working code for retrieving, converting and showing the image:
byte[] imageRaw = null;
try {
URL url = new URL("http://some.domain.tld/somePicture.jpg");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
out.flush();
imageRaw = out.toByteArray();
urlConnection.disconnect();
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String image64 = Base64.encodeToString(imageRaw, Base64.DEFAULT);
String urlStr = "http://example.com/my.jpg";
String mimeType = "text/html";
String encoding = null;
String pageData = "<img src=\"data:image/jpeg;base64," + image64 + "\" />";
WebView wv;
wv = (WebView) findViewById(R.id.webview);
wv.loadDataWithBaseURL(urlStr, pageData, mimeType, encoding, urlStr);
Use this.. solve the problem of images load in webview.
WebView webView = (WebView)findViewById(R.id.webView1);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setJavaScriptEnabled(true);
String url ="Path of image";
String imgSrcHtml = "<html><img src='" + url + "' /></html>";
webView.loadData(imgSrcHtml, "text/html", "UTF-8");