I want to download images and cache them base64 encoded in database, when i'm online. When my app is offline, i would replace all image tags by the appropriate strings. But if i show them, there are always question mark icons, which e.g. are shown, when an image is not found. (There's no error or warning in LogCat). How could I show the image?
I created a short example app:
#Override
protected void onCreate(Bundle savedInstanceState)
{
activity = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new MyWebViewClient());
webView.setWebChromeClient(new MyWebChromeClient());
webView.setHttpAuthUsernamePassword(host, "", user, password);
new Image().execute("");
}
public String getUrlContent(String urlstring) throws IOException
{
URL url = new URL(urlstring);
URLConnection connection = url.openConnection();
Authenticator.setDefault(new Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(user, password .toCharArray());
}
});
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
{
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(httpConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String inputLine;
while ((inputLine = bufferedReader.readLine()) != null)
stringBuilder.append(inputLine + "\n");
return stringBuilder.toString();
}
return null;
}
private class Image extends AsyncTask<String, Void, Boolean>
{
private String img;
#Override
protected Boolean doInBackground(String... string)
{
try
{
img = new String(Base64.encodeToString(getUrlContent(url).getBytes(),
Base64.DEFAULT));
} catch (IOException e)
{
e.printStackTrace();
}
return true;
}
#Override
protected void onPostExecute(Boolean doInBackground)
{
String html = "<html><img src=\"data:image/jpeg;base64," + img + "\" /></html>";
webView.loadDataWithBaseURL("http://example.com/my.jpg", html, "text/html", null, url);
webView.loadData(html, "text/html", "UTF-8");
}
}
private class MyWebViewClient extends WebViewClient
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
return true;
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl)
{
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_LONG)
.show();
}
#Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm)
{
handler.proceed(user, password);
}
}
private class MyWebChromeClient extends WebChromeClient
{
#Override
public void onProgressChanged(WebView view, int progress)
{
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach
// 100%
activity.setProgress(progress * 1000);
}
#Override
public void onReachedMaxAppCacheSize(long spaceNeeded,
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
{
quotaUpdater.updateQuota(spaceNeeded * 2);
}
}
The Method to download is incorrect for images (I think you have explicitly read bytes, not Strings for images).
Here's the correct download code:
public String getUrlContent(String urlstring) throws IOException
{
byte[] imageRaw = null;
URL url = new URL(urlstring);
Authenticator.setDefault(new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password.toCharArray());
}});
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setUseCaches(false);
urlConnection.connect();
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
{
try
{
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();
}
return Base64.encodeToString(imageRaw, Base64.DEFAULT);
}
return null;
}
Thanks to this two posts: How to display image with WebView loaddata? and How to do HTTP authentication in android?
Related
I want to start an activity and give out a Toast message after I parsed a JSON response, well as you can't do that while a Dialog is open, I am using a DialogListener, which actually works fine, but not when it gets called in the parseJSON method.
public class Pop_Forgot_PW extends AppCompatDialogFragment{
......
sendResetMail();
private void sendResetMail()
{
final String url = "someURL";
new Json(new Json.Callback() {
#Override
public void run(String result) {
parseJSON(result);
}
}).checkJsonFile(url, getContext());
}
//Now in an non-activity class
public class Json {
public void checkJsonFile(final String url, final Context context) {
new Thread(new Runnable() {
public void run() {
String result;
String line;
try {
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setReadTimeout(5000);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
boolean redirect = false;
// normally, 3xx is redirect
int status = conn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
redirect = true;
}
if (redirect) {
// get redirect url from "location" header field
String newUrl = conn.getHeaderField("Location");
// get the cookie if need, for login
String cookies = conn.getHeaderField("Set-Cookie");
// open the new connnection again
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn.setRequestProperty("Cookie", cookies);
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", "google.com");
}
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
result = sb.toString();
callback.run(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
//Back in the Pop_Up
public void parseJSON(String JSON) {
try {
JSONObject jsonObject = new JSONObject(JSON);
error = jsonObject.getInt("error_code");
switch (error) {
case 0:
toastText = getString(R.string.email_sent);
break;
case 1:
toastText = getString(R.string.no_account);
break;
}
listener.showToast(toastText);
dismiss();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void setListener(DialogListener listener) {
this.listener = listener;
}
public interface DialogListener
{
void showToast(String toastText);
}
I already tried the runOnUIThread, but it doesn't help.
Thank you very much in advance
Solved it by putting all the stuff in an activity an not in the DialogFragment.
Thank you to everyone :)
when calling
new AsyncFeed(strurl).execute();
after this its able to call constructor of AsyncFeed but not able to execute doInBackground(). while debugging i found out it calls constructor and then simply returns back to the calling statement making a nullpointer exception in later code
public class HttpHandler {
public HttpHandler() {
}
URL url;
HttpURLConnection httpURLConnection = null;
InputStream inputStream;
BufferedReader bufferedReader = null;
StringBuffer stringBuffer;
String strurl;
public String getJsonString(String strurl){
new AsyncFeed(strurl).execute();
return String.valueOf(stringBuffer);
}
class AsyncFeed extends AsyncTask<String,Void,String>{
String urlStr;
public AsyncFeed(String urlStr) {
this.urlStr=urlStr;
}
#Override
protected String doInBackground(String... strings) {
try {
url = new URL(urlStr);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
stringBuffer = new StringBuffer();
while ((line=bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedReader !=null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
httpURLConnection.disconnect();
}
return null;
}
If you think that stringBuffer is null, it's because function public String getJsonString(String strurl) returns String value of uninitialized stringBuffer before AsyncFeed is completed. You should use something like this:
public void loadJsonString(String strurl){
new AsyncFeed(strurl).execute();
//return String.valueOf(stringBuffer);
}
class AsyncFeed extends AsyncTask<Void,Void,Void>{
String urlStr;
public AsyncFeed(String urlStr) {
this.urlStr=urlStr;
}
#Override
protected String doInBackground(Void... records) {
try {
url = new URL(urlStr);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
stringBuffer = new StringBuffer();
while ((line=bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedReader !=null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
httpURLConnection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
//f.e. show progress dialog
}
#Override
protected void onPostExecute(Void result) {
//now you have initialized stringBuffer so do what you want with it
//hide progress dialog
//print String value of stringBuffer initialized in doInBackground
System.out.print(String.valueOf(stringBuffer));
}
)
There are more options to do that but it's hard to write exactly what you need without seeing more of your code or specify your question, so if you have some
questions to me just write comment :) or read more here Android Developers - AsyncTask
EDIT
Okay I understand, try do it like this, the idea is just pass calling object into the async task and from there in onPostExecute() will be updated data
in ClassA and continue with what you need
public class ClassA{
String url;
String jsonObjectString;
//instead of getJsonString(url) call this and after async task will finish
//it calls updateDataFromAsync() so you will have data loaded and you can continue work with it in doSomethingAfterAsync()
private void loadData(){
//pass the calling object into the async task
new HttpHandler(this).startLoadJsonString(url);
}
//this will async taks call in onPostExecute()
public void updateDataFromAsync(String s){
jsonObjectString = s;
doSomethingAfterAsync();
}
private doSomethingAfterAsync(){
}
}
public class HttpHandler {
URL url;
HttpURLConnection httpURLConnection = null;
InputStream inputStream;
BufferedReader bufferedReader = null;
StringBuffer stringBuffer;
String strurl;
ClassA classA;
public HttpHandler(ClassA classA) {
this.classA = classA;
}
public void startLoadJsonString(String strurl){
new AsyncFeed(strurl).execute();
}
private class AsyncFeed extends AsyncTask<Void,Void,Void>{
String urlStr;
public AsyncFeed(String urlStr) {
this.urlStr=urlStr;
}
#Override
protected String doInBackground(Void... records) {
try {
url = new URL(urlStr);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
stringBuffer = new StringBuffer();
while ((line=bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedReader !=null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
httpURLConnection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
//f.e. show progress dialog
}
#Override
protected void onPostExecute(Void result) {
//now you have initialized stringBuffer so do what you want with it
//hide progress dialog
//call updateDataFromAsync from ClassA class and continue there
classA.updateDataFromAsync(String.valueOf(stringBuffer));
}
)
I try to execute an AsyncTask like this
private static final String REQUESTED_URL = "//my url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
EarthQuakeAsyncTask task = new EarthQuakeAsyncTask();
task.execute(REQUESTED_URL); //this is where the error is
}
but Android Studio said that it cannot resolve method execute(String). I'm having a tutorial from Udacity, their sample is pretty much similar
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL =
"//url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EarthquakeAsyncTask task = new EarthquakeAsyncTask();
task.execute(USGS_REQUEST_URL); //it works
}
Can someone tell me why this possibly occurs?
Edit: this is my EarthQuakeAsyncTask class:
private class EarthQuakeAsyncTask extends AsyncTask<URL,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(URL... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create URL object
URL url = createUrl(REQUESTED_URL);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
}
Your class signature suggests that you are expecting a URL type as parameter, but you are passing a String type in the execute() method. All you need to do is to change your class signature to expect a String as in the one in this code.
private class EarthQuakeAsyncTask extends AsyncTask<String,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(String... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create a URL object from the String passed to the execute method
URL url = createUrl(urls[0]);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
}
That is because your AsyncTask class isn't defined in a manner to handle the execute method with a String parameter. Let me explain myself.
The AsyncTask class you develop will look like this:
private class MyAsyncTask extends AsyncTask<TYPE1, TYPE2, TYPE3> {
protected TYPE3 doInBackground(TYPE1... type1_variables) {
// Do some long process here..
return variable_of_type_TYPE3;
}
protected void onPostExecute(TYPE3 result) {
// Do something here
}
}
So for you to call task.execute(REQUESTED_URL); you'd need to implement your AsyncTask class correctly.
For example it might look like this:
private class EarthQuakeAsyncTask extends AsyncTask<String, Void, Void> {
...
}
I am trying to get my webview to show a page that is only accesible after i am logged in. but whatever i try i cant get past the login url.
How can i open/show the SEND_VISUM_URL after i login.
this is what i have so far:
String LOGIN_URL = "http://10.35.50.125/BCS/index.php?module=";
String SEND_VISUM_URL = "http://10.35.50.1/BCS/index.php?module=ScanVisa&Action=save";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.webviewer);
webView.loadUrl(LOGIN_URL);
cookieManager = new CookieManager();
Button login = (Button) findViewById(R.id.PostData);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
new loginTask().execute(getLoginData());
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
public class loginTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String loginData = params[0];
String text = "";
BufferedReader reader = null;
// Send data
try {
// Defined URL where to send data
URL login_url = new URL(LOGIN_URL);
// getting cookies:
URLConnection conn = login_url.openConnection();
conn.connect();
// setting cookies
cookieManager.storeCookies(conn);
cookieManager.setCookies(login_url.openConnection());
cookiestring = cookieManager.toString();
Log.d("Cookie in logintask:", cookiestring);
conn.getContent();
conn.setDoOutput(true);
conn.setConnectTimeout(3000);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
try {
wr.write(loginData); //post
wr.flush();
} catch (Exception e) {
e.printStackTrace();
}
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (line.length() > 0) {
sb.append(line + "\n");
if (line == null) {
continue;
}
}
}
text = sb.toString();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (reader != null) reader.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return text;
}
protected void onPostExecute(String line) {
if (!line.contains("I107")) { //I107 is an error code that is returend when a login failed
Toast.makeText(getBaseContext(), "Login succesfull", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();
}
}
}
public void setCookies(URLConnection conn) throws IOException {
// let's determine the domain and path to retrieve the appropriate cookies
URL url = conn.getURL();
String domain = getDomainFromHost(url.getHost());
String path = url.getPath();
Map domainStore = (Map)store.get(domain);
if (domainStore == null) return;
StringBuffer cookieStringBuffer = new StringBuffer();
Iterator cookieNames = domainStore.keySet().iterator();
while(cookieNames.hasNext()) {
String cookieName = (String)cookieNames.next();
Map cookie = (Map)domainStore.get(cookieName);
// check cookie to ensure path matches and cookie is not expired
// if all is cool, add cookie to header string
if (comparePaths((String)cookie.get(PATH), path) && isNotExpired((String)cookie.get(EXPIRES))) {
cookieStringBuffer.append(cookieName);
cookieStringBuffer.append("=");
cookieStringBuffer.append((String)cookie.get(cookieName));
if (cookieNames.hasNext()) cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
}
}
try {
conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
} catch (java.lang.IllegalStateException ise) {
IOException ioe = new IOException("Illegal State! Cookies cannot be set on a URLConnection that is already connected. "
+ "Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
throw ioe;
}
}
any help would be greatly appreciated!
I am having an android application requirement where i need to open saved web pages, how to do the same?? FIrst of all, how can we save a webpage with its dependancies on android and later open it in your applications? Any inputs will be of great help!
First of all, let's save the webarchive from webview
private void initUI{
webView = (WebView) findViewById(R.id.webView);
AndroidWebClient client = new AndroidWebClient();
webView.setWebViewClient(client);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
}
private class AndroidWebClient extends WebViewClient {
#Override
public void onPageStarted(WebView view, String url,
android.graphics.Bitmap favicon) {
}
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.saveWebArchive(Environment.getExternalStorageDirectory()
+ File.separator +"myArchive"+".mht");
// our webarchive wull be available now at the above provided location with name "myArchive"+".mht"
}
public void onLoadResource(WebView view, String url) {
}
}
The way to save the webarchive is same in all APIs but to load it, varies
for API less than Kitkat
private void loadArchive(){
String rawData = null;
try {
rawData = getStringFromFile(Environment.getExternalStorageDirectory()
+ File.separator+"myArchive"+".mht");
} catch (Exception e) {
e.printStackTrace();
}
webView.loadDataWithBaseURL(null, rawData, "application/x-webarchive-xml", "UTF-8", null);
}
public String getStringFromFile (String filePath) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin);
//Make sure you close all streams.
fin.close();
return ret;
}
public String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
for Kitkat and above
private void loadArchive(){
webView.loadUrl("file:///"+Environment.getExternalStorageDirectory()
+ File.separator+"myArchive"+".mht");
}
This is how I would implement that:
Save original web page into a file
Parse saved file and get all image URLs. Save images into the same directory.
Convert URL of the images(bind all links to a local copies)
Here is simple code which demonstrate this idea:
String download(String url) throws Exception {
String filename = "local.html";
save(url, filename);
List<String> imageLinks = getImageURLs(filename);
for (String imageLink : imageLinks) {
String imageFileName = getImageName(imageLink);
save(imageLink, imageFileName);
}
convertImageURLs(filename);
return filename;
}
void save(String url, String saveTo) throws Exception {
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
conn.connect();
InputStream is = conn.getInputStream();
save(is, saveTo);
}
void save(InputStream is, String saveTo) {
// save actual content
}
List<String> getImageURLs(String localHtmlFile) {
// parse localHtmlFile and get all URLs for the images
return Collections.EMPTY_LIST;
}
String getImageName(String imageLink) {
// get image name, from url
return null;
}
void convertImageURLs(String localHtmlFile) {
// convert all URLs of the images, something like:
// <img src="original_url"> -> <img src="local_url">
}