Verify sqlite database before import into android app - android

I have an app in which I have added Export/Import DB functionality... I want to do two things:
1) When exporting: Scramble the exported database so that normal folks (I know that some people can decode the best camouflage techniques) cannot read the contents...
2) When importing: Verify the file being imported to make sure that it is something that will work with my app and not anything else.
I have seen some links here about encryption that can address the 1st point here. But I dont want to do encryption. I want to do some simple scrambling. And I have seen some posts about verifying the table contents by checking for the tables that my application looks for. That is a good solution but i need to load the file first to verify and roll back if there are errors.
Any help would be greatly appreciated...

very very simple way: add some header to the file which you can later read back in and check:
// w/o exception handling finally etc
String secret = "zomg,secret";
byte[] header = secret.getBytes();
byte[] buffer = new byte[4096];
FileInputStream in = new FileInputStream("/your/sqlite.db");
FileOutputStream out = new FileOutputStream("/sdcard/the.secretfile");
out.write(header);
int read = 0;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
in.close();

The best and simple way to deal with this is to generate Checksum (MD5) of your database file and compare with your per-calculated one. For more info

So I finally settled to doing DES encryption using cipherinputstream and instead of adding a header to verify the integrity, I am checking to see if all my table names are present in the file being imported. I saw that the sqlite DB file has the ddl statements in clear text. This is probably not the most elegant/complete solution but it works.

Related

REST Server for uploading and downloading documents

I wrote an android application that part of it is to handle upload and download documents. Currently I am using the Microsoft Azure server to save the files on.
The way I am currently doing it is by turning the files to a string and saving it that way on the Azure server:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis;
try {
fis = new FileInputStream(new File(Uridata.getPath()));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
} catch (Exception e) {
e.printStackTrace();
}
byte[] bbytes = baos.toByteArray();
item.setStringFile(Base64.encodeToString(bbytes, Base64.URL_SAFE));
item.setName(Uridata.getLastPathSegment());
where item is my class that saves the string representation and the name of the file and is being loaded to the Azure, Uridata is an Uri instance of the file chosen.
I have one main problem with this solution and it is the limit on the file size.
I am searching for a good server to use instead of the Azure (maybe a RESET one) and if there is a better way to save files of all kinds (pdf, word...).
I will also want in the future to use the same data in a web interface
Does anybody have any suggestions on how to do it?
Thanks in advance!
To start, you don't have to transform the file into a string, you can just save it as a file. You have the possibility of losing data by continuing to do that. See: How do I save a stream to a file in C#?
If you're looking for another service to save files, then you should look into Azure Blob Storage. It will allow you to upload as much data as you want to a storage service for arbitrary files. See for example:
https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/

Cancel GetObjectRequest Amazon S3

I download an image from S3 using their SDK as follows:
s3Client.getObject(new GetObjectRequest("a24images", s3FileURLString), file);
However, I can't find anything in the docs to indicate how to:
• cancel a request
• pause a request
Any advice on implementing cancel and pause on these requests would be appreciated please.
The variant of the getObject method you are using may not allow for cancellation, but if you just use the more basic s3Client.getObject(
new GetObjectRequest(bucketName, key)); then this should just give you a reference to an input stream as already mentioned by sanket.
There is not really much "optimization" being done here, but if you wanted to see or reuse the code that Amazon itself uses it's here:
https://github.com/aws/aws-sdk-java/blob/master/src/main/java/com/amazonaws/services/s3/internal/ServiceUtils.java?source=c#L236
As far as I know, the:
S3Object object = s3.getObject(new GetObjectRequest(bucketname, key));
will give you a handler to the object. You would further need to read the object to either a file system or an output stream like this:
InputStream is = object.getObjectContent();
int read = 0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
The while loop above will actually read the object from S3 and in this case convert it to an OutputStream.
You may want to look at controlling the while loop with a boolean value that you can set from wherever you need to cancel this request.
Is this what you need to achieve ?
Or have I got the question wrong ?
This answer is in terms with the java sdk.
Thanks
try with this.
myS3Client.shutdown();
but i did manual tracking i just take one Boolean and when user try to cancel then it will be false and the time when download from s3 just check weather it is true or false if false then i delete that file from my side in sdcard.

Android Creating a memory resident input file that can be attached to an email

The final objective will be clear shortly.
I want to create a file object and instead of getting data from a real physical file I want to provide the buffer myself.
Then, I want to use this file, which does not really exist in the sdcard or anywhere outside my app, give it a name and send it by email as an attachment (using the EXTRA_STREAM).
I found the following bit of code, by Adriaan Koster (#adriaankoster), the post Write byte[] to File in Java
// convert byte[] to File
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
File fileFromBytes = (File) ois.readObject();
bis.close();
ois.close();
System.out.println(fileFromBytes);
I used it to create this function
private File fileFromBytes(byte[] buf) {
File f = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(bis);
f = (File) ois.readObject();
bis.close();
ois.close();
}
catch (Exception e) {}
return f;
}
and here is where I am stuck, because when I use it:
// When sent as body the mail is sent OK
// emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());
// When I try to attach the mail is empty
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileFromBytes(dump().getBytes()));
I know from examples I've seen the second argument should be an URI, but: How do I create a virtual URI to fit my file?
EDIT:
The option to attach data directly from within the application is important to certain kind of applications. Namely, security & banking applications that do not want to move sensitive data around too much. Surely if the data does not reach the sdcard and goes directly to a mail attachment it is harder to sniff than within the application memory.
This is not my specific case, but I wanted to point out that this capability is important to have.
The first thing you'll want to do, I imagine, is create a ContentProvider. You can see an example implementation here
https://github.com/dskinner/AndroidWeb/blob/master/src/org/tsg/web/WebContentProvider.java
where in the above link's case, you would add this to your AndroidManifest.xml
<provider
android:name="org.tsg.web.WebContentProvider"
android:authorities="your.package.name" />
Now, you'll have a content uri available for use, content://your.package.name/.
The portion of the above ContentProvider your interested in, again I imagine, is the openFile method. When sharing data by intent across apps, certain things are expected. In your case, you're looking to share some byte data that's meant to be attached to the email.
So if you pass in a content uri to the email app such as content://your.package.name/foo with the appropriate intent flags, then openFile will get called on your ContentProvider. In this case, you can inspect the end of the uri segment to see foo was requested, and return appropriately.
The next issue you bring up is not having the file actually on disk. While I can't vouch for the method you used above (though it looks kosher), what you need to be returning is a ParcelFileDescriptor from your ContentProvider. If you look at the link I provided, you could possibly try to use that as a sample to get the file descriptor from your File object (my knowledge waivers here), but I imagine, the data simply wont be available at that point.
What you do bring up is security though. It's important to note that you can write data to disk privately so only the app has access to the data. I believe, but you might want to double check on this, if that data is private to the app, you can expose it via the ContentProvider and possibly lock down who and how the provider gets used, who can call it, etc. You may want to dig into android docs for that portion or look at some other SO questions.
Anyway, good luck.
Create the file in the application's cache directory. It will be created in the internal filesystem. Use 'getCacheDir()' API for getting the path to the cache dir. Write the data into this dir and then get the URI from the File object using ' Uri.fromFile (File file) '. When you are finished with the file, delete it.
Your application's cache is only available to your app, hence its safe to use for your purpose.
You can do some encryption if the data is too critical.
I think in order to do this, you are going to have to expose a ContentProvider, which will allow you handle a URI. The email application should then openInputStream on your URI, at which point you return an InputStream on your in-memory data.
I've not tried it, but in theory this should work.
i was busy with adding attachment to mail and i can send mail with attachment.
if you want to take a look: can not send mail with attachment in Android

Unzip single file from .zip file with multiple files in android

I am trying to obtain only one file (I know its name) from very large zip archive. This archive include around 100000 files because I do not want find my file in loop. I think that must be some solution for this case, something like command on Linux.
unzip archive.zip myfile.txt
I wrote following code
try {
FileInputStream fin = new FileInputStream(rootDir+"/archive.zip");
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = new ZipEntry("myfile.txt");
FileOutputStream fout = new FileOutputStream(rootDir+"/buff/" + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
This code create new file in buff directory, but this file is empty!
Please, help me with this trouble!
Thanks for your time!
I'm fairly new to Java, but the API documentation contains a pretty reasonable amount of information for the standard Java libraries, including for java.util.zip. Going from there into the ZipFile Entry, you can scroll down to the method listing to find a method called getEntry. This seems to be the route you should start with!
EDIT: bear in mind that you will probably need to include the directory (e.g.: "dir\subdirF\subdirW\FileThatYouWant.txt") when making the call, since that seems to be the way the files are named when you go through one-by-one.
EDIT 2: a considerable wealth of information is available here: Compressing and Decompressing Data Using Java APIs, if you're willing to read a bit :D.
Subject to memory constraints, the only reasonable solution for you might be to use a ZipInputStream object, which AFAIK will require you to step through each ZipEntry in the archive (on average 50,000?), but will not require you to load the entire file into memory. As far as performance, I would guess manually stepping through would be just as efficient as any current implementation of this niche functionality.

having trouble reading and writing to internal storage android

I'm writing a simple budget app for myself, and I'm having trouble figuring out how to write to internal storage. I don't seem to be writing to the file properly, and I can't find any more in depth examples than the Data Storage article on developer.android.com
Basically, I'm trying to write a test float to the MyBalance file, then read it into balance. In my actual code I use try/catch statements around the file in/out operations, but I skipped them to make the code more readable.
float test = 55;
float balance;
byte[] buffer = null;
FileOutputStream fos = openFileOutput( "MyBalance", Context.MODE_PRIVATE );
fos.write(Float.floatToRawIntBits(balance));
fis.read(buffer); //null pointer
ByteBuffer b = ByteBuffer.wrap(buffer);
balance=b.getFloat();
That's the gist of it, anyone see what I'm doing wrong?
Edit:
Thanks for the reply, I went ahead and converted to/from String like you suggested, but I still don't think the file is being created. I have an if statement that reads from it if it exists in onResume() and it isn't being run. Lemme post some of my code.
Here's how I'm writing the file, (setbal is an EditText and balanceview is a TextView):
balance = Float.valueOf(setbal.getText().toString());
balanceview.setText(setbal.getText());
balstring = String.valueOf(balance);
for (int i = 0; i < balstring.length(); ++i)
try {
fos.write((byte)balstring.charAt(i));
} catch (IOException e) {
e.printStackTrace();
}
I check if the file exists in onResume() like so:
File file = new File("data/data/com.v1nsai.mibudget/balance.txt");
Is that where an internal file for that context would be stored?
So this isn't exactly what you asked for, but this is how I have it working for Strings, and it may be helpful to you to see. (You could box the primatives and toString them of course if you wanted to use this code.)
Writing
FileOutputStream fos = context.openFileOutput("savedstate.txt", 0);
for (int i = 0; i < out.length(); ++i)
fos.write((byte)out.charAt(i));
Reading
StringBuilder inb = new StringBuilder();
FileInputStream fis = this.mContext.openFileInput("savedstate.txt");
int ch;
while((ch = fis.read()) != -1)
inb.append((char)ch);
Update
One thought that springs to mind is that you may not want to trust using a File object with a hand typed full path to the file. Instead, just use the FileInputStream with the context object and a relative path like in my code, then see if you get a String back of some length or something like that, or an exception that the file doesn't exist.
If you are really curious of where the file is created, or want to see it with your own eyes, I believe you can browse to it on your phone through the file manager in DDMS.
One last thing, I would suggest moving the try/catch block outside of your writing loop. Since it is an identical task being repeated, there is no need for the overhead of that approach, though it is typically good practice to minimize the size of your try/catch blocks.
Ok really one last thing, if you want to use the File object with the full path, you might want to have the path be the following:
File file = new File("/data/data/com.v1nsai.mibudget/balance.txt");
The beginning slash may make all the difference.

Categories

Resources