我正在尝试从用户那里获取一些数据,包括相机拍摄的照片,然后将其插入到数据库(缩略图)中,然后检索它以便以后查看。 1- I used this and this
,这是响应用户输入的OnclickListener。
sginUpButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String Fname = fn.getText().toString();
String Lname = ln.getText().toString();
String Email = em.getText().toString();
String Pass = pass.getText().toString();
String mobile = mob.getText().toString();
if(fn.length()!=0 && ln.length()!=0 && em.length()!=0 && pass.length()!=0&& mob.length()!=0)
{
AddData(Fname,Lname,Email,Pass,mobile,byteArray);
fn.setText("");
ln.setText("");
em.setText("");
pass.setText("");
mob.setText("");
Intent fromLoginToSignup = new Intent(SignUpScreen.this, Profile.class);
notification();
}
else
{
toastmessage("lazem temla kol al fara3'at");
}
}
});
最后,这是它插入数据库内部的部分,我认为这与要插入的图像有关,实际上存在错误。
public void onCreate(SQLiteDatabase db) {
String createTable="CREATE TABLE "+ TABLE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT , "
+ FN + " TEXT , "
+ LN + " TEXT ,"
+ E_M + " TEXT ,"
+ PASS + " TEXT ,"
+ Mobnum + " INTEGER, "
+ image + " BLOB)";
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean addData(String FirstName,String LastName,String Email,String Password,String MobileNumber, byte[] Profileimg) //to write into the datbase
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv =new ContentValues();
cv.put(FN,FirstName);
cv.put(LN,LastName);
cv.put(E_M,Email);
cv.put(PASS,Password);
cv.put(Mobnum,MobileNumber);
cv.put(image, Profileimg);
Log.d(DATABASE_NAME,"adding : " + FirstName + " TO " + TABLE_NAME );
long result=db.insert(TABLE_NAME,null,cv);
//if the result inserted correctly or not
if(result==-1)
{
return false;
}
else
{
return true;
}
}
我已经在线获得了这两个函数,所以我认为将它们放在此处很重要,但是我认为它们与错误有关,但是我不确定
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(photo);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byteArray = stream.toByteArray();
}
}
答案 0 :(得分:1)
该消息表明字节为空。 getBlob的文档指出:-
结果以及该方法在列时是否引发异常 值是null或列类型不是blob类型是 实现定义的。
因此,我相信getBlob返回的是null,因此,最有可能的是插入了null。
根据您的DatabaseHelper考虑以下内容:-
mDB = new DatabaseHelper(this);
mDB.addData("Test001", "Test001", "email", "password", "xxc", null);
mDB.addData("Test002", "Test002", "email", "password", "xxc", new byte[]{0});
Cursor csr = mDB.getData();
DatabaseUtils.dumpCursor(csr);
while (csr.moveToNext()) {
bytes = csr.getBlob(6);
if (bytes == null) {
Log.d("OUCH", "Row " + String.valueOf(csr.getPosition()) + " is null");
} else {
Log.d("OK", "Row " + String.valueOf(csr.getPosition()) + " has byte array of length " + bytes.length);
}
Log.d("REPLICATE"," byte array length is " + bytes.length);
}
这将两行相加,第一行以null作为byte [](图像),第二行具有有效值,尽管它是短byte []。
插入的行没有问题。
数据提取没有问题。
但是该日志将包含以下内容:-
2019-01-09 14:15:31.622 2783-2783/ptfc.populatetablefromcursor D/mydb: adding : Test001 TO mytable
2019-01-09 14:15:31.623 2783-2783/ptfc.populatetablefromcursor D/mydb: adding : Test002 TO mytable
2019-01-09 14:15:31.624 2783-2783/ptfc.populatetablefromcursor I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@453edcd
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: 0 {
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: ID=1
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: fn=Test001
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: ln=Test001
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: e_m=email
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: pass=password
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: mobnum=xxc
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: image=null
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: }
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: 1 {
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: ID=2
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: fn=Test002
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: ln=Test002
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: e_m=email
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: pass=password
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: mobnum=xxc
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: image=<unprintable>
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: }
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: 2 {
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: ID=3
2019-01-09 14:15:31.626 2783-2783/ptfc.populatetablefromcursor I/System.out: fn=Test001
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: ln=Test001
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: e_m=email
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: pass=password
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: mobnum=xxc
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: image=null
2019-01-09 14:15:31.627 2783-2783/ptfc.populatetablefromcursor I/System.out: }
2019-01-09 14:15:31.629 2783-2783/ptfc.populatetablefromcursor I/System.out: <<<<<
2019-01-09 14:15:31.629 2783-2783/ptfc.populatetablefromcursor D/OUCH: Row 0 is null
2019-01-09 14:15:31.630 2783-2783/ptfc.populatetablefromcursor D/AndroidRuntime: Shutting down VM
2019-01-09 14:15:31.632 2783-2783/ptfc.populatetablefromcursor E/AndroidRuntime: FATAL EXCEPTION: main
Process: ptfc.populatetablefromcursor, PID: 2783
java.lang.RuntimeException: Unable to start activity ComponentInfo{ptfc.populatetablefromcursor/ptfc.populatetablefromcursor.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2914)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3049)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1809)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at ptfc.populatetablefromcursor.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2894)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3049)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1809)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
stackTrace类似。显示如果插入空值,则 bytes.length 会导致失败。
有很多方法可以解决此问题,例如,如果传递给addData方法的ProfileImage为null,则可以将image列设置为具有DEFAULT值,并跳过cv.put
。
在数据库助手中将+ image + " BLOB ')";
更改为+ image + " BLOB DEFAULT X'00')";
在addData方法中进行以下更改:-
if (Profileimg != null) {
cv.put(image, Profileimg);
}
此外,如果图像可能还会遇到其他问题 由于存在限制,它们本身就很大(100万最近为200万) 具有CursorWindow(由Cursor使用)可以达到的数据大小 使用1张图片处理超过或接近2M,并且例外 保证。对于1M图像,如果出现以下情况,则CursorWindow最多可容纳1个 根本没有,所以您会期望显示问题。
如果图像平均大约100k,则可以将其存储在数据库中,并且 搜索可能会揭示SQlite如何变得更好的背后原因 比文件系统更有效。
答案 1 :(得分:0)
如果您不想使用blob,这是另一种解决方案。您可以实现如下,
有关转换代码,请参考here