我正在尝试制作一个应用程序,我可以在其中导入图片,添加一些详细信息,然后将此信息保存到设备上的 SQLite 数据库中。在将详细信息添加到数据库之前,我将图像压缩并保存到设备中。当我从相机中选择一个大图像时遇到问题,它会导致数据库锁定?但是,当保存没有图像的详细信息时,它会成功。请看我下面的代码和错误:
数据库:
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "showcaseManager";
// Showcase table name
private static final String TABLE_SHOWCASE = "showcase";
// Showcase Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_DESCRIPTION = "description";
private static final String KEY_IMAGE = "image";
private static final String KEY_RATING = "rating";
private static DatabaseHandler mInstance = null;
public static String Lock = "dblock";
public static DatabaseHandler getInstance() {
if (mInstance == null) {
mInstance = new DatabaseHandler();
}
return mInstance;
}
private DatabaseHandler() {
super(MainActivity.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_SHOWCASE_TABLE = "CREATE TABLE " + TABLE_SHOWCASE + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_DESCRIPTION + " TEXT," + KEY_IMAGE + " TEXT," + KEY_RATING + " TEXT" + ")";
db.execSQL(CREATE_SHOWCASE_TABLE);
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SHOWCASE);
// Create tables again
onCreate(db);
}
/**
* All CRUD(Create, Read, Update, Delete) Operations
*/
// Adding new item. ##Correct##
public void addItem(ShowcaseItemLite item) {
Log.v("Database", "Adding Item 1/2: " + item.getName());
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, item.getName()); // Item Name
values.put(KEY_DESCRIPTION, item.getDescription()); // Item Description
values.put(KEY_IMAGE, item.getCompressedImagePath()); // Item Image Path
values.put(KEY_RATING, item.getRating()); // Item Rating
// Inserting Row
db.insert(TABLE_SHOWCASE, null, values);
db.close(); // Closing database connection
Log.v("Database", "Item added 2/2.");
}
// Getting single item. ##Correct##
public ShowcaseItemLite getItem(int id) {
Log.v("Database", "Getting item 1/2: " + id);
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_SHOWCASE, new String[] { KEY_ID,
KEY_NAME, KEY_DESCRIPTION, KEY_IMAGE, KEY_RATING }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
ShowcaseItemLite item = new ShowcaseItemLite(Integer.parseInt(cursor.getString(0)));
item.setName(cursor.getString(1));
item.setDescription(cursor.getString(2));
item.setImagePath(cursor.getString(3));
item.setRating(Float.valueOf(cursor.getString(4)));
Log.v("Database", "Item Got 2/2: " + cursor.getString(1));
// return item
return item;
}
// Getting All Items. ##Correct##
public List<ShowcaseItemLite> getAllItems() {
Log.v("Database", "Getting all items 1/2.");
List<ShowcaseItemLite> itemList = new ArrayList<ShowcaseItemLite>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SHOWCASE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
ShowcaseItemLite item = new ShowcaseItemLite(Integer.parseInt(cursor.getString(0)));
item.setName(cursor.getString(1));
item.setDescription(cursor.getString(2));
item.setCompressedImagePath(cursor.getString(3));
item.setRating(Float.valueOf(cursor.getString(4)));
// Adding Item to list
itemList.add(item);
} while (cursor.moveToNext());
}
Log.v("Database", "Received all items 2/2. Amount: " + itemList.size());
// return item list
return itemList;
}
// Updating single item. ##Correct##
public int updateItem(ShowcaseItemLite item) {
Log.v("Database", "Updating Item 1/2: " + item.getName());
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, item.getName());
values.put(KEY_DESCRIPTION, item.getDescription());
values.put(KEY_IMAGE, item.getImagePath());
// updating row
int i = db.update(TABLE_SHOWCASE, values, KEY_ID + " = ?",
new String[] { String.valueOf(item.getDatabaseID()) });
db.close();
Log.v("Database", "Item Updated 2/2");
return i;
}
// Deleting single item
public void deleteItem(ShowcaseItemLite item) {
synchronized(Lock) {
Log.v("Database", "Deleting Item 1/2: " + item.getName());
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_SHOWCASE, KEY_ID + " = ?",
new String[] { String.valueOf(item.getDatabaseID()) });
db.close();
Log.v("Database", "Item deleted 2/2: ");
}
}
// Getting items Count
public int getItemCount() {
Log.v("Database", "Preparing to get Item Count 1/2. ");
String countQuery = "SELECT * FROM " + TABLE_SHOWCASE;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
Log.v("Database", "Received item count 2/2: " + count);
// return count
return count;
}
}
物品类别:
public class ShowcaseItemLite {
private String name;
private String description;
private String imagePath;
private float rating;
private String file_path = MainActivity.getStorageFilePath();
private int databaseID = 0;
private String thumbnailStoredLoc;
private String compressedImageStoredLoc;
public ShowcaseItemLite(int databaseID){
this.setDatabaseID(databaseID);
}
public ShowcaseItemLite(String name, String description, String imagePath, float rating){
this.name = name;
this.description = description;
this.imagePath = imagePath;
this.rating = rating;
}
public String getName(){
return name;
}
public String getDescription(){
return description;
}
public String getImagePath(){
return imagePath;
}
public float getRating(){
return rating;
}
public int getDatabaseID() {
return databaseID;
}
public void setDatabaseID(int databaseID) {
this.databaseID = databaseID;
}
public String getFile_path() {
return file_path;
}
public void setFile_path(String file_path) {
this.file_path = file_path;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public void setRating(float rating) {
this.rating = rating;
}
public void saveImageAndThumb(int imageID){
Log.v("IMAGE_SAVE_LOG", "Preparing to store images.");
if(imagePath != null && !imagePath.equals("")){
try{
File dir = new File(file_path);
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(dir, "I"+imageID+".bmp");
if(!file.exists()){
FileOutputStream fOut = new FileOutputStream(file);
Bitmap bitmap = shrinkBitmap(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
//bitmap.recycle();
this.compressedImageStoredLoc = file.getAbsolutePath().toString();
Log.v("IMAGE_SAVE_LOG", "Saved image path: " + compressedImageStoredLoc);
}else{
Log.v("IMAGE_SAVE_LOG", "Image exists. Skipping creation: " + file.toString());
this.compressedImageStoredLoc = file.getAbsolutePath().toString();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
File dir = new File(file_path);
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(dir, "T"+imageID+".bmp");
if(!file.exists()){
FileOutputStream fOut = new FileOutputStream(file);
Bitmap bitmap = shrinkBitmapToThumb(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
this.thumbnailStoredLoc = file.getAbsolutePath().toString();
}else{
Log.v("IMAGE_SAVE_LOG", "Thumbnail exists. Skipping creation: " + file.toString());
this.thumbnailStoredLoc = file.getAbsolutePath().toString();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private Bitmap shrinkBitmap(String file){
int height = 200;
int width = 200;
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
return bitmap;
}
private Bitmap shrinkBitmapToThumb(String file){
int height = 100;
int width = 100;
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
return bitmap;
}
public String getImageThumbnailPath() {
if(thumbnailStoredLoc == null){
if(compressedImageStoredLoc != null){
return getCompressedImagePath().replace("I", "T");
}else{
return null;
}
}else{
return thumbnailStoredLoc;
}
}
public String setImageThumbnailPath() {
return thumbnailStoredLoc;
}
public String getCompressedImagePath() {
return compressedImageStoredLoc;
}
public void setCompressedImagePath(String image) {
this.compressedImageStoredLoc = image;
}
}
新物品类别:
public class NewItemActivity extends Activity {
private static final int SELECT_PICTURE = 0;
public static int TAKE_IMAGE = 111;
private String selectedImagePath = null;
private ImageView imageView;
private String selectedCameraPath;
private int itemID;
public NewItemActivity() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_new_item);
imageView = (ImageView)findViewById(R.id.newItemImageView);
Bundle extras = getIntent().getExtras();
itemID = extras.getInt("newID");
Log.v("IMAGE_SAVE_LOG", "New ImageID: " + itemID);
Button galleryButton =((Button) findViewById(R.id.galleryButton));
galleryButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
});
Button cameraButton =((Button) findViewById(R.id.cameraButton));
cameraButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(NewItemActivity.this, CameraActivity.class);
NewItemActivity.this.startActivity(intent);
}
});
Button saveButton =((Button) findViewById(R.id.saveButton));
saveButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
EditText nameTextField = (EditText) findViewById(R.id.nameTextField);
String nameTextFieldString = nameTextField.getText().toString();
EditText descriptionTextField = (EditText) findViewById(R.id.descriptionTextField);
String descriptionTextFieldString = descriptionTextField.getText().toString();
RatingBar rating = (RatingBar) findViewById(R.id.newRatingbar);
Log.v("IMAGE_SAVE_LOG", "SelectedImagePath: " + selectedImagePath);
if(!nameTextFieldString.equals("")){
if(descriptionTextFieldString.equals("")){
Log.v("IMAGE_SAVE_LOG", "Creating Item 1/3." + "ItemID: " + itemID);
ShowcaseItemLite item = new ShowcaseItemLite(nameTextFieldString,"No Description.",selectedImagePath,rating.getRating());
item.saveImageAndThumb(itemID);
Log.v("IMAGE_SAVE_LOG", "Item created 2/3.");
DatabaseHandler.getInstance().addItem(item);
Log.v("IMAGE_SAVE_LOG", "Item added 3/3.");
finish();
}else{
Log.v("IMAGE_SAVE_LOG", "Creating Item 1/3.");
ShowcaseItemLite item = new ShowcaseItemLite(nameTextFieldString, descriptionTextFieldString, selectedImagePath, rating.getRating());
item.saveImageAndThumb(itemID);
Log.v("IMAGE_SAVE_LOG", "Item created 2/3.");
DatabaseHandler.getInstance().addItem(item);
Log.v("IMAGE_SAVE_LOG", "Item added 3/3.");
finish();
}
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.new_item, menu);
return true;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
imageView.setImageURI(selectedImageUri);
}
}
if (resultCode == RESULT_OK && requestCode == TAKE_IMAGE){
String cameraPath = data.getStringExtra("location");
Log.v("IMAGE_SAVE_LOG", "Camera image location: " + cameraPath);
selectedCameraPath = cameraPath;
//imageView.setImageURI(cameraPath);
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
堆栈跟踪:
11-09 20:34:42.610: E/AndroidRuntime(8970): FATAL EXCEPTION: main
11-09 20:34:42.610: E/AndroidRuntime(8970): java.lang.NullPointerException
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
11-09 20:34:42.610: E/AndroidRuntime(8970): at database.DatabaseHandler.addItem(DatabaseHandler.java:77)
11-09 20:34:42.610: E/AndroidRuntime(8970): at showcasen.NewItemActivity$3.onClick(NewItemActivity.java:84)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.view.View.performClick(View.java:4211)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.view.View$PerformClick.run(View.java:17267)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.os.Handler.handleCallback(Handler.java:615)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.os.Handler.dispatchMessage(Handler.java:92)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.os.Looper.loop(Looper.java:137)
11-09 20:34:42.610: E/AndroidRuntime(8970): at android.app.ActivityThread.main(ActivityThread.java:4898)
11-09 20:34:42.610: E/AndroidRuntime(8970): at java.lang.reflect.Method.invokeNative(Native Method)
11-09 20:34:42.610: E/AndroidRuntime(8970): at java.lang.reflect.Method.invoke(Method.java:511)
11-09 20:34:42.610: E/AndroidRuntime(8970): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
11-09 20:34:42.610: E/AndroidRuntime(8970): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
11-09 20:34:42.610: E/AndroidRuntime(8970): at dalvik.system.NativeStart.main(Native Method)