Fresco: java.io.FileNotFoundException

Created on 19 Dec 2016  Â·  11Comments  Â·  Source: facebook/fresco

since switching from v0.14.1 to v1.0.0 fresco will not load images from local storage.

AbstractDraweeController: controller a65fcb9 null -> 125: initialize AbstractDraweeController: controller a65fcb9 125: setHierarchy: com.facebook.drawee.generic.GenericDraweeHierarchy@8328fe AbstractDraweeController: controller a65fcb9 125: onAttach: request needs submit PipelineDraweeController: controller a65fcb9: getDataSource AbstractDraweeController: controller a65fcb9 125: submitRequest: dataSource: ca085f AbstractDraweeController: controller 230cb7b null -> 126: initialize AbstractDraweeController: controller 230cb7b 126: setHierarchy: com.facebook.drawee.generic.GenericDraweeHierarchy@8e84d98 AbstractDraweeController: controller 230cb7b 126: onAttach: request needs submit PipelineDraweeController: controller 230cb7b: getDataSource AbstractDraweeController: controller 230cb7b 126: submitRequest: dataSource: e1d89f1 AbstractDraweeController: controller a65fcb9 125: final_failed @ onFailure: failure: java.io.FileNotFoundException: torage/emulated/0/Images/1482147242789-1165.jpg (No such file or directory) AbstractDraweeController: controller 230cb7b 126: final_failed @ onFailure: failure: java.io.FileNotFoundException: torage/emulated/0/Images/1481641781949-2816.jpg (No such file or directory) AbstractDraweeController: controller 240eaeb 103: onDetach AbstractDraweeController: controller 16f66d9 104: onDetach AbstractDraweeController: controller 33fba98 105: onDetach AbstractDraweeController: controller 240eaeb 103: release: image: CloseableReference ac1e844 AbstractDraweeController: controller 16f66d9 104: release: image: CloseableReference d89775a

you can see that first part of image path (file:/s) is missing in log

Most helpful comment

@lambdapioneer I have solved the issue, problem is that following code doesn't work when you try to load image from folder with empty space in name

Uri uri = new Uri.Builder()
                            .scheme(UriUtil.LOCAL_FILE_SCHEME)
                            .path(imagePath)
                            .build();

instead of that use this

Uri uri = Uri.parse("file://" + imagePath);

also i have tested it in fresco sample app (zoomableapp) and issue is persist there, here is the code i changed in test app

```/*

  • This file provided by Facebook is for non-commercial testing and evaluation
  • purposes only. Facebook reserves all rights not expressly granted.
    *
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  • FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  • ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  • CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */

package com.facebook.samples.zoomableapp;

import android.net.Uri;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.facebook.common.util.UriUtil;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.samples.zoomable.DoubleTapGestureListener;
import com.facebook.samples.zoomable.ZoomableDraweeView;

class MyPagerAdapter extends PagerAdapter {

private static final String[] SAMPLE_URIS = {
        "/storage/emulated/0/test images/99.jpg",
        "/storage/emulated/0/test images/98.jpg",
        "/storage/emulated/0/test images/97.jpg",
        "/storage/emulated/0/test images/96.jpg",
        "/storage/emulated/0/test images/95.jpg",
        "/storage/emulated/0/test images/94.jpg",
        "/storage/emulated/0/test images/93.jpg",
        "/storage/emulated/0/test images/92.jpg"
};

private final int mItemCount;
private boolean mAllowSwipingWhileZoomed = true;

public MyPagerAdapter(int itemCount) {
    mItemCount = itemCount;
}

public void setAllowSwipingWhileZoomed(boolean allowSwipingWhileZoomed) {
    mAllowSwipingWhileZoomed = allowSwipingWhileZoomed;
}

public boolean allowsSwipingWhileZoomed() {
    return mAllowSwipingWhileZoomed;
}

public void toggleAllowSwipingWhileZoomed() {
    mAllowSwipingWhileZoomed = !mAllowSwipingWhileZoomed;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    FrameLayout page = (FrameLayout) container.getChildAt(position);
    if (page == null) {
        return null;
    }
    ZoomableDraweeView zoomableDraweeView =
            (ZoomableDraweeView) page.findViewById(R.id.zoomableView);
    zoomableDraweeView.setAllowTouchInterceptionWhileZoomed(mAllowSwipingWhileZoomed);
    // needed for double tap to zoom
    zoomableDraweeView.setIsLongpressEnabled(false);
    zoomableDraweeView.setTapListener(new DoubleTapGestureListener(zoomableDraweeView));

    // this doesn't work
    /*Uri uri = new Uri.Builder()
            .scheme(UriUtil.LOCAL_FILE_SCHEME)
            .path(SAMPLE_URIS[position % SAMPLE_URIS.length])
            .build();*/

    //this works
    Uri uri = Uri.parse("file://" + SAMPLE_URIS[position % SAMPLE_URIS.length]);

    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setUri(uri)
            .build();
    zoomableDraweeView.setController(controller);
    page.requestLayout();
    return page;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    FrameLayout page = (FrameLayout) container.getChildAt(position);
    ZoomableDraweeView zoomableDraweeView = (ZoomableDraweeView) page.getChildAt(0);
    zoomableDraweeView.setController(null);
}

@Override
public int getCount() {
    return mItemCount;
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == arg1;
}

@Override
public int getItemPosition(Object object) {
    // We want to create a new view when we call notifyDataSetChanged() to have the correct behavior
    return POSITION_NONE;
}

}
```

All 11 comments

Hi @prgomet, the correct start of file uris should be: file:///storage/emulated/0/. If this is already the case for you, can you post a minimal code example that reproduces the issue? I verified that local file URIs still work fine using the sample apps.

Hi @lambdapioneer, image uri is correct. I get image uris from ContentResolver, also images from "/storage/emulated/0/DCIM/Camera/" are displayed correctly, for other images i get java.io.FileNotFoundException.

It's tested on few phones from android 4.4 to 7.1.1, same problem on all of them.

Edit: I think i have found problem, if folder name has empty space in name like "test images" fresco will not load images and i get java.io.FileNotFoundException.

<com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/img_thumb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        fresco:actualImageScaleType="fitCenter"
        fresco:placeholderImage="@drawable/photo_thumb"
        fresco:placeholderImageScaleType="center" />

Uri uri;
File localImage = new File(image.local);
if (localImage.exists()) {
    uri = new Uri.Builder()
            .scheme(UriUtil.LOCAL_FILE_SCHEME)
            .path(image.local)
            .build();
} else {
    uri = Uri.parse(image.thumb);
}
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
        .setResizeOptions(new ResizeOptions(size, size))
        .build();
holder.thumb.setController(Fresco.newDraweeControllerBuilder()
        .setOldController(holder.thumb.getController())
        .setImageRequest(request)
        .build());

Hi @lambdapioneer , any thoughts on this issue?

Hi @prgomet, the normal Uri builder will encode spaces with %20. You can either use a ContentResolver to get the correct URIs in the first place or use the following:

uri = Uri.parse("file://" + yourFile.getAbsolutePath());

@lambdapioneer , yes i know that and i have tried everything but i still get java.io.FileNotFoundException when i try to load image from folder with empty space in name...

I didn't have this problem in v0.14.1.

final_failed @ onFailure: failure: java.io.FileNotFoundException: /storage/emulated/0/My%20Images/1482147242789-1165.jpg (No such file or directory)

@lambdapioneer I have solved the issue, problem is that following code doesn't work when you try to load image from folder with empty space in name

Uri uri = new Uri.Builder()
                            .scheme(UriUtil.LOCAL_FILE_SCHEME)
                            .path(imagePath)
                            .build();

instead of that use this

Uri uri = Uri.parse("file://" + imagePath);

also i have tested it in fresco sample app (zoomableapp) and issue is persist there, here is the code i changed in test app

```/*

  • This file provided by Facebook is for non-commercial testing and evaluation
  • purposes only. Facebook reserves all rights not expressly granted.
    *
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  • FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  • ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  • CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */

package com.facebook.samples.zoomableapp;

import android.net.Uri;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.facebook.common.util.UriUtil;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.samples.zoomable.DoubleTapGestureListener;
import com.facebook.samples.zoomable.ZoomableDraweeView;

class MyPagerAdapter extends PagerAdapter {

private static final String[] SAMPLE_URIS = {
        "/storage/emulated/0/test images/99.jpg",
        "/storage/emulated/0/test images/98.jpg",
        "/storage/emulated/0/test images/97.jpg",
        "/storage/emulated/0/test images/96.jpg",
        "/storage/emulated/0/test images/95.jpg",
        "/storage/emulated/0/test images/94.jpg",
        "/storage/emulated/0/test images/93.jpg",
        "/storage/emulated/0/test images/92.jpg"
};

private final int mItemCount;
private boolean mAllowSwipingWhileZoomed = true;

public MyPagerAdapter(int itemCount) {
    mItemCount = itemCount;
}

public void setAllowSwipingWhileZoomed(boolean allowSwipingWhileZoomed) {
    mAllowSwipingWhileZoomed = allowSwipingWhileZoomed;
}

public boolean allowsSwipingWhileZoomed() {
    return mAllowSwipingWhileZoomed;
}

public void toggleAllowSwipingWhileZoomed() {
    mAllowSwipingWhileZoomed = !mAllowSwipingWhileZoomed;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    FrameLayout page = (FrameLayout) container.getChildAt(position);
    if (page == null) {
        return null;
    }
    ZoomableDraweeView zoomableDraweeView =
            (ZoomableDraweeView) page.findViewById(R.id.zoomableView);
    zoomableDraweeView.setAllowTouchInterceptionWhileZoomed(mAllowSwipingWhileZoomed);
    // needed for double tap to zoom
    zoomableDraweeView.setIsLongpressEnabled(false);
    zoomableDraweeView.setTapListener(new DoubleTapGestureListener(zoomableDraweeView));

    // this doesn't work
    /*Uri uri = new Uri.Builder()
            .scheme(UriUtil.LOCAL_FILE_SCHEME)
            .path(SAMPLE_URIS[position % SAMPLE_URIS.length])
            .build();*/

    //this works
    Uri uri = Uri.parse("file://" + SAMPLE_URIS[position % SAMPLE_URIS.length]);

    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setUri(uri)
            .build();
    zoomableDraweeView.setController(controller);
    page.requestLayout();
    return page;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    FrameLayout page = (FrameLayout) container.getChildAt(position);
    ZoomableDraweeView zoomableDraweeView = (ZoomableDraweeView) page.getChildAt(0);
    zoomableDraweeView.setController(null);
}

@Override
public int getCount() {
    return mItemCount;
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == arg1;
}

@Override
public int getItemPosition(Object object) {
    // We want to create a new view when we call notifyDataSetChanged() to have the correct behavior
    return POSITION_NONE;
}

}
```

Glad to hear that this works now for you. I see that it is confusing which way the URI should be created. I've created https://github.com/facebook/fresco/issues/1596 in order to tackle this issue (especially since this is a nice task for first-time contributors).

I'll close here then :)

I have same problem with this, when file path contain Chinese character

// 0.14.1 ImageRequest
  public synchronized File getSourceFile() {
    if (mSourceFile == null) {
      mSourceFile = new File(mSourceUri.getPath());
    }
    return mSourceFile;
  }
// 1.0.0 ImageRequest
  public synchronized File getSourceFile() {
    if (mSourceFile == null) {
      String filepath = mSourceUri.toString();
      filepath = filepath.substring("file://".length());
      mSourceFile = new File(filepath);
    }
    return mSourceFile;
  }

Fresco 1.0.0
X Uri uri = Uri.fromFile("/storage/哈哈/123.jpg");
√ Uri uri = Uri.parse("file://" + "/storage/哈哈/123.jpg");

yeah, @succlz123 is right.

Hi I get
java.io.FileNotFoundException (permission denied) for following code

AndroidNetworking.upload(DATA_UPLOAD_URL)
.addMultipartFile("image",imageFile)
.addMultipartParameter("teacher_name",s.getName())
.addMultipartParameter("teacher_description",s.getDescription())
.addMultipartParameter("name","upload")
.setTag("MYSQL_UPLOAD")
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
@Override
public void onResponse(JSONObject response) {
if(response != null) {
try{
//SHOW RESPONSE FROM SERVER
String responseString = response.get("message").toString();
Toast.makeText(getActivity(), "PHP SERVER RESPONSE : " + responseString, Toast.LENGTH_LONG).show();

                                    if (responseString.equalsIgnoreCase("Success")) {
                                        //RESET VIEWS
                                        EditText nameEditText = (EditText) inputViews[0];
                                        EditText descriptionEditText = (EditText) inputViews[1];
                                        ImageView teacherImageView = (ImageView) inputViews[2];

                                        nameEditText.setText("");
                                        descriptionEditText.setText("");
                                        teacherImageView.setImageResource(R.drawable.ic_launcher_background);

                                    } else {
                                        Toast.makeText(getActivity(), "PHP WASN'T SUCCESSFUL. ", Toast.LENGTH_LONG).show();
                                    }
                                }catch(Exception e)
                                {
                                    e.printStackTrace();
                                    Toast.makeText(getActivity(), "JSONException "+e.getMessage(), Toast.LENGTH_LONG).show();
                                }
                            }else{
                                Toast.makeText(getActivity(), "NULL RESPONSE. ", Toast.LENGTH_LONG).show();
                            }
                            uploadProgressBar.setVisibility(View.GONE);
                        }
                        @Override
                        public void onError(ANError error) {
                            error.printStackTrace();
                            uploadProgressBar.setVisibility(View.GONE);
                            Toast.makeText(getActivity(), "UNSUCCESSFUL :  ERROR IS : \n"+error.getMessage(), Toast.LENGTH_LONG).show();
                        }
                    });
        }
    }
} //uploader class ends here
Was this page helpful?
0 / 5 - 0 ratings