我想用db保存一些字符串。图像可以从图库中获取,或者用户可以设置样本。在另一个活动中,我有一个listview,它应该显示带有图像和名称的行。我这么长时间面对这个问题。它发生在我想用图库中的图像显示列表视图时,如果样本图像保存在行中,一切正常。我的问题类似于这个问题:how to save image taken from camera and show it to listview - crashes with "IllegalStateException"但我无法找到适合我的解决方案
db中的表格如下所示:
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 + ");";
插入声明:
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);
}
添加图片的按钮和保存图像并将其放入图像视图的onActivityResult方法
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);
}
}
}
然后将位图转换为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();
}
将数据放入行的方法:
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();
你可以看到我在这里检查数组的长度,以确保我不发送空的数组。
这里是Error出现imo的地方,这段代码来自于活动,它显示了listview以及从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);
}
我把行中的信息放在列表中的对象中。
我读了问题的语气,但我找不到任何解决方案。当我放置样本图像(存储在app res文件夹中)时,一切正常。感谢任何建议
来自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 我添加获取所有列的代码,你可以看到我使用这个方法从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);
}