I want to save to db some strings with image. Image can be taken from gallery or user can set the sample one. In the other activity I have a listview which should present the rows with image and name. I'm facing so long this problem. It occurs when I wanna display listview with the image from gallery, If the sample image is saved in the row everything works ok. My problem is similar to this one: how to save image taken from camera and show it to listview - crashes with "IllegalStateException" but I can't find there the solution for me
My table in db looks like this:
public static final String KEY_ID = "_id";
public static final String ID_DETAILS = "INTEGER PRIMARY KEY AUTOINCREMENT";
public static final int ID_COLUMN = 0;
public static final String KEY_NAME = "name";
public static final String NAME_DETAILS = "TEXT NOT NULL";
public static final int NAME_COLUMN = 1;
public static final String KEY_DESCRIPTION = "description";
public static final String DESCRIPTION_DETAILS = "TEXT";
public static final int DESCRIPTION_COLUMN = 2;
public static final String KEY_IMAGE ="image" ;
public static final String IMAGE_DETAILS = "BLOB";
public static final int IMAGE_COLUMN = 3;
//method which create our table
private static final String CREATE_PRODUCTLIST_IN_DB =
"CREATE TABLE " + DB_TABLE + "( "
+ KEY_ID + " " + ID_DETAILS + ", "
+ KEY_NAME + " " + NAME_DETAILS + ", "
+ KEY_DESCRIPTION + " " + DESCRIPTION_DETAILS + ", "
+ KEY_IMAGE +" " + IMAGE_DETAILS + ");";
inserting statement:
public long insertToProductList(String name, String description, byte[] image)
{
ContentValues value = new ContentValues();
// get the id of column and value
value.put(KEY_NAME, name);
value.put(KEY_DESCRIPTION, description);
value.put(KEY_IMAGE, image);
// put into db
return db.insert(DB_TABLE, null, value);
}
Button which add the picture and onActivityResult method which saves the image and put it into the imageview
public void AddPicture(View v)
{
// creating specified intent which have to get data
Intent intent = new Intent(Intent.ACTION_PICK);
// From where we want choose our pictures
intent.setType("image/*");
startActivityForResult(intent, PICK_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
// if identification code match to the intent,
//if yes we know that is our picture,
if(requestCode ==PICK_IMAGE )
{
// check if the data comes with intent
if(data!= null)
{
Uri chosenImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(chosenImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePat = cursor.getString(columnIndex);
cursor.close();
ImageOfProduct = BitmapFactory.decodeFile(filePat);
if(ImageOfProduct!=null)
{
picture.setImageBitmap(ImageOfProduct);
}
messageDisplayer("got picture, isn't null " + IdOfPicture);
}
}
}
Then the code which converts bitmap to byte[]
public byte[] bitmapToByteConvert(Bitmap bit )
{
// stream of data getted for compressed bitmap
ByteArrayOutputStream gettedData = new ByteArrayOutputStream();
// compressing method
bit.compress(CompressFormat.PNG, 0, gettedData);
// our byte array
return gettedData.toByteArray();
}
The method which put data to the row:
byte[] image=null;
// if the name isn't put to the editView
if(name.getText().toString().trim().length()== 0)
{
messageDisplayer("At least you need to type name of product if you want add it to the DB ");
}
else{
String desc = description.getText().toString();
if(description.getText().toString().trim().length()==0)
{
messageDisplayer("the description is set as none");
desc = "none";
}
DB.open();
if(ImageOfProduct!= null){
image = bitmapToByteConvert(ImageOfProduct);
messageDisplayer("image isn't null");
}
else
{
BitmapDrawable drawable = (BitmapDrawable) picture.getDrawable();
image = bitmapToByteConvert(drawable.getBitmap());
}
if(image.length>0 && image!=null)
{
messageDisplayer(Integer.toString(image.length));
}
DB.insertToProductList(name.getText().toString(), desc, image );
DB.close();
messageDisplayer("well done you add the product");
finish();
You can see that I'm checking here the length of array to be sure that I don't send empty one.
And here is the place where Error appears imo, this code is from activity which presents the listview with data taken from db
private void LoadOurLayoutListWithInfo()
{
// firstly wee need to open connection with db
db= new sqliteDB(getApplicationContext());
db.open();
// creating our custom adaprer, the specification of it will be typed
// in our own class (MyArrayAdapter) which will be created below
ArrayAdapter<ProductFromTable> customAdapter = new MyArrayAdapter();
//get the info from whole table
tablecursor = db.getAllColumns();
if(tablecursor != null)
{
startManagingCursor(tablecursor);
tablecursor.moveToFirst();
}
// now we moving all info from tablecursor to ourlist
if(tablecursor != null && tablecursor.moveToFirst())
{
do{
// taking info from row in table
int id = tablecursor.getInt(sqliteDB.ID_COLUMN);
String name= tablecursor.getString(sqliteDB.NAME_COLUMN);
String description= tablecursor.getString(sqliteDB.DESCRIPTION_COLUMN);
byte[] image= tablecursor.getBlob(3);
tablefromDB.add(new ProductFromTable(id,name,description,image));
// moving until we didn't find last row
}while(tablecursor.moveToNext());
}
listView = (ListView) findViewById(R.id.tagwriter_listoftags);
//as description says
// setAdapter = The ListAdapter which is responsible for maintaining
//the data backing this list and for producing a view to represent
//an item in that data set.
listView.setAdapter(customAdapter);
}
I put the info from row tho objects which are stored in list.
I read tones of question but I can't find any solution for me. Everything works when I put the sample image ( which is stored in app res folder ). Thx for any advice
Logs from logcat:
11-13 11:15:54.580: E/CursorWindow(3985): Failed to read row 0, column 0 from a
CursorWindow which has 0 rows, 4 columns.
11-13 11:15:54.585: E/AndroidRuntime(3985): FATAL EXCEPTION: main
11-13 11:15:54.585: E/AndroidRuntime(3985): java.lang.RuntimeException: Unable to start
activity ComponentInfo{com.example.nfc_friend/com.example.nfc_friend.TagWriterMenu}:
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make
sure the Cursor is initialized correctly before accessing data from it.
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread.access$600(ActivityThread.java:141)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.os.Handler.dispatchMessage(Handler.java:99)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.os.Looper.loop(Looper.java:137)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread.main(ActivityThread.java:5103)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
java.lang.reflect.Method.invokeNative(Native Method)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
java.lang.reflect.Method.invoke(Method.java:525)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
dalvik.system.NativeStart.main(Native Method)
11-13 11:15:54.585: E/AndroidRuntime(3985): Caused by: java.lang.IllegalStateException:
Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized
correctly before accessing data from it.
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.database.CursorWindow.nativeGetLong(Native Method)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.database.CursorWindow.getLong(CursorWindow.java:507)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
com.example.nfc_friend.TagWriterMenu.LoadOurLayoutListWithInfo(TagWriterMenu.java:321)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
com.example.nfc_friend.TagWriterMenu.onCreate(TagWriterMenu.java:68)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.Activity.performCreate(Activity.java:5133)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-13 11:15:54.585: E/AndroidRuntime(3985): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-13 11:15:54.585: E/AndroidRuntime(3985): ... 11 more
EDITED I add the code which getting all columns, u can see that I use this method to get data from db
public Cursor getAllColumns()
{
String[] columns = {KEY_ID, KEY_NAME, KEY_DESCRIPTION, KEY_IMAGE};
return db.query(DB_TABLE, columns, null, null, null, null, null);
}