画像付きの文字列をdbに保存したい。画像はギャラリーから取得することも、ユーザーがサンプルを設定することもできます。他のアクティビティには、行に画像と名前を表示するリストビューがあります。私は長い間この問題に直面しています。ギャラリーの画像でリストビューを表示したいときに発生します。サンプル画像が行に保存されていれば、すべて正常に動作します。私の問題はこれに似ています:カメラから撮影した画像を保存してリストビューに表示する方法-「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);
}
画像を追加するボタンと、画像を保存して imageview に入れる 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();
空の配列を送信しないように、ここで配列の長さをチェックしていることがわかります。
そして、これがエラーが表示される場所です。このコードは、データベースから取得したデータを含むリストビューを表示するアクティビティからのものです
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 フォルダーに保存されている)を配置すると、すべてが機能します。アドバイスがあればthx
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
編集済みすべての列を取得するコードを追加します。このメソッドを使用して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);
}