首页 > 解决方案 > 当我单击要添加的图像时遇到错误,我的代码中是否存在任何差异

问题描述

这是数据库的代码和在数据库中添加图像的活动。数据库和活动的名称分别是 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”。

标签: androidsqliteandroid-studioandroid-intent

解决方案


对于大小为 49M(51916812 字节)的图像,即使您设法将图像存储在数据库中,您也会遇到问题。CursorWindow有2M的限制,因此您将无法使用标准SQLiteDatabase类检索图像。

因此,您不应该存储图像,而是将图像作为文件保存在合适的位置,并将图像的路径存储在数据库中。

但是,您当前的问题是失败时的应用程序只有 16M 的可用内存。我建议阅读Loading Large Bitmaps Efficiently或进行搜索,例如在内存不足的 android 图像上


推荐阅读