Trouble at downloading sqlite database - java

My app needs to download a database from a link, heres the code I use to download the database adn save it on the sd card:
public void DownloadBD() {
try {
URL url = new URL(
"http://mylink/dbHandler.axd?SqliteDbVersion=0");
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
File SDCardRoot = Environment.getExternalStorageDirectory();
File file = new File(SDCardRoot, "DirLaguna.db");
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
}
fileOutput.close();
location = file.getAbsolutePath();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Everything seems to work fine, but at the moment I want to query the database (I'm using raw querys) an error appears saying that the tables don't exist.
After that, I tried debugging the application, and after that I get the error saying that the database is corrupted. I think that the downloading process is what is making the database corrupt.
Any help will be apreciated, if I'm missing some code to share please tell me so!
Thanks in advance!

1) The database you are downloading is sqlite database?
2) If yes, then you need to copy that in your application before you start using it.
The process will be something like you download the database in your Sd Card and as soon as its completed start copying it into your application so as it becomes part of your application, like this: http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
Make this happen in background by separate thread and then you are good to go and use it. Let me know if you face any problem or issue or I didn't provided you info what you meant.
Thanks

I suggest that first - you verify if the file is indeed a proper SQLite Database by moving it to your local machine filesystem and viewing it in a SQLite viewer application.
Several SQLite Database viewers are available. This post lists several of them : What are good open source GUI SQLite database managers?
This additional post discusses readymade database usage in Android : Ship an application with a database You can get several pointers from there.

Related

Rendering big Post Script file with Ghost4J in Java

i made a Java application whose purpose is to offer a Print Preview for PS files.
My program uses Ghostscript and Ghost4J to load the Post Script file and produces a list of Images (one for each page) using the SimpleRenderer.render method. Then using a simple JList i show only the image corresponding to the page the user selected in JList.
This worked fine until a really big PS file occurred, causing an OutOfMemoryError when executing the code
PSDocument pdocument = new PSDocument(new File(filename));
I know that is possibile to read a file a little at a time using InputStreams, the problem is that i can't think of a way to connect the bytes that i read with the actual pages of the document.
Example, i tried to read from PS file 100 MB at a time
int buffer_size = 100000000;
byte[] buffer = new byte[buffer_size];
FileInputStream partial = new FileInputStream(filename);
partial.read(buffer, 0, buffer_size);
document.load(new ByteArrayInputStream(buffer));
SimpleRenderer renderer = new SimpleRenderer();
//how many pages do i have to read?
List<Image> images = renderer.render(document, firstpage ??, lastpage ??);
Am i missing some Ghost4J functionality to read partially a file?
Or has someone other suggestions / approaches about how to solve this problem in different ways?
I am really struggling
I found out I can use Ghost4J Core API to retrieve from a Post Script file a reduced set of pages as Images.
Ghostscript gs = Ghostscript.getInstance();
String[] gsArgs = new String[9];
gsArgs[0] = "-dQUIET";
gsArgs[1] = "-dNOPAUSE";
gsArgs[2] = "-dBATCH";
gsArgs[3] = "-dSAFER";
gsArgs[4] = "-sDEVICE=display";
gsArgs[5] = "-sDisplayHandle=0";
gsArgs[6] = "-dDisplayFormat=16#804";
gsArgs[7] = "-sPageList="+firstPage+"-"+lastPage;
gsArgs[8] = "-f"+filename;
//create display callback (capture display output pages as images)
ImageWriterDisplayCallback displayCallback = new ImageWriterDisplayCallback();
//set display callback
gs.setDisplayCallback(displayCallback);
//run PostScript (also works with PDF) and exit interpreter
try {
gs.initialize(gsArgs);
gs.exit();
Ghostscript.deleteInstance();
} catch (GhostscriptException e) {
System.out.println("ERROR: " + e.getMessage());
e.printStackTrace();
}
return displayCallback.getImages(); //return List<Images>
This solve the problem of rendering page as images in the preview.
However, i could not find a way to use Ghost4J to know total number of pages of PS file (in case the file is too big for opening it with Document.load()).
So, i am still here needing some help

How to view and edit files that were created and are used by my Android app?

So I've created this simple app that asks the user questions (it's like a truth or dare game).
The questions are saved in a .json-file in SD-Card > Android > data > [package name] > files.
I want to make it possible, however, to add or delete those questions by manually editing or exchanging that .json-file in which the questions are saved (so that those new questions then appear in the app).
I already understand that the app needs to call the getExternalFilesDir() method somewhere, so that a directory that I can find in the device's file manager is created in the first place. However - as you probably have guessed - when I open that directory, the "files" folder is empty. (I know the .json-files must be in there since the app is working fine!)
Now my question:
Is there any way I can view and edit those .json-files? I don't care if the solution includes using a PC or some program.
Or should I maybe not save the questions in a .json-file but in a .txt-file instead? Or should I use a different directory to save my question files to begin with??
I would appreciate a detailed answer, since I'm obviously new.
Thanks in advance!
P.S.: I can include code on request.
EDIT: I don't want to edit those files from code, I already know how to do that. My question in particular is about whether there is a possibility to edit the json files using a text editor for example or exchanging the files using copy paste.
Code:
public void copy() {
Context Context = getApplicationContext();
String DestinationFile = Context.getExternalFilesDir(null).getPath() + File.separator + "fragenAdvanced.json";
if (!new File(DestinationFile).exists()) {
try {
CopyFromAssetsToStorage(Context, "fragenAdvanced.json", DestinationFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void CopyFromAssetsToStorage(Context Context, String SourceFile, String DestinationFile) throws IOException {
InputStream IS = Context.getAssets().open(SourceFile);
OutputStream OS = new FileOutputStream(DestinationFile);
CopyStream(IS, OS);
OS.flush();
OS.close();
IS.close();
}
private void CopyStream(InputStream Input, OutputStream Output) throws IOException { //brauche ich das?
byte[] buffer = new byte[5120];
int length = Input.read(buffer);
while (length > 0) {
Output.write(buffer, 0, length);
length = Input.read(buffer);
}
}
This is how I save the file to storage.
there is 3 way to save your user data but your way is not secure because the user has access on it.
the first way is saving user data in SharedPreferences , it's very simple to use , but if user clears the app catch, the data will be deleted ( you can just convert your json to string and save it in sharedPreferences , for converting string to json you can use Gson library )
second way is using SQlite and save data on local database , it will be deleted by clear stroge and still not good for important data
the final way is using remote database and get data from api

Getting the jsp source code appended with the file content when I download files

I am working on a File upload/download functionality, in Java using Struts2 framework, where we are uploading to and downloading from a remote server path. All seems to work fine when I check the functionality at my local machine with a local path as the destined path from where i am downloading and to which am uploading the files of any format. The development environment has JBoss server.
But when I run the same over at the prod env, where the application is deployed in Weblogic server, files of .txt,.csv,.html (basically text format files) have my jsp source code appended to the file content.
Below is the code that I have used for downloading:
BufferedOutputStream bout=null;
FileInputStream inStream = null;
byte[] buffer = null;
try {
inStream = new FileInputStream(path+File.separator+filename);
buffer = new byte[8192];
String extension = "";
int pos = filename.lastIndexOf(".");
if (pos > 0)
extension = filename.substring(pos+1);
int bytesRead = 0, bytesBuffered = 0;
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment; filename="+ filename);
bout = new BufferedOutputStream(response.getOutputStream());
while((bytesRead = fistrm.read(buffer)) > -1){
bout.write(buffer, 0, bytesRead);
bytesBuffered += bytesRead;
if(bytesBuffered > 1048576){
bytesBuffered = 0;
bout.flush();
}
}
} catch (IOException e) {
log.error(Logger.getStackTrace(e));
} finally {
if(bout!=null){
bout.flush();
bout.close();
}
if(inStream!=null)
inStream.close();
}
I have tried using different response content types with respect to the extension, but it was of no help.
Seems like the outputstream has the jsp source code in it even before writing from the inputstream.
Can anyone please suggest a solution and explain why is this happening ?
It is happening because you are writing directly in the outputstream, and then returning a struts result, that is your JSP. You are using an action as if it would be a servlet, which is not.
In Struts2, to achieve your goal, you need to use the Stream result type, as described in the following answers:
https://stackoverflow.com/a/16300376/1654265
https://stackoverflow.com/a/16900840/1654265
Otherwise, if you want to bypass the framework mechanisms and manually write to the outputStream by yourself (there are very rare cases in which it is useful, like downloading dynamically created ZIP), then you must return the NONE result.
Returning ActionSupport.NONE (or null) from an Action class method causes the results processing to be skipped. This is useful if the action fully handles the result processing such as writing directly to the HttpServletResponse OutputStream.
But I strongly suggest you to go with the Stream result, the standard way.

File from InputStream

Yes, this question has been asked a millions times, and I believe I've looked at them all. They are very "sometimesy", slow, or not what I need.
On one project, I use the following code to use the InputStream received from a GET to turn that into a PDF. This works PERFECTLY, every time, on my physical device and my emulator (Genymotion 2.1.1, Emulator API 18 4.3). Note that some things are edited out, and the PDFs are generally small, less than 1 MB.
public abstract class MyPDFFile extends File implements ApiModel{
public MyPDFFile(InputStream inputStream){
super(context.getExternalFilesDir(
Environment.DIRECTORY_DOWNLOADS), "my_pdf.pdf");
if (externalStorageIsWritable()) {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
FileOutputStream fileInputStream = new FileOutputStream(this);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileInputStream));
int readLine;
char[] cbuf = new char[1];
do {
readLine = bufferedReader.read(cbuf);
bufferedWriter.write(cbuf);
} while (readLine != -1);
bufferedWriter.close();
}
catch(IOException e){
// Didn't work
}
}
else{
// Cant write
}
}
I figured on this new project, I could use the same code to download an APK from the internet to the device. Nope, definitely not the case. I eventually tried this for Inputstream to File:
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] buffer = new byte[1];
while ( (read(buffer)) > 0 ) {
fileOutputStream.write(buffer);
}
fileOutputStream.close();
close();
That works on my emulator, and works fine. I moved to testing on my device... not so much, which is weird, because the working PDF code works on both my emulator and device. I've tried adjusting the size of my buffer to various multiples of 512 (which results in the file being EXTREMELY small, like a few KB, to being EXTREMELY large, about double the apk size, which is about 5.6 MB).
Also, another weird thing: I can NEVER get it to successfully save outside of the constructor. When I do the saving there, the InputStream is fine, my file gets created, yadayada, and when I use successful code, I just rename the file afterwards since all I have access to in the constructor is the InputStream. If I decide "No, I want to name it when I have the proper things" and simply save the InputStream to my object, it NEVER works properly. Can never get above 4KB for the downloaded file. I've tried extends InputStream and extends BufferedInputStream to no avail.
I can post more code if needed. All I would have access to is the InputStream from my GET request; I'm using the browep Android HTTP library and that's all I can get without trying to mess with the library itself (or overriding methods in it).
The problem is that you're reading the file byte by byte. This can take ton of time. Instead, read the file in bigger piece of chunks, like 4 or 8 KBs:
int file_chunk_size = 1024 * 4; //4KBs, written like this to easily change it to 8
byte[] buffer = new byte[file_chunk_size];
int bytesRead = 0;
while ( (bytesRead = read(buffer)) > 0 ) {
fileOutputStream.write(buffer, 0, bytesRead);
}

How to play .wav file from URL in web browser embed - Java

I want to play a .wav sound file in embed default media player in IE. Sound file is on some HTTP location. I am unable to sound it in that player.
Following is the code.
URL url = new URL("http://www.concidel.com/upload/myfile.wav");
URLConnection urlc = url.openConnection();
InputStream is = (InputStream)urlc.getInputStream();
fileBytes = new byte[is.available()];
while (is.read(fileBytes,0,fileBytes.length)!=-1){}
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(fileBytes);
Here is embed code of HTML.
<embed src="CallStatesTreeAction.do?ivrCallId=${requestScope.vo.callId}&agentId=${requestScope.vo.agentId}" type="application/x-mplayer2" autostart="0" playcount="1" style="width: 40%; height: 45" />
If I write in FileOutputStream then it plays well
If I replace my code of getting file from URL to my local hard disk. then it also works fine.
I don't know why I am unable to play file from HTTP. And why it plays well from local hard disk.
Please help.
Make sure you set the correct response type. IE is very picky in that regard.
[EDIT] Your copy loop is broken. Try this code:
URL url = new URL("http://www.concidel.com/upload/myfile.wav");
URLConnection urlc = url.openConnection();
InputStream is = (InputStream)urlc.getInputStream();
fileBytes = new byte[is.available()];
int len;
while ( (len = is.read(fileBytes,0,fileBytes.length)) !=-1){
response.getOutputStream.write(fileBytes, 0, len);
}
The problem with your code is: If the data isn't fetched in a single call to is.read(), it's not appended to fileBytes but instead the first bytes are overwritten.
Also, the output stream which you get from the response is already buffered.

Categories