android - 当我单击要添加的图像时遇到错误,我的代码中是否存在任何差异
问题描述
这是数据库的代码和在数据库中添加图像的活动。数据库和活动的名称分别是 database 和 camera_activity。
数据库-:
package com.database.log_on;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class database extends SQLiteOpenHelper {
public static final String data = "imagedata.db";
public static final String DBLOCATION = "/data/data/com.database.log_on/databases/";
private Context mContext;
private SQLiteDatabase mDatabase;
public database(Context context){
super(context, data, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void OpenDatabase() {
String dbPath = mContext.getDatabasePath(data).getPath();
if (mDatabase != null && mDatabase.isOpen()) {
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void CloseDatabase() {
if (mDatabase != null) {
mDatabase.close();
}
}
public long ImageInsert(int id, byte[] image) {
ContentValues content = new ContentValues();
content.put("ID", id);
content.put("IMAGE", image);
OpenDatabase();
long returnValue = mDatabase.insert("GALLERYPIC", null, content);
CloseDatabase();
return returnValue;
}
}
在活动中,我使用了上述数据库来存储图像,并且数据库存储在手机本身的活动中:
package com.database.log_on;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import static android.media.MediaRecorder.VideoSource.CAMERA;
public class cameraactivity extends AppCompatActivity {
Button submit,picture,showit;
private static final String IMAGE_DIRECTORY = "/demonuts";
ImageView img_view;
database dbf;
private int GALLERY = 1, CAMERA = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cameraactivity);
submit=(Button)findViewById(R.id.submit);
picture=(Button)findViewById(R.id.images);
img_view=(ImageView)findViewById(R.id.img_camera);
showit=(Button)findViewById(R.id.btn_show);
dbf=new database(cameraactivity.this);
File database1 = getApplicationContext().getDatabasePath(database.data);
if(false == database1.exists()){
dbf.getReadableDatabase();
if(copyDatabase(this)){
Toast.makeText(this, "Database copied successfully", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
return;
}
}
picture.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
showPictureDialog();
}
});
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int id=Integer.parseInt(getIntent().getStringExtra("idl"));
try {
long result = dbf.ImageInsert(id,imageViewToByte(img_view));
if (result > 0)
Toast.makeText(cameraactivity.this, "Data Inserted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(cameraactivity.this, "Data Not Inserted", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(cameraactivity.this, "Please Check code...", Toast.LENGTH_SHORT).show();
}
}
});
}
public byte[] imageViewToByte(ImageView image) {
Bitmap bitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == GALLERY) {
if (data != null) {
Uri contentURI = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
String path = saveImage(bitmap);
Toast.makeText(cameraactivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
img_view.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(cameraactivity.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
} else if (requestCode == CAMERA) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
img_view.setImageBitmap(thumbnail);
saveImage(thumbnail);
Toast.makeText(cameraactivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
}
}
private void showPictureDialog() {
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle("Select Action");
String[] pictureDialogItems = {"Select photo from gallery", "Capture photo from camera"};
pictureDialog.setItems(pictureDialogItems,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
}
});
pictureDialog.show();
}
public String saveImage(Bitmap myBitmap) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File wallpaperDirectory = new File(
Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
public void choosePhotoFromGallary() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, GALLERY);
}
private void takePhotoFromCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA);
}
private boolean copyDatabase(Context context) {
try {
InputStream inputStream = context.getAssets().open(database.data);
String outFileName = database.DBLOCATION + database.data;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[]buff = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0) {
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.w("signup","DB copied");
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
所有函数和变量都定义良好,我得到的错误是“无法分配 51916812 字节分配,16777216 个空闲字节和 44MB 直到 OOM”。
解决方案
对于大小为 49M(51916812 字节)的图像,即使您设法将图像存储在数据库中,您也会遇到问题。CursorWindow有2M的限制,因此您将无法使用标准SQLiteDatabase类检索图像。
- 即使是 0.5M,您也可能会发现在数据库中存储图像存在问题。根据 SQLite 的发现,可以有效且高效地存储多达 100k(可能更多)的图像 - 比文件系统快 35%
因此,您不应该存储图像,而是将图像作为文件保存在合适的位置,并将图像的路径存储在数据库中。
但是,您当前的问题是失败时的应用程序只有 16M 的可用内存。我建议阅读Loading Large Bitmaps Efficiently或进行搜索,例如在内存不足的 android 图像上
推荐阅读
- google-cloud-platform - Stackdriver 用户定义的监控中没有数据
- sql - SQL - 使用同一表中两个现有行的总和插入新行
- reactjs - React 和 typescript fortawesome 类型
- r - 如何从 dfm 中删除稀有术语?
- java - 在Android中具有固定点数的谷歌地图用户可编辑多边形?
- jmeter - 如何使用Jmeter中的正则表达式提取器提取避免特殊字符
- gatsby - 我无法通过 Gatsby 连接到 Contentful
- r - 有条件地彩色条形图
- c# - 使用 ReplaceOne 执行 Upsert,但如果记录存在则递增其中一个字段
- powershell - 使用 powershell 从 Excel 获取数据并将其写入 CSV 文件