java - 图像不会保留在我的数据库中

标签 java android sqlite android-sqlite

我已经研究这个问题好几天了,但我不知道我做错了什么。我正在为一个项目制作一个库存/商店应用程序,用户可以将他们库存的商品输入到列表中。根据要求,我需要赋予它拍照功能,并且我需要能够将图片保存在 SQLite 数据库中。这部分我已经实现了。但是,当我尝试更新某个项目并将其再次保存到列表中时,图像返回 null。我附上了图片来直观地解释...

主要 Activity

image1

新项目页面

image2

将项目保存到主要 Activity ListView

image3

点击要编辑的项目

image4

除非我拍摄新照片,否则当我保存更新的项目时,图标图像将返回 null

image5

我正在使用 CursorLoader。我以与处理数据库中所有其他列相同的方式处理图像......所以我不明白为什么它不会粘住。

以下是与 EditorActivity 中的图像相关的代码:

Bitmap photos;

// Content URI for the existing item (null if it's a new item)
private Uri mCurrentItemUri;

// Picture taking capability with button
public void takePicture(View view) {
    PackageManager pm = this.getPackageManager();
    if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    } else {
        Toast.makeText(EditorActivity.this, "Sorry! You don't have a camera app.", Toast.LENGTH_SHORT).show();
    }
}

// Once image is taken, save to image view and then save to db as a ByteArray
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        photos = (Bitmap) extras.get("data");
        mImageView.setImageBitmap(photos);
    }
}

// Get user input from editor and save item into database.
private void saveItem() {
    // Read from input fields
    // Use trim to eliminate leading or trailing white space
    String nameString = mNameEditText.getText().toString().trim();
    String priceString = mPriceEditText.getText().toString().trim();
    // Find quantity TV by id and extract int value as String
    TextView quantityTextView = (TextView) findViewById(R.id.quantity_editor_text_view);
    String quantityString = quantityTextView.getText().toString();
    ImageView iconImage = (ImageView) findViewById(R.id.image_view_editor);

    // Check if this is supposed to be a new item and check if all the fields in the editor are blank
    if (mCurrentItemUri == null && TextUtils.isEmpty(nameString)
            && TextUtils.isEmpty(priceString) && TextUtils.isEmpty(quantityString) && iconImage == null) {
        // Since no fields were modified, we can return early without creating a new item.
        // No need to create ContentValues and no need to do any ContentProvider operations.
        return;
    }

    // Create a ContentValues object where column names are the keys and item attributes from the editor are the values.
    ContentValues values = new ContentValues();

    // Find image by the member variable "photos" and get the bytes
    byte[] bytes = Utils.getImageBytes(photos);
    values.put(ItemEntry.IMAGE_VIEW, bytes);

    values.put(ItemEntry.COLUMN_NAME, nameString);

    int price = 0;
    if (!TextUtils.isEmpty(priceString)) {
        price = Integer.parseInt(priceString);
    }
    values.put(ItemEntry.COLUMN_PRICE, price);

    values.put(ItemEntry.COLUMN_QUANTITY, quantityString);

    // Determine if this is a new or existing item by checking if mCurrentItemUri is null or not
    if (mCurrentItemUri == null) {
        // This is a NEW item, so insert a new item into the provider,
        // returning the content URI for the new item.
        Uri newUri = getContentResolver().insert(ItemEntry.CONTENT_URI, values);
        // Show a toast message depending on whether or not the insertion was successful.
        if (newUri == null) {
            // If the new content URI is null, then there was an error with insertion.
            Toast.makeText(this, getString(R.string.insert_item_failed), Toast.LENGTH_SHORT).show();
        } else {
            // Otherwise, the insertion was successful and we can display a toast.
            Toast.makeText(this, getString(R.string.insert_item_successful), Toast.LENGTH_SHORT).show();
        }
    } else {
        // Otherwise this is an EXISTING item, so update the item with content URI: mCurrentItemUri
        // and pass in the new ContentValues. Pass in null for the selection and selection args
        // because mCurrentItemUri will already identify the correct row in the database that
        // we want to modify.
        int rowsAffected = getContentResolver().update(mCurrentItemUri, values, null, null);
        // Show a toast message depending on whether or not the update was successful.
        if (rowsAffected == 0) {
            // If no rows were affected, then there was an error with the update.
            Toast.makeText(this, getString(R.string.edit_item_failed), Toast.LENGTH_SHORT).show();
        } else {
            // Otherwise, the update was successful and we can display a toast.
            Toast.makeText(this, getString(R.string.edit_item_successful), Toast.LENGTH_SHORT).show();
        }
    }
}

以及图像方法的 Utils 文件:

public class Utils {

// Used in saveItem
// Adding the if/else statement here allows the picture to be null
// But now the picture disappears when you update an item without taking a new pic.
public static byte[] getImageBytes(Bitmap bitmap) {
    if (bitmap != null) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        return stream.toByteArray();
    } else {
        return null;
    }
}

// Used in OnLoadFinished (Editor) and cursor adapter
public static Bitmap getImage(byte[] image) {
    return BitmapFactory.decodeByteArray(image, 0, image.length);
}
}

我相当确定问题出在 saveItem 方法中,但如果您想查看整个文件,请告诉我。

最佳答案

这项工作的最佳方法是,您应该将图像保存在手机目录中,根据您的要求,该目录可从图库访问/不可访问,并将文件路径保存在图像列中,这样您就可以在需要加载时访问该图像。我也在我的一个离线应用程序中遵循相同的方法,该方法运行顺利,没有任何问题,但请确保每当您对任何行执行删除选项时,此时您还应该删除该文件以实现更好的存储管理。

关于java - 图像不会保留在我的数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47345532/

相关文章:

java - setImageResource 或 setImageDrawable 不显示图像

转换 EJB 时抛出 java.lang.ClassCastException : com. sun.proxy.$Proxy

android - 如何设置 View 的背景颜色

android - Phonegap 1.4.1 WebIntent 插件错误 "Class not found"Android

wpf - Linq查询非常慢

ios - Swift - SharkORM 忽略并加密属性

java - 为什么这个 eclipse 错误显示以及它的解决方案应该是什么

java - 是否可以在 Android 的 App 中创建 App Widget?

android - android web View 中的动态进度条

android - 使用 root 访问权限在 Android 6.0+ 中修改另一个应用程序的 SQLite 数据库