SQLite insert command not working with images - android

It was working very well. But when i put image broked. Before doesn´t exist "foto". But I need save a property type BLOB. But I dont´t know why is broking.
Bitmap bitmap = imageViewProeto.getDrawingCache();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
if(bitmap != null){
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
}
//byte[] data = baos.toByteArray();
byte[] data = stream.toByteArray();
bitmap.recycle();
boolean isOk = validarCampos();
if(!isOk){
String query = "INSERT INTO projetos (nome, descricao, url, foto, voluntario_id ) " +
"VALUES ('"+ nomeDigitado +"','"+descricaoDigitada+ "','"+urlDigitada+"', "+ data +" , " + testeId + ")";
bancoDados.execSQL(query);

A blob needs to be inserted as a string of hex numbers enclosed in single quotes and prefixed by x e.g.
"INSERT INTO projetos (nome, descricao, url, foto, voluntario_id ) " +
"VALUES ('"+ nomeDigitado +"','"+descricaoDigitada+ "','"+urlDigitada+"', x'000102030405060708090a0b0c' , " + testeId + ")";
x'000102030405060708090a0b0c' is just an example of the format using some arbritary value that would very likely not be an image.
As such you'd need to convert the byte[] to the respective value. However, if you use the SQLiteDatabase insert convenience method rather then execSQL then the conversion is performed by the method and thus the value can be passed as a byte[].
e.g. you could use :-
ContentValues() cv = new ContentValues();
cv.put(nome,nomeDigitado);
cv.put(nomeDigitado,descricaoDigitada);
cv.put(foto,data);
cv.put(voluntario_id,testeId);
cv.put(url,urlDigitada); //<<<<< note out of order but the correct SQL will be built
long rowid = bancoDados.insert("projetos",null,cv);
In addition to conveniently handling byte[]'s the insert method also has the fowlling advantages :-
it returns the rowid of the inserted row or -1 if the row was not inserted.
it also offers protection against SQL Injection.
it builds the underlying SQL (for insertion via VALUES)
HOWEVER, if the byte[] is around 2MB or greater then you will not be able to retrieve the BLOB as there is a 2MB size limit for a Cursor Window (a buffer into which complete rows are placed). There may also be issues with smaller byte[] as the process for retrieving the data can be relatively slow.
It is recommended to rather save the path to the respective image which is stored as a file. However, saving images (byte[]) as BLOBs that are around about 100KB can be more efficient.

Related

how to import pictures from SQLite Data base?

I am doing a project on Contacts For this , I need to Import/Store Pictures in SQlite DataBase.From what I have read , I have to convert the picture into a different format (maybe wrong in this assumption) and then store it in the data Base . Can you please tell me how can I do it or can I use a different method to do it?Both would be helpful for me , so that I can learn a bit more.
Thank You,
Depending on where you want to get the picture from, whether from the internet or from the sdcard. However, I'm assuming that you can get it and convert it into a bitmap.
Bitmap bm = (get it from anywhere);
ByteArrayOutputStream blob = new ByteArrayOutputStream();
//the below line is used if you like to scale it down to store it into the database
bm = Bitmap.createScaledBitmap(bm, width, height, false);
//then put it into a byte array to store it in the database
bm.compress(CompressFormat.JPEG, 100, blob);
// method call to database
dbClass.addPicture(blob.toByteArray());
Table definition in the database:
SQLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS Pictures (id integer primary key autoincrement, pic blob not null ");
addPicture method in the database class is as the following
public void addPicture(byte[] picture){
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("pic", picture);
db.insert("Pictures ", null, cv);
}
I hope that helps

Error while inserting blob data into sqlite on android

I want to store blob data into sqlite, It adds imageData as null although bloc has value. What should I put bloc value into sql?
String x = getResultAsOnlyValue("soapImage", xdata);
byte[] bloc = Base64.decode(x, Base64.DEFAULT);
Bitmap bmp = BitmapFactory.decodeByteArray(bloc,0,bloc.length);
SQLiteStatement statement = db.compileStatement("insert into ImageTable (imageData) values(?)");
statement.bindBlob(0, bloc);
statement.execute();
EDITED: ANSWER TO THE QUESTION
String x = getResultAsOnlyValue("soapImage", xdata);
byte[] bloc = Base64.decode(x, Base64.DEFAULT);
Bitmap bmp = BitmapFactory.decodeByteArray(bloc,0,bloc.length);
SQLiteDatabase db = getDb();
ContentValues values = new ContentValues();
values.put("ImageData", bloc);
db.insert("imageTable", null, values);
After this operation if you get NS_ERROR_FILE_CORRUPTED error while trying to run the db via sqlitemanager that means you need to upgrade your db to sqlite3. In this link it tells you to how to do this.
Good morning, try this answer out: Convert Drawable to BLOB Datatype
I think it's what you're looking for.

DB query returns corrupted data on Android

I have an SQLite DB with a sample table, which is stored in the assets/ folder.
This DB contains a single table, one of the columns is BLOB containing a BMP image. I may read/write this image flawlessly using JDBC on the host machine.
Then the data is accessed from the emulator using the following code:
final Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, null);
if (cursor.moveToFirst()) {
byte[] icon = cursor.getBlob(cursor.getColumnIndex(SearchEngines.ICON));
// ...
But the attempt to decode retreived image fails:
final Bitmap icon = BitmapFactory.decodeByteArray(icon , 0, icon.length);
I get null result and the following in the log:
DEBUG/skia(374): --- decoder->decode returned false
After this, I dumped the blob array into the file and compared with the original image. And it was a complete surprise, because the only uncovered difference was that all the 0x00 bytes were replaced with 0x25 0x30 sequences in the retreived blob:
0x00 -> 0x25 0x30 // %0
Besides that, all the data was intact. What the heck?
Update 1. After pulling the DB from the emulator (adb pull) the data it contains is corrupted (same %0 symbols). So, the problem is either in DB itself or implementation/usage of query/getBlob or other DB access code.
Update 2. *Seems that it's wrong* As far as I understand, SQLite supports 2 ways of storing large objects: TEXT and BLOB. TEXT columns don't contain 0x00 bytes, and in BLOBs 0x00 is translated into %0 (what a coincidence!). So, it seems that what I get is internal representation, not the actual data.
Update 3. Code for adding to DB is the following:
private void save(Connection conn, String id, String fileName) throws SQLException, IOException {
final String sql = "UPDATE " + TABLE_NAME + " SET " + BLOB_COLUMN_NAME + " = ? WHERE " + ID_COLUMN_NAME + " = ?";
System.out.println("Executing: " + sql);
final PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(2, Integer.valueOf(id));
File fBlob = new File(fileName);
FileInputStream is = new FileInputStream(fBlob);
byte[] bytes = new byte[(int) fBlob.length()];
int rc = is.read(bytes);
assert (rc == bytes.length);
System.out.println("Total size: " + rc);
pstmt.setBytes(1, bytes);
pstmt.execute();
}

Image insertion from SQL info

What does 'howard.jpg' do in the sql statement below & how do I insert the image into my android app?
CREATE TABLE IF NOT EXISTS employee (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
firstName VARCHAR(50),
lastName VARCHAR(50),
title VARCHAR(50),
department VARCHAR(50),
managerId INTEGER,
city VARCHAR(50),
officePhone VARCHAR(30),
cellPhone VARCHAR(30),
email VARCHAR(30),
picture VARCHAR(200))
INSERT INTO employee VALUES(1,'Ryan','Howard','Vice President, North East',
'Management', NULL, 'Scranton','570-999-8888','570-999-8887','ryan#dundermifflin.com','howard.jpg')
'howard.jpg' is just a string that is put into the varchar column. You should use BLOB instead of varchar for jpg and put not the name of a picture, but actual bytes of it.
Refer here for more details.
To store an image file inside your sqlite db you should use a BLOB field
and due android sqlite limitations you should store info in this way:
ContentValues cv = new ContentValues();
//your table fields goes here
...
// adding the bitmap in byte array way to the blob field
ByteArrayOutputStream out = new ByteArrayOutputStream();
friendInfo.getImage_bmp().compress(Bitmap.CompressFormat.PNG, 100,out);
cv.put("avatar_img", out.toByteArray());
db.insert(TABLE_NAME, null, cv);
and to read it you can do:
byte[] blob = cur.getBlob(cur.getColumnIndex("avatar_img"));
Bitmap bmp = BitmapFactory.decodeByteArray(blob, 0,blob.length, opts);
friend.setImage_bmp(bmp);
friend is and instance from a class havind a Bitmap property callend Image_bmp ;)
I've tried many methods to get this work, but until i made
cur.moveToFirst();
after query, i had null pointer here:
byte[] imageByteArray = cur.getBlob(cur.getColumnIndex("myImage"));

Storing audio file in a database

I'm developing an application. I need to use at least 400 audio files which can be played for some respective texts. My question is which is the best and optimized way to do this?
One solution is putting all the audio files in the resources folder and referring from there. This will never be a feasible solution as the application size will increase. Is there any way to convert the audio file into some format and dump into the SQLite database and retrieve them flexibly? If so, what options do I have?
Storing the files as BLOB in a SQLite db will not save you any space vs storing them as files. If these files are not meant to be associated to any dynamic data, I would just put them in assets folders, that way they'll be compiled into the APK and might be a tad faster to retrieve that if they were in a db.
try the following code... it stored for me.....
#Override
public void onClick(View arg0) {
SQLiteDatabase myDb;
String MySQL;
byte[] byteImage1 = null;
byte[] byteImage2 = null;
MySQL="create table emp1(_id INTEGER primary key autoincrement, sample TEXT not null, picture BLOB);";
myDb = openOrCreateDatabase("Blob List", Context.MODE_PRIVATE, null);
myDb.execSQL(MySQL);
String s=myDb.getPath();
textView.append("\r\n" + s+"\r\n");
myDb.execSQL("delete from emp1");
ContentValues newValues = new ContentValues();
newValues.put("sample", "HI Hello");
try
{
FileInputStream instream = new FileInputStream("/sdcard/AudioRecorder/AudioRecorder.wav");
BufferedInputStream bif = new BufferedInputStream(instream);
byteImage1 = new byte[bif.available()];
bif.read(byteImage1);
textView.append("\r\n" + byteImage1.length+"\r\n");
newValues.put("picture", byteImage1);
long ret = myDb.insert("emp1", null, newValues);
if(ret<0) textView.append("\r\n!!! Error add blob filed!!!\r\n");
} catch (IOException e)
{
textView.append("\r\n!!! Error: " + e+"!!!\r\n");
}
Cursor cur = myDb.query("emp1",null, null, null, null, null, null);
cur.moveToFirst();
while (cur.isAfterLast() == false)
{
textView.append("\r\n" + cur.getString(1)+"\r\n");
cur.moveToNext();
}
///////Read data from blob field////////////////////
cur.moveToFirst();
byteImage2=cur.getBlob(cur.getColumnIndex("picture"));
bmImage.setImageBitmap(BitmapFactory.decodeByteArray(byteImage2, 0, byteImage2.length));
textView.append("\r\n" + byteImage2.length+"\r\n");
cur.close();
myDb.close();
}
});
Anybody correct me if I'm wrong, but SQLite has an restriction of total row size < 1024kb. If all of your audio files are small enough, you could store them as BLOBs.
The main reason for storing sound files on database might be product line approach. You can develop many many similar applications by just modifying your database and not touching your code.
I do not comment on application size because there are comments about it and I do not look at it.
Yes. You can store your small sized sound files in sqlite database as blob fields. It works well. First store your data in database then retrieve it and put it in a temp file. That way you can store your sound files in database.
Check this:
soundDataFile = File.createTempFile( "sound", "sound" );
FileOutputStream fos = new FileOutputStream( soundDataFile );
fos.write( soundData );
fos.close();
mediaPlayer.reset();
mediaPlayer.setDataSource( soundDataFile.getAbsolutePath() );
mediaPlayer.prepare();
mediaPlayer.start();
What is the motivation behind storing the files in the sql lite db? I dont see much benefit to that over storing the file path in the db, and the actual file on the file system...

Categories

Resources