Как загрузить изображения из SQLite и показать их в ListView - PullRequest
0 голосов
/ 04 октября 2019

Я новичок в Android и у меня есть ошибка в моем проекте, я буду благодарен, если какой-либо орган поможет.

У моего приложения есть база данных, которую я сделал с помощью SQLite. я сохраняю изображения в формате BLOB и использую SimpleCurserAdapter для загрузки моих данных, но адаптер не может загрузить изображения и вызывает эту ошибку:

Процесс: com.example.radman.cars, PID: 9861 android. database.sqlite.SQLiteException: неизвестная ошибка (код 0): невозможно преобразовать BLOB в строку в android.database.CursorWindow.nativeGetString (собственный метод) в android.database.CursorWindow.getString (CursorWindow.java:438) в android.database.AbstractWindowedCursor.getString (AbstractWindowedCursor.java:51) в android.widget.SimpleCursorAdapter.bindView (SimpleCursorAdapter.java:150) в android.widget.CursorAdapter.getView (CursorAdapter). widget.AbsListView.obtainView (AbsListView.java:2363) в android.widget.ListView.makeAndAddView (ListView.java:1970) в android.widget.ListView.fillDown (ListView.java:704) в android.widget.ListView.fillromTop(ListView.java:765) в android.widget.ListView.layoutChildren (ListView.java:1744) в android.widget.AbsListView.onLayout (AbsListView.java:2162) в android.view.View.layout (View.java:17637) в android.view.ViewGroup.layout (ViewGroup.java:5575) в android.support.constraint.ConstraintLayout.onLayout (ConstraintLayout.java: 1197) на android.view.View.layout (View.java:17637) на android.view.ViewGroup.layout (ViewGroup.java:5575) на android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на android.view.View.layout (View.java:17637) на android.view.ViewGroup.layout (ViewGroup.java:5575) на com.android. internal.widget.ActionBarOverlayLayout.onLayout (ActionBarOverlayLayout.java:493) в android.view.View.layout (View.java:17637) в android.view.ViewGroup.layout (ViewGroup.java:5575) в android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)на android.widget.FrameLayout.onLayout (FrameLayout.java:261) на com.android.internal.policy.DecorView.onLayout (DecorView.java:726) на android.view.View.layout (View.java:17637) наandroid.view.ViewGroup.layout (ViewGroup.java:5575) в android.view.ViewRootImpl.performLayout (ViewRootImpl.java:2346) в android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2068l) в android.view.oot.view. .doTraversal (ViewRootImpl.java:1254) в android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java:6337) в android.view.Choreographer $ CallbackRecord.run (Choreographer.java:874. and and at. doCallbacks (Choreographer.java:686) в android.view.Choreographer.doFrame (Choreographer.java:621) в android.view.Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:860) в android.os.Chler.java: 751) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:154) на android.app.ActivityThread.main (ActivityThread.java: 6119) на java.lang.reflect.Method.invoke (собственный метод) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:886) на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 10-04 20: 24: 09.517 9861-9870 / com.example.radman.cars W / art: приостановка всех потоков заняла: 17.145мс

Я думаю, что ошибкапотому что адаптер не может прочитать двоичное значение, хотя я не уверен.

здесь мои коды:

Мой класс помощника:

public class Connector extends SQLiteOpenHelper {

private static final int DB_VERSION = 1; // Db version
private static final String DB_NAME = "Cars"; // name of the TABLE
private String name;
private String model;
private String color;
private int year;
private int photoR;

//CTOR coz the super class doesn't have any default CTOR
Connector(Context context, int year, int res, String color, String model, String name) {
    super(context, DB_NAME, null, DB_VERSION);
    this.name = name;
    this.model = model;
    this.color = color;
    this.year = year;
    this.photoR = res;
}

public SQLiteDatabase geter() {
    return this.getWritableDatabase();
}

// an overrided FUN (if DB doesn't exist create one )
@Override
public void onCreate(SQLiteDatabase db) {
    updateDB(db, 0, DB_VERSION);
}

// an overrided FUN (if DB exists update it )
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    updateDB(db, 0, DB_VERSION);
}

// a created FUN to check either DB exists or not
// IF yes just update it
// ELSE create
// * although the update feature will come in future *
public void updateDB(SQLiteDatabase db, int oldVersion, int newVersion) {

    db.execSQL("CREATE TABLE CARS (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + "NAME TEXT, "
            + "MODEL TEXT, "
            + "COLOR TEXT, "
            + "IMAGE_RESOURCE_ID BLOB NOT NULL, "
            + "YEAR INTEGER);");
    //insertOBJ(db, this.name, this.model, this.color, this.photoR, this.year);
    insertOBJ(db, name, model, color, R.drawable.performance, year);
}

// a created FUN to add the OBJ (Car) to the DB
public static void insertOBJ(SQLiteDatabase db, String name, String model,
                             String color, int photoId, int productionyear) {
    ContentValues car = new ContentValues();
    car.put("NAME", name);
    car.put("MODEL", model);
    car.put("COLOR", color);
    car.put("IMAGE_RESOURCE_ID", photoId);
    car.put("YEAR", productionyear);
    db.insert("CARS", null, car);
}

}


мой домашний код, который предназначен для домашней активности, и он должен загружать и показывать записи из базы данных:

 package com.example.radman.cars;
    import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

import javax.crypto.interfaces.PBEKey;


public class Home extends ListActivity {

private SQLiteDatabase db;
private Cursor data;


@Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.Home);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    orders();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.add: {
            Intent intent = new Intent(this, Add.class);
            startActivity(intent);
        }
    }
    return super.onOptionsItemSelected(item);
}

@Override
protected void onResume() {
    orders();
    super.onResume();
}

private void orders() {

    // this.deleteDatabase("Cars");
    ListView list = getListView();
    try {
        SQLiteOpenHelper helper = new Connector(this, 0, 0, null, null, null);
        db = helper.getReadableDatabase();

        data = db.query("CARS", null, null, null, null, null, null);

            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                    R.layout.format
                    , data, new String[]{"NAME", "YEAR", "MODEL", "IMAGE_RESOURCE_ID"},
                    new int[]{R.id.nameText, R.id.yearTEXT, R.id.modelTXT, R.id.PICIMG});



            list.setAdapter(adapter);

    } catch (SQLException e) {
        String a = e.getMessage();
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }

    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        }
    });
    list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, final long id) {

            new AlertDialog.Builder(Home.this).setCancelable(true).setMessage("Do you want to delete or edit ?")
                    .setNegativeButton("Delete", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            new AlertDialog.Builder(Home.this).setTitle("Delete ?").setMessage("Are you sure you want to delete it?")
                                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            delete((int) id);
                                        }
                                    }).setNegativeButton("No", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {

                                }
                            }).setCancelable(false).show();

                        }
                    }).setPositiveButton("Edit", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    edit((int) id);
                }
            }).setTitle("Ready for order").show();

            return true;
        }
    });

}

public void delete(int id) {
    try {
        Connector c = new Connector(this, 0, 0, null, null, null);
        SQLiteDatabase db = c.getWritableDatabase();
        db.delete("CARS", "_id=?", new String[]{Integer.toString(id)});
        Toast.makeText(this, "Deleted successfully !", Toast.LENGTH_SHORT).show();
        orders();
    } catch (SQLException e) {
        Toast.makeText(this, "Failed to delete ! please try later", Toast.LENGTH_SHORT).show();
    }
}

public void edit(int id) {
    Bundle b = new Bundle();
    b.putInt("id", id);
    Intent intent = new Intent(this, Edit.class);
    intent.putExtra("id", b);
    startActivity(intent);
}

}


мой домашний макет:

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">

    <ListView
        android:id="@android:id/list"
        android:layout_width="344dp"
        android:layout_height="495dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.984" />
</android.support.constraint.ConstraintLayout>

как я сохранил свои записи:

    package com.example.radman.cars;

import android.content.ContentValues;
import android.content.Intent;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.BitmapDrawable;
import android.media.Image;
import android.media.MediaPlayer;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import android.graphics.Bitmap;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Objects;

public class Add extends AppCompatActivity {

    //    private static final int CAMERA_REQUEST = 1888;
//    private ImageView imageView;
//    private static final int MY_CAMERA_PERMISSION_CODE = 100;
    static final int REQUEST_IMAGE_CAPTURE = 1;
    public static final int PICK_IMAGE = 1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

      //  getActionBar().setDisplayHomeAsUpEnabled(true);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);

//        getActionBar().setDisplayHomeAsUpEnabled(true);

        MediaPlayer player = new MediaPlayer();
        player.start();

        ArrayList<String> items = new ArrayList<>();
        for (int i = 1960; i < 2020; i++) {
            items.add(Integer.toString(i));
        }
        Spinner s = (Spinner) findViewById(R.id.spnYear);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, items);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        s.setAdapter(adapter);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            ImageView imageView = (ImageView) findViewById(R.id.photoImage);
            imageView.setImageBitmap(imageBitmap);
        } else if (requestCode == PICK_IMAGE) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            ImageView imageView = (ImageView) findViewById(R.id.photoImage);
            imageView.setImageBitmap(imageBitmap);
        }
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }

    public void btnAdd(View view) {

        try {
            TextView[] texts = new TextView[2];
            texts[0] = (TextView) findViewById(R.id.nameText);
            texts[1] = (TextView) findViewById(R.id.mdlText);

            Spinner a = (Spinner) findViewById(R.id.spnYear);
            String year = a.getSelectedItem().toString();
            a = (Spinner) findViewById(R.id.spnColor);
            String color = a.getSelectedItem().toString();

            ImageView image = (ImageView)findViewById(R.id.photoImage);
            BitmapDrawable drawable = (BitmapDrawable) image.getDrawable();
            Bitmap bitmap = drawable.getBitmap();

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            byte[] buffer=out.toByteArray();

            Connector connection = new Connector(this, 0, 0, null, null, null);

            SQLiteDatabase db = connection.getWritableDatabase();
            ContentValues car = new ContentValues();
            String n = texts[0].getText().toString();
            car.put("NAME", n);
            car.put("MODEL", texts[1].getText().toString());
            car.put("COLOR", color);
            car.put("IMAGE_RESOURCE_ID",buffer /*R.id.photoImage*/);
            car.put("YEAR", Integer.parseInt(year));
            db.insert("CARS", null, car);

            Toast.makeText(this, "Saved Successfully !", Toast.LENGTH_SHORT).show();
        } catch (SQLException e) {

            Toast.makeText(this, "Database unable !", Toast.LENGTH_SHORT).show();
        }
        Intent intent = new Intent(this, Home.class);
        startActivity(intent);
        finish();

    }

    public void btnTake(View view) {

        dispatchTakePictureIntent();
    }

    public void btnGal(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
    }


}

и мой макет, который используется в качестве макета для просмотра списка:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <TextView
        android:id="@+id/modelTXT"
        android:layout_width="189dp"
        android:layout_height="32dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="67dp"
        android:layout_marginTop="8dp"
        android:text="MODEL"
        android:textAlignment="inherit"
        android:textColor="@android:color/black"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0" />

    <TextView
        android:id="@+id/yearTEXT"
        android:layout_width="60dp"
        android:layout_height="33dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        android:text="2020"
        android:textAlignment="center"
        android:textColor="@android:color/black"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/nameText"
        android:layout_width="132dp"
        android:layout_height="34dp"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        android:text="NAME"
        android:textAlignment="inherit"
        android:textColor="@android:color/black"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

    <ImageView
        android:id="@+id/PICIMG"
        android:layout_width="134dp"
        android:layout_height="95dp"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.976"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.454"
        app:srcCompat="@color/white" />
</android.support.constraint.ConstraintLayout>

Я будубудь очень благодарен, если кто-нибудь поможет.

в продвинутом спасибо.

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