Как вставить и получить изображение из базы данных Sqlite в Android Studio - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь получить некоторые данные от пользователя, включая снимок, сделанный камерой, а затем вставить его в БД (миниатюру), а затем извлечь его для просмотра позже. 1- Я использовал это и это

Но я все еще получаю ошибку in this image

строка 45, упомянутая в этой ошибке, находится здесь: This is the error

и это 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;
    }
}

Я получил эти 2 функции онлайн, поэтому я думаю, что важно разместить их здесь, но я думаю, что они как-то связаны с ошибкой, но я не могу быть уверен,

    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();
    }
}

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Это альтернативное решение, если вы не хотите использовать blob. Вы можете реализовать это следующим образом,

  • Преобразование растрового изображения в base64 и сохранение его в виде текста в sqlite.
  • При извлечении конвертируйте этот base64 в растровое изображение и отображайте его в ImageView.

Код конверсии см. Здесь

0 голосов
/ 09 января 2019

Сообщение указывает, что байт равно нулю. Документация для getBlob гласит: -

Результат и выбрасывает ли этот метод исключение, когда столбец значение равно нулю или тип столбца не является типом BLOB-объекта реализации.

Таким образом, я считаю, что getBlob возвращает ноль и, следовательно, похоже, что нули вставляются.

Рассмотрим следующее на основе вашего 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);
    }

Это добавляет две строки, первая с нулем в качестве байта [] (изображение), вторая имеет действительный, хотя и короткий байт [].

Строки вставляются без проблем.

Данные извлечены без проблем.

Однако журнал будет содержать следующее: -

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 приводит к ошибке, если вставлено значение NULL.

Существует множество способов исправить это, например, вы можете установить для столбца изображения значение DEFAULT, пропуская cv.put, если ProfileImage, переданный методу addData, равен нулю, например,

в помощнике по базе данных изменить + image + " BLOB ')"; на + image + " BLOB DEFAULT X'00')";

вместе со следующим изменением в методе addData: -

    if (Profileimg != null) {
        cv.put(image, Profileimg);
    }
  • Не могу вспомнить, как это повлияет на изображение в просмотре списка, хотя я думаю, что оно обрабатывает его.

Однако основной причиной будет то, что при съемке изображения будет возвращен ноль.

Кроме того, вы можете столкнуться с другими проблемами, если изображения сами по себе большие, так как есть ограничения (1М, недавно 2М) с размером данных, который может использовать CursorWindow (используемый курсором) ручка превышает или приближается к 2M с 1 изображением, исключение составляет гарантировано. С 1M изображениями CursorWindow будет содержать максимум 1, если вообще, так что вы ожидаете проблем с отображением.

Если изображения в среднем около 100 КБ, они могут быть сохранены в БД и поиск может выявить причины того, как SQlite может быть более эффективнее файловой системы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...