错误尝试保存和检索图像到android系统数据库 [英] Error while trying save and retrieve images into database in android

查看:131
本文介绍了错误尝试保存和检索图像到android系统数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的Andr​​oid和我有我的应用程序错误。

I am new with android and I have an error on my app.

我的应用程序执行以下操作:

My app doing the following:

1的用户可以选择从照相机或图库导入图像。

1- The user can choose to import an images from Camera or Gallery.

2 - 所有的图像都保存在数据库中,用户可以看到列表视图所有的人
在另一项活动。

2- All the images are saved in database and the user can see all of them in list view on another activity.

虽然我在菜单栏上点击图标传递给另一个活动,查看所有的图像
应用程序崩溃,并让我在日志文件中出现以下错误:

While i click in menu bar icon to pass to another activity to see all the images the app crashes and i get the following error in the log file :

11-06 15:16:17.199: E/AndroidRuntime(1789): FATAL EXCEPTION: main
11-06 15:16:17.199: E/AndroidRuntime(1789): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demodbimage/com.example.demodbimage.ImagesList}: java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

MainActivity.java

public class MainActivity extends ActionBarActivity {
    private static int FROM_CAMERA = 1;
    private static int FROM_GALLERY = 2;
    ImageView background;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        background = (ImageView)findViewById(R.id.imgBackground);
       DataBaseHandler db = new DataBaseHandler(this);
     db.deleteAllContact();



    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.activity_main_actions, menu);

        android.app.ActionBar actionBar = getActionBar();

        actionBar.setDisplayHomeAsUpEnabled(true);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;

        }
        else if(id == R.id.action_camera) {

            showOptions();

            return true;
        }
        else if(id == R.id.action_view_as_list) {

            Intent i = new Intent(MainActivity.this,ImagesList.class);
            startActivity(i);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }



    public void showOptions(){
        final String[] items = {"Camera","Gallery"};

        final int[] icons = {R.drawable.ic_camera,R.drawable.ic_gallery};


        ListAdapter adapter = new ArrayAdapter<String>( this, R.layout.list_item, items) {

            ViewHolder holder;

            class ViewHolder {
                ImageView icon;
                TextView title;
            }

            public View getView(int position, View convertView, ViewGroup parent) {
                final LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);


                if (convertView == null) {
                    convertView = inflater.inflate(R.layout.list_item, null);

                    holder = new ViewHolder();
                    holder.icon = (ImageView) convertView .findViewById(R.id.icon);

                    holder.title = (TextView) convertView .findViewById(R.id.title);
                    convertView.setTag(holder);
                } else {
                    // view already defined, retrieve view holder
                    holder = (ViewHolder) convertView.getTag();
                }     

                holder.title.setText(items[position]);
                holder.icon.setImageResource(icons[position]);
                return convertView;
            }
        };


        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("Choose photo from:");
        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                if(which == 0){
                     Intent fromCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                     startActivityForResult(fromCamera, FROM_CAMERA);

                }
                else{
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.setType("image/*");
                    startActivityForResult(i, FROM_GALLERY);

                }



            }

        });

        builder.create();
        builder.show();
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FROM_GALLERY && resultCode == RESULT_OK && null != data) {
                Uri selectedImage = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };
                Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);

                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();

                background.setImageBitmap(BitmapFactory.decodeFile(picturePath));
                insertToDatabase(BitmapFactory.decodeFile(picturePath));
        }
        else{
            if(requestCode == FROM_CAMERA  && resultCode == RESULT_OK && null != data )
            {

                Bundle extras = data.getExtras();
                Bitmap photo = extras.getParcelable("data");
                background.setImageBitmap(photo);
                insertToDatabase(photo);

            }
        }
    }
    public  void insertToDatabase(Bitmap img){
            DataBaseHandler db = new DataBaseHandler(this);
            //db.deleteAllContact();
            // get image from drawable

            //Drawable i = background.getBackground();
            //Bitmap image = ((BitmapDrawable)i).getBitmap();
            //Bitmap image = BitmapFactory.decodeResource(getResources(),R.id.imgBackground);

            // convert bitmap to byte
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            img.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            byte imageInByte[] = stream.toByteArray();

             //Inserting Contacts
            Log.d("Insert: ", "Inserting ..");
            db.addContact(new Contact("Image", imageInByte));

    }



}

DataBaseHandler.java

public class DataBaseHandler extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "imagedb";
    private static final String TABLE_CONTACTS = "contacts";

    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_IMAGE = "image";

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


    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                + KEY_IMAGE + " BLOB" + ")";
        db.execSQL(CREATE_CONTACTS_TABLE);
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

        // Create tables again
        onCreate(db);
    }


    // Adding new contact
    public void addContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, contact._name); // Contact Name
        values.put(KEY_IMAGE, contact._image); // Contact Phone

        // Inserting Row
        db.insert(TABLE_CONTACTS, null, values);
        db.close(); // Closing database connection
    }



    // Getting single contact
    Contact getContact(int id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
                KEY_NAME, KEY_IMAGE }, KEY_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
                cursor.getString(1), cursor.getBlob(1));

        // return contact
        return contact;

    }


    // Getting All Contacts
    public List<Contact> getAllContacts() {
        List<Contact> contactList = new ArrayList<Contact>();
        // Select All Query
        String selectQuery = "SELECT * FROM contacts ORDER BY name";

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Contact contact = new Contact();
                contact.setID(Integer.parseInt(cursor.getString(0)));
                contact.setName(cursor.getString(1));
                contact.setImage(cursor.getBlob(2));
                // Adding contact to list
                contactList.add(contact);
            } while (cursor.moveToNext());
        }
        // close inserting data from database
        db.close();
        // return contact list
        return contactList;

    }

    // Updating single contact
    public int updateContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, contact.getName());
        values.put(KEY_IMAGE, contact.getImage());

        // updating row
        return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
                new String[] { String.valueOf(contact.getID()) });

    }

    // Deleting single contact
    public void deleteContact(Contact contact) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
                new String[] { String.valueOf(contact.getID()) });
        db.close();
    }


    public void deleteAllContact() {
        SQLiteDatabase db = this.getWritableDatabase();

        db.delete(TABLE_CONTACTS,null,null);
        db.close();
    }




    // Getting contacts Count
    public int getContactsCount() {
        String countQuery = "SELECT * FROM " + TABLE_CONTACTS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        cursor.close();

        // return count
        return cursor.getCount();
    }
}

ImagesList.java

public class ImagesList extends Activity{

    ArrayList<Contact> imageArry = new ArrayList<Contact>();
    ContactImageAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_list);
        ListView dataList = (ListView) findViewById(R.id.listView1);


        DataBaseHandler db = new DataBaseHandler(this);

        // Reading all contacts from database
        List<Contact> contacts = db.getAllContacts();

            for (Contact cn : contacts) {
                String log = "ID:" + cn.getID() + " Name: " + cn.getName()  + " ,Image: " + cn.getImage();

                // Writing Contacts to log
                Log.d("Result: ", log);
                //add contacts data in arrayList
                imageArry.add(cn);

            }

        adapter = new ContactImageAdapter(this,R.layout.layout_row,imageArry);
        dataList.setAdapter(adapter);

    }


}

image_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

layout_row.xml 布局列表视图中每行

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp"
        android:paddingBottom="10dp"    
        android:src="@drawable/ic_gallery" />

    <TextView
        android:id="@+id/tvImageName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imageView1"
        android:layout_marginBottom="18dp"
        android:layout_toRightOf="@+id/imageView1"
        android:text="The name of the image"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

我失去了很多时间用于搜索解决方案,但没有找到。

I lost a lot of time for searching solution but didn't find.

感谢上级篇!

完整的日志文件:

11-06 15:16:17.199: E/AndroidRuntime(1789): FATAL EXCEPTION: main
11-06 15:16:17.199: E/AndroidRuntime(1789): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demodbimage/com.example.demodbimage.ImagesList}: java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2351)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2403)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.app.ActivityThread.access$600(ActivityThread.java:165)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.os.Handler.dispatchMessage(Handler.java:107)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.os.Looper.loop(Looper.java:194)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at android.app.ActivityThread.main(ActivityThread.java:5391)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at java.lang.reflect.Method.invokeNative(Native Method)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at java.lang.reflect.Method.invoke(Method.java:525)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
11-06 15:16:17.199: E/AndroidRuntime(1789):     at dalvik.system.NativeStart.main(Native Method)

*

推荐答案

而不是仅仅看在logcat中的错误,看警告。我相信你会看到类似于以下警告:

Instead of just looking at the errors in logcat, look at the warnings. I believe you will see a warning that looks similar to the following:

WARN CursorWindow Window is full: requested allocation x bytes, free space x bytes, window size x bytes

这意味着你的光标对象比分配的大小,通常为2Mb较大。你的光标加载夫妇图像/斑点,这可能会导致它大于2MB增长较大。

This means that your cursor object is larger than the allocated size, which is normally 2Mb. Your cursor is loading a couple of image / blobs, which might cause it to grow larger than 2Mb.

解决方案

Solutions

1 - 读取图像逐个。与其这样做,例如选择一切查询SELECT * FROM接触......改变它通过索引结果读取一次一个或两个图像。你也许可以锻炼你需要多大的空间通过查看图像的大小。

1 - Read the images one by one. Instead of doing a query that selects everything e.g. SELECT * FROM contacts ... change it to read one or two images at a time by indexing the results. You can probably workout how much space you need by looking at the size of your images.

2 - 不要将图像保存在数据库中。这可能是最好的图像保存在SD卡的一个目录,然后只需保存的URI到数据库,并将其读入你的光标。然后离开图像的解码你的应用程序,它有更多的内存比你的光标对象的工作。

2 - Don't save the images in the database. It might be better to save the images in a directory on the SDcard and then just save the URI's into the db and read them into your cursor. then leave the decoding of the images to your application, which has much more memory to work with than your cursor object.

解决方案1的实施


于是,我终于坐下来,写了code和测试,它的伟大工程。因此,这里是解决方案1. code它正常工作对我来说,很明显你的实现可能取决于你如何存储不同和检索数据等,所以在这里不用

Implementation of Solution 1

So I finally sat down and wrote the code and tested and it works great. So here is the code for solution 1. It works fine for me, obviously your implementation might be different depending on how you store and retrieve your data etc. So here goes

我已经把意见和修改了code,使其更容易理解。

I have put in comments and modified the code so that it's easier to understand.

        //This is the part of my Sync method where I start pulling images from the database. 
        if(isSyncNeeded)
        {
            android.util.Log.w("     CURSOR FIXES     ", "BEGIN...");
            databaseHelperimages = new Handler_Database(Screen_Main.this);
            SQLiteDatabase dbimages = databaseHelperimages.getReadableDatabase();

            //I store my data in arraylists when I read the from the db.
            Session.arraylist_pictures_1 = new ArrayList<String>();
            Session.arraylist_pictures_2 = new ArrayList<String>();

            //Do all your reading here...
            // I have another query before this where I get the id of each row in my database. And here, I say, for each id in my database, get the corresponding image in that row.
            for (String id : Session.arraylist_allsubmissions_id)
            {
                Cursor c1 = dbimages.rawQuery("SELECT picture1 FROM submissions WHERE id" + " = " + id, null);
                if(c1.getCount() > 0) 
                {
                    if(c1.moveToFirst())
                    {
                        do
                        {
                            try
                            {
                                int index = c1.getColumnIndex("picture1");
                                String entry = c1.getString(index);
                                Session.arraylist_pictures_1.add(entry);
                            }
                            catch (IllegalStateException e)
                            {
                                //Do Nothing
                            }
                            catch (NullPointerException e)
                            {
                                //Do Nothing
                            }
                        }
                        while(c1.moveToNext());
                    }
                }
                c1.close();

                Cursor c2 = dbimages.rawQuery("SELECT picture2 FROM submissions WHERE id" + " = " + id, null);
                if(c2.getCount() > 0) 
                {
                    if(c2.moveToFirst())
                    {
                        do
                        {
                            try
                            {
                                int index = c2.getColumnIndex("picture2");
                                String entry = c2.getString(index);
                                Session.arraylist_pictures_2.add(entry);
                            }
                            catch (IllegalStateException e)
                            {
                                //Do Nothing
                            }
                            catch (NullPointerException e)
                            {
                                //Do Nothing
                            }
                        }
                        while(c2.moveToNext());
                    }
                }
                c2.close();

                //Continue doing this for all your images.
            }
            databaseHelperimages.close();
            dbimages.close();
            android.util.Log.w("     CURSOR FIXES     ", "END...");
        }

这篇关于错误尝试保存和检索图像到android系统数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆