Reputation: 7574
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
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
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
Reputation: 3497
It causes because intent.getDataString()
returns the uri string. Use intent.getData().getPath()
instead.
Upvotes: 2
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
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
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