我是android编程的初学者。我试着写一个代码来保存sqlite数据库中有关该产品的一些数据。关于产品图片,我创建了一个TEXT类型的列productImage。在使用相机获取图像后,我从中创建了Bitmap对象:
Bitmap bm = (Bitmap) imageReturnedIntent.getExtras().get("data");
然后将其编码为字符串base 64:
productImageString = new ImageEncodeDecode().BitMapToString(bm);
public String BitMapToString(Bitmap bitmap){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
byte [] b=baos.toByteArray();
String temp=Base64.encodeToString(b, Base64.DEFAULT);
return temp;
}
并将其发送到产品对象并将其插入数据库:
b.addProduct(new ProductInfo(title.getText().toString(), details.getText().toString(),
phone.getText().toString(), dateOfPost, price.getText().toString(), productImageString,
logedInUser));
虽然我将列productImage创建为TEXT类型,但编译器存储编码的图像字符串。但是当它尝试使用getAllProducts()获取产品信息时,会出现以下异常:(问题的原因在于此行:productInfo.setThumbnail(cursor.getString(4));
)
04-15 20:41:03.601 5946-5946/com.mobileapp4u.sp.espareparts E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mobileapp4u.sp.espareparts, PID: 5946
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mobileapp4u.sp.espareparts/com.mobileapp4u.sp.espareparts.Main3Activity}: android.database.sqlite.SQLiteException: unknown error (code 0 SQLITE_OK): Unable to convert BLOB to string
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3027)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:101)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1786)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: android.database.sqlite.SQLiteException: unknown error (code 0 SQLITE_OK): Unable to convert BLOB to string
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:465)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at com.mobileapp4u.sp.espareparts.Database.DatabaseHandler.getAllProducts(DatabaseHandler.java:229)
at com.mobileapp4u.sp.espareparts.Main3Activity.prepareProducts(Main3Activity.java:201)
at com.mobileapp4u.sp.espareparts.Main3Activity.onCreate(Main3Activity.java:134)
at android.app.Activity.performCreate(Activity.java:7117)
at android.app.Activity.performCreate(Activity.java:7108)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1262)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2867)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3027)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:101)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1786)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
我该如何解决这个问题?
这是数据库代码的表创建部分:
String CREATE_PRODUCTS_TABLE;
CREATE_PRODUCTS_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_PRODUCTS + " (" + KEY_PRODUCT_ID +
" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_PRODUCT_TITLE + " TEXT, " + KEY_PRODUCT_DETAILS + " TEXT, " + KEY_PRODUCT_DATE_OF_POST +
" TEXT, " + KEY_PRODUCT_IMAGE + " TEXT, "
+ KEY_PRODUCT_PHONE + " TEXT, " + KEY_PRODUCT_PRICE + " INTEGER, " +
KEY_USER_NameFK + " TEXT, " +
"FOREIGN KEY ("+KEY_USER_NameFK+") REFERENCES "+TABLE_USERS+"("+KEY_NAME+"));";
db.execSQL(CREATE_PRODUCTS_TABLE);
广告代码:
public void addProduct(ProductInfo productInfo)
{
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_PRODUCT_TITLE, productInfo.getTitle());
values.put(KEY_PRODUCT_DETAILS, productInfo.getDescription());
values.put(KEY_PRODUCT_DATE_OF_POST, productInfo.getDateOfPost().toString());
values.put(KEY_PRODUCT_IMAGE, productInfo.getThumbnail());
values.put(KEY_PRODUCT_PHONE, productInfo.getPhone());
values.put(KEY_PRODUCT_PRICE, productInfo.getPrice());
values.put(KEY_USER_NameFK, productInfo.getUserNameFK());
db.insert(TABLE_PRODUCTS, null, values);
db.close();
}
检索代码:
public List<ProductInfo> getAllProducts()
{
List<ProductInfo> allProductsList = new ArrayList<ProductInfo>();
String selectQuery = "SELECT * FROM " + TABLE_PRODUCTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
Log.d("Database Operation", "Table Created");
// looping through all rows and adding to list
if(cursor.moveToFirst())
{
do
{
//byte[] c = (cursor.getString(4)).getBytes();
ProductInfo productInfo = new ProductInfo();
productInfo.setProductId(Integer.parseInt(cursor.getString(0)));
productInfo.setTitle(cursor.getString(1));
productInfo.setDescription(cursor.getString(2));
productInfo.setDateOfPost(cursor.getString(3));
productInfo.setThumbnail(cursor.getString(4));
productInfo.setPhone(cursor.getString(5));
productInfo.setPrice(cursor.getString(6));
productInfo.setUserNameFK(cursor.getString(7));
allProductsList.add(productInfo);
} while (cursor.moveToNext());
}
db.close();
return allProductsList;
}
答案 0 :(得分:1)
而不是尝试将位图转换为String。将位图转换为 byte [] 并存储它。
e.g。
public byte[] BitMapToString(Bitmap bitmap){
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
return b=baos.toByteArray();
}
更改 ProductInfo 类,以便图片的成员是 byte [] ,同时更改getter和setter以处理 byte [] < /强>
插入成员,假设getThumnail
现在获取字节数组,不需要更改,并将保持为: -
public void addProduct(ProductInfo productInfo)
{
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_PRODUCT_TITLE, productInfo.getTitle());
values.put(KEY_PRODUCT_DETAILS, productInfo.getDescription());
values.put(KEY_PRODUCT_DATE_OF_POST, productInfo.getDateOfPost().toString());
values.put(KEY_PRODUCT_IMAGE, productInfo.getThumbnail());
values.put(KEY_PRODUCT_PHONE, productInfo.getPhone());
values.put(KEY_PRODUCT_PRICE, productInfo.getPrice());
values.put(KEY_USER_NameFK, productInfo.getUserNameFK());
db.insert(TABLE_PRODUCTS, null, values);
db.close();
}
数据将作为 KEY_PRODUCT_IMAGE
存储在BLOB
列中(无论列的定义方式如何(只要列未定义)作为INTEGER PRIMARY KEY,因此是rowid的别名(应用于任何值的一个限制可以存储在任何列类型中)): -
SQLite版本3数据库中的任何列,但INTEGER PRIMARY除外 KEY列,可用于存储任何存储类的值。 Datatypes In SQLite Version 3
但是,您应该将列类型更改为BLOB。
您必须更改getAllProducts
方法以使用Cursor getBlob
方法而不是getString
方法。这将成为: -
public List<ProductInfo> getAllProducts()
{
List<ProductInfo> allProductsList = new ArrayList<ProductInfo>();
String selectQuery = "SELECT * FROM " + TABLE_PRODUCTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
Log.d("Database Operation", "Table Created");
// looping through all rows and adding to list
if(cursor.moveToFirst())
{
do
{
//byte[] c = (cursor.getString(4)).getBytes();
ProductInfo productInfo = new ProductInfo();
productInfo.setProductId(Integer.parseInt(cursor.getString(0)));
productInfo.setTitle(cursor.getString(1));
productInfo.setDescription(cursor.getString(2));
productInfo.setDateOfPost(cursor.getString(3));
productInfo.setThumbnail(cursor.getBlob(4)); //<<<< CHANGED
productInfo.setPhone(cursor.getString(5));
productInfo.setPrice(cursor.getString(6));
productInfo.setUserNameFK(cursor.getString(7));
allProductsList.add(productInfo);
} while (cursor.moveToNext());
}
db.close();
return allProductsList;
}
然后,您必须编码将 byte [] 转换回位图/图像。
注意,如果图像通常大于100k左右,那么将它们存储在数据库中会导致检索它们时出现问题以及产生处理开销。在这种情况下,最好将图像保存为文件,并保存数据库中这些文件的路径。