将图像保存在Android应用程序的SQLite数据库中

当您开始从Android应用程序将数据缓存到本地数据库时,迟早也需要将图像保存在该数据库中。 例如,如果您要存储有关用户在现场进行的观察的报告,该报告随后将上传到主系统,则可以方便地添加图片以更好地描述问题。

存储这些图像的第一个想法是将它们直接保存为BLOB(二进制大对象)到数据库中。 它可以工作,但这并不是最有效的方法,因为SQLite旨在存储值而不是大的二进制值。 另外,本地数据库很快就会变得很大,尤其是如果您需要保存完整大小,高质量的图片时。 如果您想对性能有一个更好的了解,可以在官方SQLite网站上找到一个基准,网址为https://www.sqlite.org/intern-v-extern-blob.html

在这种情况下,您真正​​想做的是仅在数据库中保留映像的路径,并将映像保存在应用程序的内部存储中。 当需要使用映像时,只需使用路径即可从文件系统中获取映像。 我建议您将图片保存到内部存储器中,因为它只能从您的应用程序访问,并且随时可用; 实际上,SQLite数据库本身也存储在内部存储中。

这是一个如何将图像添加到现有报表,将其保存在内部存储中以及将路径保留在数据库中的示例。 要了解有关如何创建数据库并将数据存储到数据库的更多信息,请阅读有关保存到SQLite数据库的文章

public class ApplicationDatabaseHelper extends SQLiteOpenHelper {
/**
  * Updates the current picture for the report.
  *
  * @param reportId the identifier of the report for which to save the picture
  * @param picture the picture to save to the internal storage and save path in the database.
  */
public void updateReportPicture(long reportId, Bitmap picture) {
   // Saves the new picture to the internal storage with the unique identifier of the report as 
   // the name. That way, there will never be two report pictures with the same name.
   String picturePath = "";
   File internalStorage = mContext.getDir("ReportPictures", Context.MODE_PRIVATE);
   File reportFilePath = new File(internalStorage, reportId + ".png");
   String picturePath = reportFilePath.toString();

   FileOutputStream fos = null;
   try {
      fos = new FileOutputStream(reportFilePath);
      picture.compress(Bitmap.CompressFormat.PNG, 100 /*quality*/, fos);
      fos.close();
      }
   catch (Exception ex) {
      Log.i("DATABASE", "Problem updating picture", ex);
      picturePath = "";
      }

   // Updates the database entry for the report to point to the picture
   SQLiteDatabase db = getWritableDatabase();

   ContentValues newPictureValue = new ContentValues();
   newPictureValue.put(ReportContract.ReportEntry.COLUMN_PICTURE_TITLE, 
                       picturePath);

   db.update(ReportContract.TABLE_NAME,
             newPictureValue,
             ReportContract.ReportEntry._ID + "=?",
             new String[]{String.valueOf(reportId)});
   }
}

如果将图片保存到数据库,则还需要一种获取图片以在应用程序中显示图片的方法。 以下是获取刚刚保存的图像以再次显示的方法:

public class ApplicationDatabaseHelper extends SQLiteOpenHelper {
/**
  * Gets the picture for the specified report in the database.
  *
  * @param reportId the identifier of the report for which to get the picture.
  *
  * @return the picture for the report, or null if no picture was found.
  */
public Bitmap getReportPicture(long reportId) {
   String picturePath = getReportPicturePath(reportId);
   if (picturePath == null || picturePath.length() == 0)
      return (null);

   Bitmap reportPicture = BitmapFactory.decodeFile(picturePath);

   return (reportPicture);
   }

/**
  * Gets the path of the picture for the specified report in the database.
  *
  * @param reportId the identifier of the report for which to get the picture.
  *   
  * @return the picture for the report, or null if no picture was found.
  */
private String getReportPicturePath(long reportId) {
   // Gets the database in the current database helper in read-only mode
   SQLiteDatabase db = getReadableDatabase();

   // After the query, the cursor points to the first database row
   // returned by the request
   Cursor reportCursor = db.query(ReportContract.TABLE_NAME,
                                  null,
                                  ReportContract.ReportEntry._ID + "=?",
                                  new String[]{String.valueOf(reportId)},
                                  null,
                                  null,
                                  null);
   reportCursor.moveToNext();
    
   // Get the path of the picture from the database row pointed by
   // the cursor using the getColumnIndex method of the cursor.
   String picturePath = reportCursor.getString(reportCursor.
                             getColumnIndex(ReportContract.ReportEntry.COLUMN_PICTURE_TITLE));

   return (picturePath);
   }
}

最后,如果您从数据库中删除关联的记录,则需要确保从内部存储器中删除图片。 如果保留这些图片,则应用程序使用的内部存储会随着时间的推移而变大,并且您的用户将无法删除这些图片,因为内部存储已被隐藏。

public class ApplicationDatabaseHelper extends SQLiteOpenHelper {
/**
  * Deletes the specified report from the database, removing also the associated picture from the
  * internal storage if any.
  *
  * @param reportId the report to remove.
  */
public void deleteReport(long reportId) {
   // Remove picture for report from internal storage
   String picturePath = getReportPicturePath(reportId); // See above
   if (picturePath != null && picturePath.length() != 0) {
      File reportFilePath = new File(picturePath);
      reportFilePath.delete();
   }

   // Remove the report from the database
   SQLiteDatabase db = getWritableDatabase();

   db.delete(ReportContract.TABLE_NAME,
             ReportContract.ReportEntry._ID + "=?",
             new String[]{String.valueOf(reportId)});
   }
}

翻译自: https://www.javacodegeeks.com/2015/05/saving-an-image-in-a-sqlite-database-in-your-android-application.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值