将图像从相机保存到数据库

时间:2017-11-02 12:05:57

标签: java android sqlite nullpointerexception

在我的示例应用程序中,我想从相机和图库中保存图像并保存到sqlite数据库。这是我的代码。

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();
private static final int GAL_CODE = 24;
private static final int CAM_CODE = 31;
private static final String ALLOW_KEY = "ALLOWED";
private static final String CAMERA_PREF = "camera_pref";

private ImageView imageView;
private EditText nameET, addrET;
private ImageButton galleryBtn, cameraBtn;
private Button saveBtn;

private String address;
private String name;

private DBHelper dbHelper;
private boolean fromCamera = false;
private boolean fromGallery = false;
private Uri outputFileUri;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    dbHelper = new DBHelper(this);

    imageView = (ImageView) findViewById(R.id.image);
    nameET = (EditText) findViewById(R.id.nameET);
    addrET = (EditText) findViewById(R.id.addrET);
    galleryBtn = (ImageButton) findViewById(R.id.galleryBtn);
    cameraBtn = (ImageButton) findViewById(R.id.cameraBtn);
    saveBtn = (Button) findViewById(R.id.saveBtn);

    galleryBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            selectImage();
        }
    });

    cameraBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            takePhoto();
        }
    });


    saveBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            saveUser();
        }
    });

}

private void takePhoto() {

    File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
    root.mkdirs();

    String fileName = "img_" + System.currentTimeMillis() + ".jpg";
    File sdCardImageMainDir = new File(root, fileName);
    outputFileUri = Uri.fromFile(sdCardImageMainDir);

    List<Intent> cameraIntents = new ArrayList<>();
    Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    PackageManager pm = getPackageManager();
    List<ResolveInfo> listCam = pm.queryIntentActivities(captureIntent, 0);

    for (ResolveInfo info: listCam){
        String packageName = info.activityInfo.packageName;
        Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        cameraIntents.add(intent);
    }
    startActivityForResult(captureIntent, CAM_CODE);
}

private void saveUser() {

    name = nameET.getText().toString();
    address = addrET.getText().toString();

    if (!address.isEmpty() && !name.isEmpty()){
        User user = new User(name, address);
        dbHelper.saveInputField(user);
        dbHelper.close();
        startActivity(new Intent(MainActivity.this, ShowActivity.class));
    }

}

private void selectImage() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GAL_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GAL_CODE && resultCode == RESULT_OK){
        Uri imgUri = data.getData();

        if (imgUri != null){
            if(saveImageToDB(imgUri)){
                Toast.makeText(this, "Saved Image", Toast.LENGTH_SHORT).show();
            }

        }

    }

    if (requestCode == CAM_CODE && resultCode == RESULT_OK){
        Bitmap bitmap = (Bitmap) data.getExtras().get("data");
        if (bitmap != null){
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            byte[] imageinByte = outputStream.toByteArray();

            User user = new User(name, address, imageinByte);
            dbHelper.saveInputField(user);  // error on this line
        }
    }

}

这是我的用户模型类。

public class User {

public int id;
public String name;
public String address;
public byte[] image;

public User() {
}

public User(int id) {
    this.id = id;
}

public User(String name, String address, byte[] camImage) {
    this.name = name;
    this.address = address;
    this.image = camImage;
}

public User(int id, String name, String address, byte[] camImage) {
    this.id = id;
    this.name = name;
    this.address = address;
    this.image = camImage;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public byte[] getImage() {
    return image;
}

public void setImage(byte[] image) {
    this.image = image;
}
}

我的数据库助手类可以在这里看到:

public class DBHelper {

private static final String DATABASE_NAME = "UsersDemo.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "profileInfo";

private static final String COL_ID = "databaseId";
private static final String COL_NAME = "name";
private static final String COL_ADDRESS = "addr";
private static final String COL_IMAGE = "image";

private Context mCtx;

private DatabaseManager databaseManager;
private SQLiteDatabase db;

public DBHelper (Context context){
    this.mCtx = context;
    databaseManager = new DatabaseManager(mCtx);
}

public DBHelper open() throws SQLException{
    db = databaseManager.getWritableDatabase();
    return this;
}

public void close(){
    databaseManager.close();
}

public void saveInputField(User user){
    ContentValues values = new ContentValues();

    values.put(COL_NAME, user.getName());
    values.put(COL_ADDRESS, user.getAddress());
    values.put(COL_IMAGE, user.getImage());

    db.insert(TABLE_NAME, null, values);
    db.close();
}

public User getCurrentUser(int id){
    Cursor cursor = db.query(true, TABLE_NAME, new String[]{COL_ID, COL_NAME, COL_ADDRESS}, COL_ID + "=?", new String[]{String.valueOf(id)}, null, null, null, null);

    if (cursor != null && cursor.moveToFirst()){

        User user = new User(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getBlob(1));
        return user;
    }

    return null;

}

public void saveCamerayImage(byte[] imageBytes){
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_IMAGE, imageBytes);
    db.insert(TABLE_NAME, null, contentValues);
}

public void saveGalleryImage(byte[] imageBytes){
    ContentValues contentValues = new ContentValues();
    contentValues.put(COL_IMAGE, imageBytes);
    db.insert(TABLE_NAME, null, contentValues);
}

public byte[] getImage(){
    Cursor cursor = db.query(true, TABLE_NAME, new String[]{COL_IMAGE,}, null, null, null, null, COL_ID + " DESC", "1");
    if (cursor.moveToFirst()){
        byte[] blob = cursor.getBlob(cursor.getColumnIndex(COL_IMAGE));
        cursor.close();
        return blob;
    }
    cursor.close();
    Toast.makeText(mCtx, "No Image Found", Toast.LENGTH_SHORT).show();
    return null;
}


public class DatabaseManager extends SQLiteOpenHelper {

    public DatabaseManager(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        String db_create = "Create Table " + TABLE_NAME + " ("
                + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + COL_NAME + " TEXT, "
                + COL_ADDRESS + " TEXT, "
                + COL_IMAGE + " BLOB NOT NULL );";
        sqLiteDatabase.execSQL(db_create);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
        onCreate(sqLiteDatabase);
    }

}

}

在运行应用程序时,我在logcat中收到此错误消息。我似乎无法理解为什么它会显示出来。

我的logcat如下:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long android.database.sqlite.SQLiteDatabase.insert(java.lang.String, java.lang.String, android.content.ContentValues)' on a null object reference
                                                                         at com.joey.example.dbsqlite.DBHelper.saveInputField(DBHelper.java:53)
                                                                         at com.joey.example.dbsqlite.MainActivity.onActivityResult(MainActivity.java:170)
                                                                         at android.app.Activity.dispatchActivityResult(Activity.java:6919)
                                                                         at android.app.ActivityThread.deliverResults(ActivityThread.java:4184)
                                                                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:4231) 
                                                                         at android.app.ActivityThread.-wrap20(ActivityThread.java) 
                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                                         at android.os.Handler.dispatchMessage(Handler.java:110) 
                                                                         at android.os.Looper.loop(Looper.java:203) 
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6269) 
                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063) 
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924) 

有人可以解释如何解决此错误吗?感谢。

3 个答案:

答案 0 :(得分:0)

在写入数据库时​​,您忘记在方法中调用open() databaseManager.getWritableDatabase()允许您写入数据库的权限。

我也觉得在调用方法时不需要返回DBHelper。更改此内容

 public DBHelper open() throws SQLException {
        db = databaseManager.getWritableDatabase();
        return this;
    }

答案 1 :(得分:0)

将图像保存到sqlite是个坏主意,但是如果你还想继续下去,这里有代码

public static void insertPicture(byte[] data)
{

SQLiteDatabase db = thisAct.openOrCreateDatabase(ConstantCodes.IMAGE_DATABASE, 2, null);
ContentValues values = new ContentValues(1);
values.put("photo", data);
db.insert("photos", null, values);
db.close();

} 

快乐的编码!!

答案 2 :(得分:0)

您需要致电

db = databaseManager.getWritableDatabase();

saveInputField之前,对db对象做任何事情。处理db

的其他方法也是如此