Open Local Html File in Webview - Android - java

I have a saved a file in the root folder and am trying to open it in a webview.
This is my code for saving:
OutputStream outstream = null;
outstream = openFileOutput(fileName ,MODE_WORLD_READABLE);
/// if file the available for writing
if (outstream != null) {
/// prepare the file for writing
OutputStreamWriter outputreader = new OutputStreamWriter(outstream);
BufferedWriter buffwriter = new BufferedWriter(outputreader);
/// write the result into the file
buffwriter.write(result);
}
/// close the file
outstream.close();
} catch (java.io.FileNotFoundException e) {
System.out.println("File not found in the writing...");
} catch (IOException e) {
System.out.println("In the writing...");
}
This is my code for recalling the file:
fileView.getSettings().setJavaScriptEnabled(true);
fileView.loadUrl("file:///" + name); <---
and inside the app it gives me a file not found error.
Any insight is helpful.

WebView mWebView=(WebView)findViewById(R.id.mWebView);
mWebView.loadUrl("file:///book.html");
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setSaveFormData(true);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.setWebViewClient(new MyWebViewClient());
private class MyWebViewClient extends WebViewClient
{
#Override
//show the web page in webview but not in web browser
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl (url);
return true;
}
}
try this

Actually when you open a URL using file:///...
Then it means that you should save the file under assets directory (say test.html ).
Now suppose you have to access test.html file, you need to write like this
loadURL("file:///android_asset/test.html');

The path is wrong, assuming the exceptions weren't hit.
file:/// tells the browser to look for /name
openFileOutput(fileName) tells the app to write in <application-files-directory>/fileName
Your url should be "file:///"+getFilesDir()+File.separator+fileName

For files that will be bundled with the application you can add an "asset" folder to your project by right clicking your app in the project explorer then select
New=> Folder=> Assets Folder.
Add the HTML file to your asset folder then load it by:
fileView.loadUrl("file:///android_asset/"+name);
same URL can be used in your HTML to link to other HTML or CSS files.

You can read your asset file first and then display it on webview via asd
like this
BufferedReader read = null;
StringBuilder data = new StringBuilder();
try {
read = new BufferedReader(new InputStreamReader(getAssets().open("htmlFile.html"), "UTF-8"));
String webData;
while ((mLine = read.readLine()) != null) {
data.append(mline);
}
} catch (IOException e) {
log(",e.getmessage()) } finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log(",e.getmessage())
}
}
}
and then load this data in webview
webview.loadData(data, "text/html", "UTF-8");

Please refer to the youtube video https://youtu.be/n2KbDqoCv_Q?t=173
I've tested its solution and it works.

Related

Is there any criteria to judge a website is blank and has no content using Java?

My problem is as follows. Currently I`m doing a web crawling project for my final year. I want to crawl down web pages carrying out .org domains and archive for text mining. Having said about the background.
During the crawling process number of blank .org domain carrying websites also were detected. Is there any criteria we could use to refrain from crawling web sites having no content?
Currently I am passing the URL and it reads the URLs HTML content in Java. Although websites do not carry any content, still it has HTML code. So could you please suggest me a way of doing it?
I have tried figuring out text availability, image availability but it was not possible to stop 100% blank web pages detection.
Finally I was able to detect blank web pages depends on its size (below 3 KB) and by scanning the content. Firstly I download the HTML content via URLConnection and store it in memory.
public ArrayList<String> captureHtmlTags(String inputUrl) {
ArrayList<String> readWebsiteHTMLTags = new ArrayList<String>();
try {
URL url = new URL(inputUrl);
try {
URLConnection connection = url.openConnection();
// open the stream and assign it into buffered reader..
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
if (bufferedReader.readLine() != null) {
while ((inputLine = bufferedReader.readLine()) != null) {
Document doc = Jsoup.parse(inputLine);
readWebsiteHTMLTags.add(String.valueOf(doc));
}
bufferedReader.close();
readWebsiteHTMLTags.size();
} else {
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
return readWebsiteHTMLTags;
}
Then using iText 7 library I convert read HTML into PDF and scan for text contents.
public String convertWebsiteToPdf(ArrayList<String> htmlCode) {
String generateHtmlPage = null;
String fileLocation = CONST_FILE_PATH; // path to save the PDFs
generateHtmlPage = htmlCode.toString();
FileOutputStream fileOutputStream = null;
try {
try {
fileOutputStream = new FileOutputStream(fileLocation);
HtmlConverter.convertToPdf(generateHtmlPage, fileOutputStream);
fileOutputStream.close();
} catch (Exception e) {
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return fileLocation;
}
If no content found along with the low size of file, I consider it as a Blank web page.
It worked out finally.

Download Google Docs file from Google Drive with java

I am trying to download a file from Google Drive. Download of a common file (pdf, jpg) went without any problem. But I can't get it to download Google files. I am getting an empty file without type and with size 0. Do you have any idea of what might cause this?
public InputStream download(String id) throws CloudServiceException {
try {
File file = service.files()
.get(id)
.execute();
String link = file.getExportLinks().get("application/pdf");
HttpResponse resp = service.getRequestFactory()
.buildGetRequest(
new GenericUrl(link))
.execute();
return resp.getContent();
} catch (HttpResponseException e) {
throw CloudServiceExceptionTransformer.transform(e, e.getStatusCode());
} catch(IOException ex) {
throw new InternalException(ex);
}
}
You need to use Export method for downloading google docs or any google files
String fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().export(fileId, "application/pdf")
.executeMediaAndDownloadTo(outputStream);
You can try this:
URL url = new URL("http://www.gaertner-servatius.de/images/sinnfrage/kapitel-2/spacetime.gif");
InputStream inStream = url.openStream();
Files.copy(inStream, Paths.get("foobar.gif"), StandardCopyOption.REPLACE_EXISTING);
inStream.close();
Try this:
com.google.api.services.drive.Drive service;
static InputStream download(String id) {
if (service != null && id != null) try {
com.google.api.services.drive.model.File gFl =
service.files().get(id).setFields("downloadUrl").execute();
if (gFl != null){
return service.getRequestFactory()
.buildGetRequest(new GenericUrl(gFl.getDownloadUrl())).execute().getContent());
}
} catch (Exception e) { e.printStackTrace(); }
return null;
}
Good Luck
So the problem was in fact in building of a response. Google files have a size 0 and google media type was not recognized which resulted in this broken file.
Edit: Here is my working version. I removed the set size so that it downloads those 0 sized files.
ResponseEntity.BodyBuilder builder = ResponseEntity.status(HttpStatus.OK)
.header(HttpHeaders.CONTENT_DISPOSITION, encoding)
.contentType(MediaType.parseMediaType(resource.getMimeType()));
return builder.body(new InputStreamResource(resource.getContent()));

Android File.exists() is always true

I'm trying to copy files from the assets folder to the device folder using this function:
public static void copyJSON(Context aContext) {
AssetManager assetManager = aContext.getResources().getAssets();
String[] pFiles = null;
try {
pFiles = assetManager.list("ConfigurationFiles");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (pFiles != null) for (String pJsonFileName : pFiles) {
InputStream tIn = null;
OutputStream tOut = null;
try {
tIn = assetManager.open("ConfigurationFiles" + File.separator + pJsonFileName);
String[] pList = aContext.getFilesDir().list(); //just for test
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
tOut = new FileOutputStream(pOutFile);
if (pOutFile.exists()) {
copyFile(tIn, tOut);
}
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + pJsonFileName, e);
} finally {
if (tIn != null) {
try {
tIn.close();
} catch (IOException e) {
Log.e("tag", "Fail closing", e);
}
}
if (tOut != null) {
try {
tOut.close();
} catch (IOException e) {
Log.e("tag", "Fail closing", e);
}
}
}
}
}
If I delete the App and run the code, the variable pList is empty as I expect but the pOutFile.exists()returns true ALWAYS!!.
I don't want to copy them again every time I open my App, and I'm doing this because all my app uses JSON to navigate thru all the screens, so If I change any value in my BBDD a WS send a new JSON file and the App respond in accordance for example a button is no longer needed, so the first time you download my App I copy the original JSON and then if you use the app an if you have internet connection you will download a new JSON file that it is more accurate than the one that is in the Bundle and it will be override, this is because as far as I know I can't change the files that are in the assets folder.
I have read everywhere and all say the same use this:
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
And then ask for this:
pOutFile.exists()
I don't know what I'm doing wrong.
Thanks for all your help.
put it this way:
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
if (pOutFile.exists()) {
tOut = new FileOutputStream(pOutFile);
copyFile(tIn, tOut);
}
and everything should work fine. Remember the FileOutputStream creates the file it should stream to if possible and non existing
The problem is you're essentially creating a file and then checking if it exists.
try {
tIn = assetManager.open("ConfigurationFiles" + File.separator + pJsonFileName);
String[] pList = aContext.getFilesDir().list(); //just for test
File pOutFile = new File(aContext.getFilesDir(), pJsonFileName);
// See here: you're creating a file right here
tOut = new FileOutputStream(pOutFile);
// And that file will be created in the exact location of the file
// you're trying to check:
if (pOutFile.exists()) { // Will always be true if FileOutputStream was successful
copyFile(tIn, tOut);
}
}
You should instead create your FileOutputStream AFTER you've done your existence check.
Source: http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
A file that you have just created without getting an exception always exists. The test is pointless. Remove it.

Reading a file from a Res folder

I have put a file "template.html" inside RAW folder and I want to read it into a InputStream. But it is returning me null. Can't understand what is wrong in the below code
e.g. fileName passed as parameter is "res/raw/testtemplate.html"
public String getFile(String fileName) {
InputStream input = this.getClass().getClassLoader().getResourceAsStream(fileName);
return getStringFromInputStream(input);
}
Also, there might be a better solution by putting these files in a particular subfolder and putting it inside Asset folder but then I believe I would need to pass context in AssetManager. I don't understand that solution, sorry I am new to android development. Can someone shed some light regarding how this approach can be achieved.
EDIT
I have started implementing this solution with Assets. Below method is supposed to return a string containing the entire text of the file stored as template.html.
getFile("template.html") // I am sending extension this time
Problem getting error getAssets() is undefined.
public String getFile(String fileName) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
String line;
try {
reader = new BufferedReader(new InputStreamReader(getAssets().open(fileName)));
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
use this
new BufferedInputStream(getResources().openRawResource(filepath));
this will return a buffered input stream
The file name should be without extension :
InputStream ins = getResources().openRawResource(
getResources().getIdentifier("raw/FILENAME_WITHOUT_EXTENSION",
"raw", getPackageName()));
For this purposes uses assets folder:
assets/
This is empty. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original filename is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
So, you could easy get access at assets with context: context.getAssets()
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(context.getAssets().open("filename.txt")));
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}

java.io.FileNotFoundException when uploading a file from a JSP

I have coded a AJAX file upload feature in my application. It works perfectly when running it from my laptop. When I try the exact same file using the same app, but deployed on a jBoss server, I get the following exception:
2013-02-18 11:30:02,796 ERROR [STDERR] java.io.FileNotFoundException: C:\Users\MyUser\Desktop\TestFile.pdf (The system cannot find the file specified).
getFileData method:
private byte[] getFileData(File file) {
FileInputStream fileInputStream = null;
byte[] bytFileData = null;
try {
fileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
if (fileInputStream != null) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytBuffer = new byte[1024];
try {
for (int readNum; (readNum = fileInputStream.read(bytBuffer)) != -1;) {
byteArrayOutputStream.write(bytBuffer, 0, readNum);
}
} catch (IOException e) {
e.printStackTrace();
}
bytFileData = byteArrayOutputStream.toByteArray();
}
return bytFileData;
}
Getting the file content in a variable (from the method above):
byte[] bytFileData = this.getFileData(file);
Making the file:
private boolean makeFile(File folderToMake, File fileToMake, byte[] bytFileData) {
Boolean booSuccess = false;
FileOutputStream fileOutputStream = null;
try {
if (!folderToMake.exists()) {
folderToMake.mkdirs();
}
if (!fileToMake.exists()) {
if (fileToMake.createNewFile() == true) {
booSuccess = true;
fileOutputStream = new FileOutputStream(fileToMake);
fileOutputStream.write(bytFileData);
fileOutputStream.flush();
fileOutputStream.close();
}
}
} catch (Exception e) {
e.printStackTrace();
booSuccess = false;
}
return booSuccess;
}
Any idea?
Thank you
Charles
It seems you're just passing the file path as part of the request to the server, not actually uploading the file, then attempting to use that file path to access the file.
That will work on your laptop because the code, when running locally, has access to your file system and will be able to locate the file. It won't work deployed on a server because it's an entirely separate machine, and as a result won't have access to your file system.
You'll need to modify your client-side (AJAX) code to actually upload the file, then modify your server-side code to use that uploaded file. Note that AJAX file uploads aren't generally possible - there are plugins for frameworks such as jQuery that provide this functionality using workarounds.
I'm not 100%, but I think proper AJAX file uploads may be possible using HTML5 features, but browser support for that is likely going to be pretty poor right now.

Categories