turtleboy
turtleboy

Reputation: 7574

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

Upvotes: 1

Views: 4783

Answers (6)

Rohit Goyal
Rohit Goyal

Reputation: 550

Check for the inputstream, you are passing just a URI.

BitmapFactory.decodeFile(imagePaths.get(position));

Hence the file is not found, get the absolute path of the Image and pass it over.

Upvotes: 0

Hareshkumar Chhelana
Hareshkumar Chhelana

Reputation: 24848

Try this way,hope this will help you to solve your problem.

  public String getAbsolutePath(Uri uri) {
        if(Build.VERSION.SDK_INT >= 19){
            String id = uri.getLastPathSegment().split(":")[1];
            final String[] imageColumns = {MediaStore.Images.Media.DATA };
            final String imageOrderBy = null;
            Uri tempUri = getUri();
            Cursor imageCursor = getContentResolver().query(tempUri, imageColumns,
                    MediaStore.Images.Media._ID + "="+id, null, imageOrderBy);
            if (imageCursor.moveToFirst()) {
                return imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }else{
                return null;
            }
        }else{
            String[] projection = { MediaColumns.DATA };
            Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
                cursor.moveToFirst();
                return cursor.getString(column_index);
            } else
                return null;
        }

    }

Upvotes: 1

Roman Black
Roman Black

Reputation: 3497

It causes because intent.getDataString() returns the uri string. Use intent.getData().getPath() instead.

Upvotes: 2

Shivam Verma
Shivam Verma

Reputation: 8023

content://media/external/images/media/7496 is not the actual location of the stored file, but just the Uri, hence android can't find the file on the specified path. However, you can use the URI to get the absolute path of the file and use that path when decoding.

Use this method to the get the absolute path :

public String getRealPathFromURI(Context context, Uri contentUri) {
  Cursor cursor = null;
  try { 
    String[] proj = { MediaStore.Images.Media.DATA };
    cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
}

From : https://stackoverflow.com/a/3414749/1239966

Upvotes: 0

kalyan pvs
kalyan pvs

Reputation: 14590

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

Upvotes: 6

Gabe Sechan
Gabe Sechan

Reputation: 93678

Your problem is in appObj.getQueuedPhotos- it isn't returning filenames, its returning URIs, decodeFile expects a path. You can, for this case, do a quick string manipulation and remove the content:/ from the front, but you're better off fixing the URIs in your getQueuedPhotos function

Upvotes: 0

Related Questions