androidlistviewlocal-storageandroid-viewbinder

Android Dev: Inserting a local image file into a ListView referenced from a SQLite database via a ViewBinder


So I have an application that users can take a picture and store it locally. The image name is stored in my SQLite database for future reference to call the photo. Right now I've traced the problem to setting the bitmap image to the imageview. Here's my code:

    private void displayListView() {
    // TODO Auto-generated method stub

    Cursor cursor = info.getListData();
    String[] listViewColumns = new String[] { Database.KEY_BREWNAME, Database.KEY_BREWERY, Database.KEY_RATING,
            Database.KEY_DATEIMAGENAME, };
    int[] dataToListView = new int[] { R.id.tvBrewName, R.id.tvBrewery, R.id.tvRating, R.id.ivThumb, };

    dataAdapter = new SimpleCursorAdapter(this, R.layout.entrymain, cursor, listViewColumns, dataToListView, 0);

    ViewBinder viewBinder = new ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            ImageView image = (ImageView)view;
            Log.w(TAG, "******************List Image loaded == " + columnIndex + " **********************");
            try {
                FileInputStream fis = openFileInput(cursor.getString(columnIndex));
                fis.close();
                Log.w(TAG, "******************List Image loaded == fis.close **********************");
                image.setImageBitmap(BitmapFactory.decodeStream(fis));
                Log.w(TAG, "******************List Image loaded == setimage success **********************");

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;

        };
    };
    ImageView image = (ImageView)findViewById(R.id.ivThumb);
    viewBinder.setViewValue(image, cursor, cursor.getColumnIndex("date_image_name"));
    dataAdapter.setViewBinder(viewBinder);

    listview.setAdapter(dataAdapter);

The code works just fine with out the ViewBinder and by using log.w's I traced the problem to the image.setImageBitmap(BitmapFactory.decodeStream(fis)) and I don't quite understand why it won't set the image as I've used this code else where with great success. Any ideas on why it won't set, I see that it's something to do with java.io.IOException: read failed: EBADF (Bad file number) however how do I remedy this? Thank in advance!

Here's a segment of my error log:

 03-18 10:44:16.281: D/ActivityThread(19380): setTargetHeapUtilization:0.25
03-18 10:44:16.281: D/ActivityThread(19380): setTargetHeapIdealFree:8388608
03-18 10:44:16.281: D/ActivityThread(19380): setTargetHeapConcurrentStart:2097152
03-18 10:44:16.782: I/Adreno200-EGLSUB(19380): <ConfigWindowMatch:2087>: Format RGBA_8888.
03-18 10:44:16.792: E/(19380): <s3dReadConfigFile:75>: Can't open file for reading
03-18 10:44:16.792: E/(19380): <s3dReadConfigFile:75>: Can't open file for reading
03-18 10:44:17.112: D/AbsListView(19380): Get MotionRecognitionManager
03-18 10:44:17.152: W/Start(19380): ******************List Image loaded == 4 **********************
03-18 10:44:17.162: W/Start(19380): ******************List Image loaded == fis.close **********************
03-18 10:44:17.162: W/System.err(19380): java.io.IOException: read failed: EBADF (Bad file number)
03-18 10:44:17.172: W/System.err(19380):    at libcore.io.IoBridge.read(IoBridge.java:442)
03-18 10:44:17.172: W/System.err(19380):    at java.io.FileInputStream.read(FileInputStream.java:179)
03-18 10:44:17.172: W/System.err(19380):    at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:168)
03-18 10:44:17.172: W/System.err(19380):    at java.io.BufferedInputStream.read(BufferedInputStream.java:309)
03-18 10:44:17.172: W/System.err(19380):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
03-18 10:44:17.172: W/System.err(19380):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:619)
03-18 10:44:17.172: W/System.err(19380):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:691)
03-18 10:44:17.172: W/System.err(19380):    at com.ex.beerlog.Start$1.setViewValue(Start.java:78)
03-18 10:44:17.172: W/System.err(19380):    at com.ex.beerlog.Start.displayListView(Start.java:91)
03-18 10:44:17.172: W/System.err(19380):    at com.ex.beerlog.Start.onCreate(Start.java:56)
03-18 10:44:17.172: W/System.err(19380):    at android.app.Activity.performCreate(Activity.java:5048)
03-18 10:44:17.172: W/System.err(19380):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
03-18 10:44:17.172: W/System.err(19380):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2052)
03-18 10:44:17.172: W/System.err(19380):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2113)
03-18 10:44:17.182: W/System.err(19380):    at android.app.ActivityThread.access$700(ActivityThread.java:139)
03-18 10:44:17.182: W/System.err(19380):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1224)
03-18 10:44:17.182: W/System.err(19380):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-18 10:44:17.182: W/System.err(19380):    at android.os.Looper.loop(Looper.java:137)
03-18 10:44:17.182: W/System.err(19380):    at android.app.ActivityThread.main(ActivityThread.java:4918)
03-18 10:44:17.182: W/System.err(19380):    at java.lang.reflect.Method.invokeNative(Native Method)
03-18 10:44:17.182: W/System.err(19380):    at java.lang.reflect.Method.invoke(Method.java:511)
03-18 10:44:17.182: W/System.err(19380):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
03-18 10:44:17.182: W/System.err(19380):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
03-18 10:44:17.182: W/System.err(19380):    at dalvik.system.NativeStart.main(Native Method)
03-18 10:44:17.182: W/System.err(19380): Caused by: libcore.io.ErrnoException: read failed: EBADF (Bad file number)
03-18 10:44:17.182: W/System.err(19380):    at libcore.io.Posix.readBytes(Native Method)
03-18 10:44:17.182: W/System.err(19380):    at libcore.io.Posix.read(Posix.java:118)
03-18 10:44:17.182: W/System.err(19380):    at libcore.io.BlockGuardOs.read(BlockGuardOs.java:149)
03-18 10:44:17.182: W/System.err(19380):    at libcore.io.IoBridge.read(IoBridge.java:432)
03-18 10:44:17.182: W/System.err(19380):    ... 23 more

Solution

  • You are trying to decode a bitmap from a closed InputStream. fis.close(); must be called after image.setImageBitmap(BitmapFactory.decodeStream(fis));

    Also, you have to check in the setViewValue method if you are really setting the value to the ImageView:

    ViewBinder viewBinder = new ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            if (!(view instanceof ImageView) || view.getId() != R.id.ivThumb) {
                return false;
            }
    
            // the rest of the code
        };
    };
    

    And the last thing. You don't need to explicitly call viewBinder.setViewValue(image, cursor, cursor.getColumnIndex("date_image_name")); because SimpleAdapter will do it for you. Just remove this line and everything should work fine.