【问题标题】:How to retrieve image from sqlite to list view?如何从 sqlite 检索图像到列表视图?
【发布时间】:2015-09-30 03:57:38
【问题描述】:

这里是我的代码 EmployeeAppActivity

我的代码在没有图像的列表视图中运行良好。我需要列表视图中的员工照片,当图像从数据库添加到列表视图时出现错误。请帮帮我。

// Primitive Variables
String selected_ID = "";

// Widget GUI Declare
EditText txtEname, txtDesig, txtSalary;
Button btnAddEmployee, btnUpdate, btnDelete;
ListView lvEmployees;

// DB Objects
DBHelper helper;
SQLiteDatabase db;

// Adapter Object
SimpleCursorAdapter adapter;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Init DB Objects
    helper = new DBHelper(this);

    // Widget GUI Init
    txtEname = (EditText) findViewById(R.id.txtEname);
    txtDesig = (EditText) findViewById(R.id.txtDesig);
    txtSalary = (EditText) findViewById(R.id.txtSalary);
    lvEmployees = (ListView) findViewById(R.id.lvEmployees);

    btnAddEmployee = (Button) findViewById(R.id.btnAdd);
    btnUpdate = (Button) findViewById(R.id.btnUpdate);
    btnDelete = (Button) findViewById(R.id.btnDelete);

    // Attached Listener
    btnAddEmployee.setOnClickListener(this);
    btnUpdate.setOnClickListener(this);
    btnDelete.setOnClickListener(this);
    lvEmployees.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapter, View v,
                int position, long id) {

            String name, desig, salary;
            byte[] empphoto;

            // Display Selected Row of Listview into EditText widget

            Cursor row = (Cursor) adapter.getItemAtPosition(position);
            selected_ID = row.getString(0);
            name = row.getString(1);
            desig = row.getString(2);
            salary = row.getString(3);
            empphoto=row.getBlob(4);

            txtEname.setText(name);
            txtDesig.setText(desig);
            txtSalary.setText(salary);
        }
    });

    // Fetch Data from database
    fetchData();
}

@Override
public void onClick(View v) {

    // Perform CRUD Operation

    if (v == btnAddEmployee) {

        // Add Record with help of ContentValues and DBHelper class object

        Bitmap b=BitmapFactory.decodeResource(getResources(), R.drawable.icon);
        //Bitmap b=BitmapFactory.decodeFile(imagepath);
        //ContentValues cv=new ContentValues();
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.JPEG, 90, bos);
        byte[] photo=bos.toByteArray();
        ContentValues values = new ContentValues();
        values.put(DBHelper.C_ENAME, txtEname.getText().toString());
        values.put(DBHelper.C_DESIGNATION, txtDesig.getText().toString());
        values.put(DBHelper.C_SALARY, txtSalary.getText().toString());
        values.put(DBHelper.C_Dp, photo);

        // Call insert method of SQLiteDatabase Class and close after
        // performing task
        db = helper.getWritableDatabase();
        db.insert(DBHelper.TABLE, null, values);
        db.close();

        clearFields();
        Toast.makeText(this, "Employee Added Successfully",
                Toast.LENGTH_LONG).show();

        // Fetch Data from database and display into listview
        fetchData();

    }
    if (v == btnUpdate) {

        // Update Record with help of ContentValues and DBHelper class
        // object

        ContentValues values = new ContentValues();
        values.put(DBHelper.C_ENAME, txtEname.getText().toString());
        values.put(DBHelper.C_DESIGNATION, txtDesig.getText().toString());
        values.put(DBHelper.C_SALARY, txtSalary.getText().toString());

        // Call update method of SQLiteDatabase Class and close after
        // performing task
        db = helper.getWritableDatabase();
        db.update(DBHelper.TABLE, values, DBHelper.C_ID + "=?",
                new String[] { selected_ID });
        db.close();

        // Fetch Data from database and display into listview
        fetchData();
        Toast.makeText(this, "Record Updated Successfully",
                Toast.LENGTH_LONG).show();
        clearFields();

    }
    if (v == btnDelete) {

        // Call delete method of SQLiteDatabase Class to delete record and
        // close after performing task
        db = helper.getWritableDatabase();
        db.delete(DBHelper.TABLE, DBHelper.C_ID + "=?",
                new String[] { selected_ID });
        db.close();

        // Fetch Data from database and display into listview
        fetchData();
        Toast.makeText(this, "Record Deleted Successfully",
                Toast.LENGTH_LONG).show();
        clearFields();

    }

}

// Clear Fields
private void clearFields() {
    txtEname.setText("");
    txtDesig.setText("");
    txtSalary.setText("");
}

// Fetch Fresh data from database and display into listview
private void fetchData() {

    db = helper.getReadableDatabase();
    Cursor c = db.query(DBHelper.TABLE, null, null, null, null, null, null);
    adapter = new SimpleCursorAdapter(
            this,
            R.layout.row,
            c,
            new String[] { DBHelper.C_ENAME, DBHelper.C_SALARY, DBHelper.C_DESIGNATION ,DBHelper.C_Dp},

            new int[] { R.id.lblEname, R.id.lblSalary, R.id.lblDesignation,R.id.empdp });
    lvEmployees.setAdapter(adapter);
}

此处为 DBHelper 类

static final String DATABASE = "empapp.db";
static final int VERSION = 1;
static final String TABLE = "emp";

static final String C_ID = "_id";
static final String C_ENAME = "ename";
static final String C_DESIGNATION = "designation";
static final String C_SALARY = "salary";
static final String C_Dp = "photo";

// Override constructor
public DBHelper(Context context) {
    super(context, DATABASE, null, VERSION);

}

// Override onCreate method
@Override
public void onCreate(SQLiteDatabase db) {

    // Create Employee table with following fields
    // _ID, ENAME, DESIGNATION and SALARY
    db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
            + " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
            + C_DESIGNATION + " text, " + C_SALARY + " text, " + C_Dp+ " BLOB )");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    // Drop old version table
    db.execSQL("Drop table " + TABLE);

    // Create New Version table
    onCreate(db);
}

Logcat 错误

09-30 03:45:38.139: E/AndroidRuntime(30628): 致命异常: main 09-30 03:45:38.139: E/AndroidRuntime(30628): android.database.sqlite.SQLiteException:未知错误(代码 0): 无法将 BLOB 转换为字符串 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.database.CursorWindow.nativeGetString(Native Method) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.database.CursorWindow.getString(CursorWindow.java:434) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:150) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.CursorAdapter.getView(CursorAdapter.java:250) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.AbsListView.obtainView(AbsListView.java:2159) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.ListView.makeAndAddView(ListView.java:1831) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.ListView.fillDown(ListView.java:674) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.ListView.fillFromTop(ListView.java:735) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.ListView.layoutChildren(ListView.java:1652) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.widget.AbsListView.onLayout(AbsListView.java:1994) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.View.layout(View.java:14003) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewGroup.layout(ViewGroup.java:4375) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.LinearLayout.onLayout(LinearLayout.java:1434) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.View.layout(View.java:14003) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewGroup.layout(ViewGroup.java:4375) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.widget.FrameLayout.onLayout(FrameLayout.java:448) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.View.layout(View.java:14003) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewGroup.layout(ViewGroup.java:4375) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.widget.LinearLayout.onLayout(LinearLayout.java:1434) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.View.layout(View.java:14003) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewGroup.layout(ViewGroup.java:4375) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.widget.FrameLayout.onLayout(FrameLayout.java:448) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.View.layout(View.java:14003) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewGroup.layout(ViewGroup.java:4375) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.view.Choreographer.doCallbacks(Choreographer.java:562) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.Choreographer.doFrame(Choreographer.java:532) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 android.os.Handler.handleCallback(Handler.java:725) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.os.Handler.dispatchMessage(Handler.java:92) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 android.os.Looper.loop(Looper.java:137) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 android.app.ActivityThread.main(ActivityThread.java:5039) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 java.lang.reflect.Method.invokeNative(Native Method) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 java.lang.reflect.Method.invoke(Method.java:511) 09-30 03:45:38.139: E/AndroidRuntime(30628):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 09-30 03:45:38.139: E/AndroidRuntime(30628): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 09-30 03:45:38.139:E/AndroidRuntime(30628):在 dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 我认为您必须需要 CustomAdapter 才能将数据与图片一起显示。
  • 我认为这行出错了 'new int[] { R.id.lblEname, R.id.lblSalary, R.id.lblDesignation,R.id.empdp });'
  • 我认为你不能在 Android 中直接将 BLOB 设置为 Image。实现您的自定义适配器并将 BLOB 更改为位图,然后将此位图设置为 ImageView。
  • 请举例说明如何将 BLOB 更改为位图图像

标签: java android eclipse sqlite


【解决方案1】:

在您的数据库中,您将图片网址保存为字符串,如
静态最终字符串 C_Dp = "照片";
但是如何使用这条线将图像变成 blob?
empphoto=row.getBlob(4);
您可以从 sql lite 以字符串形式获取路径,然后从该路径获取 drawabale 图像并将其显示在列表视图中包含的图像视图中

File imgFile = new  File("your file path from sqlite");
if(imgFile.exists()){

Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);

myImage.setImageBitmap(myBitmap);

【讨论】:

    【解决方案2】:

    SimpleCursorAdapter 使用 cursor.getString 从数据库中检索值,如 the Source Code .因此,SimpleCursorAdapter 不了解如何处理 blob 数据。因此,在这种情况下,您必须创建自己的自定义视图绑定器。请查看下面的示例代码

    EmployeeAppActivity.java

    public class EmployeeAppActivity extends AppCompatActivity {
          // DB Objects
    DBHelper helper;
    SQLiteDatabase db;
    SimpleCursorAdapter adapter;
    private ListView lvEmployees;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Init DB Objects
        helper = new DBHelper(this);
    
        lvEmployees = (ListView) findViewById(R.id.lvEmployees);
        populateDummyDataInDb();
        fetchData();
    
    
    }
    
    private void fetchData() {
    
        db = helper.getReadableDatabase();
        Cursor c = db.query(DBHelper.TABLE, null, null, null, null, null, null);
        adapter = new SimpleCursorAdapter(
                this,
                R.layout.row,
                c,
                new String[]{DBHelper.C_ENAME, DBHelper.C_DP},
    
                new int[]{R.id.lblEname, R.id.empdp});
        adapter.setViewBinder(new EmployeeListViewBinder());
        lvEmployees.setAdapter(adapter);
    }
    
    private void populateDummyDataInDb() {
        Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.person_image_empty);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.JPEG, 90, bos);
        byte[] photo = bos.toByteArray();
    
        ContentValues values = new ContentValues();
        values.put(DBHelper.C_ENAME, "Waleed Sarwar");
        values.put(DBHelper.C_DP, photo);
        db = helper.getWritableDatabase();
        db.insert(DBHelper.TABLE, null, values);
       }
    
    }
    

    EmployeeListViewBinder.java

    public class EmployeeListViewBinder implements SimpleCursorAdapter.ViewBinder {
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int viewID = view.getId();
        switch (viewID) {
            case R.id.lblEname:
                TextView textView = (TextView) view;
                textView.setText(cursor.getString(cursor.getColumnIndex(DBHelper.C_ENAME)));
                break;
            case R.id.empdp:
                ImageView imageView= (ImageView) view;
                byte[] imageBytes = cursor.getBlob(cursor.getColumnIndex(DBHelper.C_DP));
                if (imageBytes != null) {
                    // Pic image from database
                    imageView.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
                } else {
                    // If image not found in database , assign a default image
                    //imageView.setBackgroundResource(R.drawable.bubble_a);
                }
                break;
        }
        return true;
     }
    }
    

    DBHelper.jave

    public class DBHelper extends SQLiteOpenHelper {
    
    public static final String DATABASE = "empapp.db";
    public static final int VERSION = 1;
    
    public static final String TABLE = "emp";
    public static final String C_ID = "_id";
    public static final String C_ENAME = "ename";
    public static final String C_DP = "photo";
    
    
    public DBHelper(Context context) {
        super(context, DATABASE, null, VERSION);
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE + " ( " + C_ID
                + " INTEGER PRIMARY KEY AUTOINCREMENT, " + C_ENAME + " text, "
                + C_DP + " BLOB )");
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop old version table
        db.execSQL("Drop table " + TABLE);
    
        // Create New Version table
        onCreate(db);
     }
    }
    

    activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
     <ListView
        android:id="@+id/lvEmployees"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:listitem="@layout/row" />
    </RelativeLayout>
    

    row.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    
    <ImageView
        android:id="@+id/empdp"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@drawable/person_image_empty" />
    
    <TextView
        android:id="@+id/lblEname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dp"
        android:layout_marginStart="5dp"
        android:text="Waleed Sarwar" />
    
    </LinearLayout>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-28
      • 2023-03-29
      • 1970-01-01
      • 2011-11-15
      • 2012-08-02
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      相关资源
      最近更新 更多