Search code examples
androidandroid-arrayadapterbitmapfactory

BitmapFactory decodeFile FileNotFoundException


I have an app where you can select images from the gallery or Photos folder on the device. The selected file's paths are stored in an Intent so they can be passed around between Activities. I access the paths via intent.getDataString().

Once i have all the selected paths to the images, i store them in an ArrayList and pass that to an ImageAdapter, to display in a ListView.

I'm geting a FileNotFoundException, Has anyone any ideas why?

Thanks in advance

Matt.

import java.util.ArrayList;

import uk.co.mobilewebexpert.infowrapsynclibrary.ApplicationObj;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;

public class QueuedImagesActivity extends Activity {

    private static final String TAG = QueuedImagesActivity.class.getSimpleName();
    private ImageAdapter adapter;
    private ListView imageList;
    ApplicationObj appObj;
    Intent[] photos;
    String path;

    private ArrayList<String> imagePaths= new ArrayList<String>(); // Edit your code here..

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_listview);

        appObj = (ApplicationObj) getApplication();

        boolean includeBeingProcessed = true;

        try {
             photos = appObj.getQueuedPhotos(includeBeingProcessed);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        for(int i = 0; i < photos.length; i++){

            path = photos[i].getDataString();
            imagePaths.add(path);

            Log.e(TAG, "path in QueuedImagesActivity = " + path);

        }




        imageList= (ListView) findViewById(R.id.listView1);
        adapter= new ImageAdapter(getBaseContext(), imagePaths);
        imageList.setAdapter(adapter);      
    }
}

.

import java.util.ArrayList;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {

    private static final String TAG = ImageAdapter.class.getSimpleName();

    static class RowItemHolder{
        ImageView imageView;
    }
    private Context context;
    private ArrayList<String> imagePaths= new ArrayList<String>();

    public ImageAdapter(Context baseContext, ArrayList<String> imagePaths) {
    // TODO Auto-generated constructor stub
        this.context= baseContext;
        this.imagePaths= imagePaths;
    }

    @Override
    public int getCount() {
    // TODO Auto-generated method stub
        return imagePaths.size();
    }

    @Override
    public Object getItem(int position) {
    // TODO Auto-generated method stub
            return null;
    }

    @Override
    public long getItemId(int position) {
    // TODO Auto-generated method stub
            return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    View view;
    view= convertView;
    RowItemHolder holder = null;
    if(view== null){
            LayoutInflater in =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = in.inflate(R.layout.image_view, parent, false);
            holder= new RowItemHolder();
            holder.imageView=(ImageView) view.findViewById(R.id.imageView1);
        view.setTag(holder);
    } else{
            holder = (RowItemHolder) view.getTag();
    }
    //Edit the code here according to you needs.. 
    //like creating option and converting to Bitmap, 
    //or you can do this job in the main activity.
    //holder.imageView.setImageResource(imagePaths.get(position));

    Log.e(TAG, "imagePaths.get(position) = " + imagePaths.get(position));


    holder.imageView.setImageBitmap(BitmapFactory.decodeFile(imagePaths.get(position)));

    return view;
}
}

.

07-02 07:51:33.941: E/QueuedImagesActivity(22700): path in QueuedImagesActivity = content://media/external/images/media/7496
07-02 07:51:33.951: E/ImageAdapter(22700): imagePaths.get(position) = content://media/external/images/media/7496
07-02 07:51:33.961: E/BitmapFactory(22700): Unable to decode stream: FileNotFoundException
07-02 07:51:33.971: E/ImageAdapter(22700): imagePaths.get(position) = content://media/external/images/media/7496
07-02 07:51:33.971: E/BitmapFactory(22700): Unable to decode stream: FileNotFoundException
07-02 07:51:33.981: E/ImageAdapter(22700): imagePaths.get(position) = content://media/external/images/media/7496
07-02 07:51:33.981: E/BitmapFactory(22700): Unable to decode stream: FileNotFoundException
07-02 07:51:33.991: E/ImageAdapter(22700): imagePaths.get(position) = content://media/external/images/media/7496
07-02 07:51:33.991: E/BitmapFactory(22700): Unable to decode stream: FileNotFoundException

Solution

  • The path you are getting is not real path of the Image it is a Uri.If you want to set it it ImageView set it like

    imageView.setImageURI(Uri.parse(imagePaths.get(position)));
    

    or

    get the Real path by passing your URI and set it to ImageView

    private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        result = contentURI.getPath();
    } else { 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
    }
    

    For more check here Uri to path conversion