在 SQLite 数据库中上传图片 Android
Image Upload In SQLite Database Android
我有google关于如何插入。但无法得到任何正确的答案。
我必须将图库中的图像插入到 sqlite 数据库中。我试过了。但是无法执行图像插入。
public class MainActivity 扩展 AppCompatActivity 实现 AdapterView.OnItemSelectedListener, View.OnClickListener {
private static final int SELECT_PICTURE = 1;
protected static ImageView imPhoto;
DatabaseHelperAdapter databaseHelperAdapter;
Button btnSubmit;
private String selectedImagePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("Register");
databaseHelperAdapter = new DatabaseHelperAdapter(this);
imPhoto = (ImageView) findViewById(R.id.imPhoto);
imPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
imPhoto.setVisibility(View.VISIBLE);
imPhoto.setImageURI(selectedImageUri);
}
}
}
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);
}
//Insert into database
public void addUser(View view) throws IOException {
byte[] byteImage1;
FileInputStream instream = new FileInputStream(selectedImagePath);
BufferedInputStream bif = new BufferedInputStream(instream);
byteImage1 = new byte[bif.available()];
bif.read(byteImage1);
byte[] image = byteImage1;
long id = databaseHelperAdapter.insertData(fname, lname, password, email, birthday, gender, image);
if (id < 0) {
Message.message(this, "Record not inserted");
} else {
Intent intent = new Intent(MainActivity.this, Welcome.class);
startActivity(intent);
Message.message(this, "Record Inserted Successfully");
}
}
}
2]数据库文件
import java.sql.Blob;
public class DatabaseHelperAdapter {
public SQLiteDatabase db;
DatabaseHelper helper;
public DatabaseHelperAdapter(Context context) {
helper = new DatabaseHelper(context);
}
public long insertData(String fname, String lname, String password, String email, String birthday, String gender, byte[] image) {
SQLiteDatabase sqLiteDatabase = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.FNAME, fname);
contentValues.put(DatabaseHelper.LNAME, lname);
contentValues.put(DatabaseHelper.PASSWORD, password);
contentValues.put(DatabaseHelper.EMAIL, email);
contentValues.put(DatabaseHelper.BIRTHDAY, birthday);
contentValues.put(DatabaseHelper.GENDER, gender);
contentValues.put(DatabaseHelper.IMAGE, String.valueOf(image));
long id = sqLiteDatabase.insert(DatabaseHelper.TABLE_NAME, null, contentValues);
sqLiteDatabase.close();
return id;
}
public String getSinlgeEntry(String email) {
SQLiteDatabase sqLiteDatabase = helper.getWritableDatabase();
Cursor cursor = sqLiteDatabase.query(DatabaseHelper.TABLE_NAME, null, DatabaseHelper.EMAIL + " =?", new String[]{email}, null, null, null);
if (cursor.getCount() < 1) // UserName Not Exist
{
cursor.close();
return "NOT EXIST";
}
cursor.moveToFirst();
String password = cursor.getString(cursor.getColumnIndex(DatabaseHelper.PASSWORD));
cursor.close();
return password;
}
public DatabaseHelperAdapter open() {
db = helper.getWritableDatabase();
return this;
}
public void close() {
db.close();
}
class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "LoginForm";
private static final String TABLE_NAME = "LoginTable";
private static final int DATABASE_VERSION = 2;
private static final String UID = "_id";
private static final String FNAME = "FName";
private static final String LNAME = "LName";
private static final String PASSWORD = "Password";
private static final String EMAIL = "Email";
private static final String BIRTHDAY = "Birthday";
private static final String GENDER = "Gender";
private static final String IMAGE = "Image";
private static final String CREATE_TABLE = " CREATE TABLE " + TABLE_NAME + " ( " + UID + " INTEGER PRIMARY KEY AUTOINCREMENT , "
+ FNAME + " VARCHAR(255) , "
+ LNAME + " VARCHAR(255) ,"
+ PASSWORD + " text ,"
+ EMAIL + " VARCHAR(255) UNIQUE ,"
+ BIRTHDAY + " VARCHAR(255) ,"
+ GENDER + " VARCHAR(255)"
+ IMAGE +" BLOB );";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
private Context context;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
Message.message(context, "Constructor is called");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_TABLE);
Message.message(context, "onCreate is called");
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Message.message(context, "onUpdates is called");
db.execSQL(DROP_TABLE);
onCreate(db);
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
}
}
3]错误日志:
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at java.io.File.fixSlashes(File.java:185)
at java.io.File.<init>(File.java:134)
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at com.example.zeronesnatik.loginform11.MainActivity.addUser(MainActivity.java:170)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
09-18 13:01:42.903 2178-2532/? W/ActivityManager﹕ Force finishing activity com.example.zeronesnatik.loginform11/.MainActivity
09-18 13:01:42.962 2178-7631/? I/OpenGLRenderer﹕ Initialized EGL, version 1.4
09-18 13:01:42.973 2178-7631/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented
09-18 13:01:42.973 2178-7631/? W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0x9deff340, error=EGL_SUCCESS
09-18 13:01:43.420 2178-2199/? W/ActivityManager﹕ Activity pause timeout for ActivityRecord{3e0c9d7b u0 com.example.zeronesnatik.loginform11/.MainActivity t43 f}
09-18 13:01:44.059 2178-2334/? W/AudioTrack﹕ AUDIO_OUTPUT_FLAG_FAST denied by client
我认为更简单的解决方案是仅将 SELECT_PICTURE
Intent 给出的图像路径保存在数据库中。无论如何,如果你强制保存图片内容,我相信问题出在:
contentValues.put(DatabaseHelper.IMAGE, String.valueOf(image));
因为您要向字节列 (BLOB) 传递一个简单的字符串。 BLOB 有点棘手,您不能将它们当作简单的字符串来处理。尝试像这样使用绑定语句进行插入:
SQLiteStatement insertStmt = db.compileStatement("INSERT INTO ....");
insertStmt.clearBindings();
insertStmt.bindBlob(3, (byte[])yourImageData);
insertStmt.executeInsert();
参见 this question 了解其他 blob 处理技术,例如 Bitmap.CompressFormat
和 base64 encoding/decoding。
您不应在 sqlite 中保存图像或大量数据,因为它们会降低性能。你可以在数据库中保存图片文件路径,你想对图片做任何操作,你可以使用-File file = new File(SAVED_IMAGE_FILE_PATH);
获取图片
我有google关于如何插入。但无法得到任何正确的答案。 我必须将图库中的图像插入到 sqlite 数据库中。我试过了。但是无法执行图像插入。
public class MainActivity 扩展 AppCompatActivity 实现 AdapterView.OnItemSelectedListener, View.OnClickListener {
private static final int SELECT_PICTURE = 1;
protected static ImageView imPhoto;
DatabaseHelperAdapter databaseHelperAdapter;
Button btnSubmit;
private String selectedImagePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("Register");
databaseHelperAdapter = new DatabaseHelperAdapter(this);
imPhoto = (ImageView) findViewById(R.id.imPhoto);
imPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
imPhoto.setVisibility(View.VISIBLE);
imPhoto.setImageURI(selectedImageUri);
}
}
}
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);
}
//Insert into database
public void addUser(View view) throws IOException {
byte[] byteImage1;
FileInputStream instream = new FileInputStream(selectedImagePath);
BufferedInputStream bif = new BufferedInputStream(instream);
byteImage1 = new byte[bif.available()];
bif.read(byteImage1);
byte[] image = byteImage1;
long id = databaseHelperAdapter.insertData(fname, lname, password, email, birthday, gender, image);
if (id < 0) {
Message.message(this, "Record not inserted");
} else {
Intent intent = new Intent(MainActivity.this, Welcome.class);
startActivity(intent);
Message.message(this, "Record Inserted Successfully");
}
}
}
2]数据库文件
import java.sql.Blob;
public class DatabaseHelperAdapter {
public SQLiteDatabase db;
DatabaseHelper helper;
public DatabaseHelperAdapter(Context context) {
helper = new DatabaseHelper(context);
}
public long insertData(String fname, String lname, String password, String email, String birthday, String gender, byte[] image) {
SQLiteDatabase sqLiteDatabase = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.FNAME, fname);
contentValues.put(DatabaseHelper.LNAME, lname);
contentValues.put(DatabaseHelper.PASSWORD, password);
contentValues.put(DatabaseHelper.EMAIL, email);
contentValues.put(DatabaseHelper.BIRTHDAY, birthday);
contentValues.put(DatabaseHelper.GENDER, gender);
contentValues.put(DatabaseHelper.IMAGE, String.valueOf(image));
long id = sqLiteDatabase.insert(DatabaseHelper.TABLE_NAME, null, contentValues);
sqLiteDatabase.close();
return id;
}
public String getSinlgeEntry(String email) {
SQLiteDatabase sqLiteDatabase = helper.getWritableDatabase();
Cursor cursor = sqLiteDatabase.query(DatabaseHelper.TABLE_NAME, null, DatabaseHelper.EMAIL + " =?", new String[]{email}, null, null, null);
if (cursor.getCount() < 1) // UserName Not Exist
{
cursor.close();
return "NOT EXIST";
}
cursor.moveToFirst();
String password = cursor.getString(cursor.getColumnIndex(DatabaseHelper.PASSWORD));
cursor.close();
return password;
}
public DatabaseHelperAdapter open() {
db = helper.getWritableDatabase();
return this;
}
public void close() {
db.close();
}
class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "LoginForm";
private static final String TABLE_NAME = "LoginTable";
private static final int DATABASE_VERSION = 2;
private static final String UID = "_id";
private static final String FNAME = "FName";
private static final String LNAME = "LName";
private static final String PASSWORD = "Password";
private static final String EMAIL = "Email";
private static final String BIRTHDAY = "Birthday";
private static final String GENDER = "Gender";
private static final String IMAGE = "Image";
private static final String CREATE_TABLE = " CREATE TABLE " + TABLE_NAME + " ( " + UID + " INTEGER PRIMARY KEY AUTOINCREMENT , "
+ FNAME + " VARCHAR(255) , "
+ LNAME + " VARCHAR(255) ,"
+ PASSWORD + " text ,"
+ EMAIL + " VARCHAR(255) UNIQUE ,"
+ BIRTHDAY + " VARCHAR(255) ,"
+ GENDER + " VARCHAR(255)"
+ IMAGE +" BLOB );";
private static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
private Context context;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
Message.message(context, "Constructor is called");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_TABLE);
Message.message(context, "onCreate is called");
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Message.message(context, "onUpdates is called");
db.execSQL(DROP_TABLE);
onCreate(db);
} catch (SQLException e) {
Message.message(context, "" + e);
}
}
}
}
3]错误日志:
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
at java.io.File.fixSlashes(File.java:185)
at java.io.File.<init>(File.java:134)
at java.io.FileInputStream.<init>(FileInputStream.java:103)
at com.example.zeronesnatik.loginform11.MainActivity.addUser(MainActivity.java:170)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4002)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
09-18 13:01:42.903 2178-2532/? W/ActivityManager﹕ Force finishing activity com.example.zeronesnatik.loginform11/.MainActivity
09-18 13:01:42.962 2178-7631/? I/OpenGLRenderer﹕ Initialized EGL, version 1.4
09-18 13:01:42.973 2178-7631/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented
09-18 13:01:42.973 2178-7631/? W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0x9deff340, error=EGL_SUCCESS
09-18 13:01:43.420 2178-2199/? W/ActivityManager﹕ Activity pause timeout for ActivityRecord{3e0c9d7b u0 com.example.zeronesnatik.loginform11/.MainActivity t43 f}
09-18 13:01:44.059 2178-2334/? W/AudioTrack﹕ AUDIO_OUTPUT_FLAG_FAST denied by client
我认为更简单的解决方案是仅将 SELECT_PICTURE
Intent 给出的图像路径保存在数据库中。无论如何,如果你强制保存图片内容,我相信问题出在:
contentValues.put(DatabaseHelper.IMAGE, String.valueOf(image));
因为您要向字节列 (BLOB) 传递一个简单的字符串。 BLOB 有点棘手,您不能将它们当作简单的字符串来处理。尝试像这样使用绑定语句进行插入:
SQLiteStatement insertStmt = db.compileStatement("INSERT INTO ....");
insertStmt.clearBindings();
insertStmt.bindBlob(3, (byte[])yourImageData);
insertStmt.executeInsert();
参见 this question 了解其他 blob 处理技术,例如 Bitmap.CompressFormat
和 base64 encoding/decoding。
您不应在 sqlite 中保存图像或大量数据,因为它们会降低性能。你可以在数据库中保存图片文件路径,你想对图片做任何操作,你可以使用-File file = new File(SAVED_IMAGE_FILE_PATH);