使用Universal Image Downloader将图像保存到外部公共存储?

时间:2014-06-21 13:11:37

标签: android exception-handling try-catch universal-image-loader fileoutputstream

我正在尝试使用Universal Image Loader将图像保存到外部SD卡。我正在关注来自作者nostra的这个极其过时的代码片段:

Download Image stream from android universal image loader

我有兴趣成功地重新创建它,但是当我尝试时,我得到了

此错误:

    06-21 07:56:22.586  17647-17647/as;dlkfa E/libEGL﹕ call to OpenGL ES API with no current context (logged once per thread)
06-21 07:56:27.562  17647-17647/;alsdjf E/ViewRootImpl﹕ sendUserActionEvent() mView == null
06-21 07:56:30.965  17647-17647/;aldjf; E/ViewRootImpl﹕ sendUserActionEvent() mView == null
06-21 07:56:32.737  17647-17647/a;sdjfl E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at com.nostra13.universalimageloader.utils.IoUtils.copyStream(IoUtils.java:73)
            at com.nostra13.universalimageloader.utils.IoUtils.copyStream(IoUtils.java:50)
            at ;a;ldsfkj.MediaDisplayActivity.saveToGallery(MediaDisplayActivity.java:344)
            at as;dlkfj.MediaDisplayActivity.onMenuItemClick(MediaDisplayActivity.java:298)
            at android.widget.PopupMenu.onMenuItemSelected(PopupMenu.java:142)
            at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
            at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
            at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
            at com.android.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:175)
            at android.widget.AdapterView.performItemClick(AdapterView.java:301)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1507)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3336)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5455)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
            at dalvik.system.NativeStart.main(Native Method)

我已将原始代码更改为此。它在菜单项上单击调用:

    private void saveToGallery()
{
    String imageUrl = imageUrls.get(pager.getCurrentItem());

    File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File fileForImage = new File(path, imageUrl);

    InputStream sourceStream = null;
    File cachedImage = ImageLoader.getInstance().getDiskCache().get(imageUrl);
    if (cachedImage.exists()) { // if image was cached by UIL
        try {
            sourceStream = new FileInputStream(cachedImage);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    } else { // otherwise - download image
        ImageDownloader downloader = new BaseImageDownloader(this);
        try {
            sourceStream = downloader.getStream(imageUrl, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // TODO : use try-finally to close streams
    OutputStream targetStream = null;
    try {
        targetStream = new FileOutputStream(fileForImage);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    try {
        IoUtils.copyStream(sourceStream, targetStream, null);
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        targetStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        sourceStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

第344行是:

IoUtils.copyStream(sourceStream, targetStream, null);

阅读修复评论。基本上,我使用的是像https **这样的坏字符:**

此外,这是我的新代码,它可以工作,但它仍然不会为您的应用创建相册,如果您希望用户快速浏览自己的相册,这是非常理想的。我将继续在评论中寻求编码之神的帮助。此外,它在保存相同图像时仍无法处理。

    //TODO upon uninstall ensure the files are still there
    //TODO make sure this janky stuff don't crash if you save the same stuff twice
    private boolean saveToGallery() {
        String imageUrl = imageUrls.get(pager.getCurrentItem());

        int i = imageUrl.length()-1;
        while(imageUrl.charAt(i) != '/')
        {
            i--;
        }
        String newImageUrl = imageUrl.substring(i+1);
        File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

        File fileForImage = new File(path, newImageUrl);
//        if (!fileForImage.mkdirs()) {
//            Log.e("shit", "Directory not created");
//        }

        boolean saved = false;

        InputStream sourceStream = null;
        File cachedImage = ImageLoader.getInstance().getDiskCache().get(imageUrl);
        try {
            if (cachedImage != null && cachedImage.exists()) { // if image was cached by UIL
                sourceStream = new FileInputStream(cachedImage);
            } else { // otherwise - download image
                ImageDownloader downloader = new BaseImageDownloader(this);
                sourceStream = downloader.getStream(imageUrl, null);
            }
        } catch (IOException e) {
            L.e(e);
        }

        if (sourceStream != null) {
            try {
                System.out.println(fileForImage.getAbsolutePath());
                OutputStream targetStream = new FileOutputStream(fileForImage);
                IoUtils.copyStream(sourceStream, targetStream, null);
                targetStream.close();
                sourceStream.close();
                saved = true;
            } catch (IOException e) {
                L.e(e);
            }
        }

        //Updates the gallery, dunno how though lol, yay SO
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
        return saved;

    }

大家好,我所要做的就是在追加url文件之前移动mkdirs()调用。我现在太累了,不知道事情的顺序,但肯定是因为这个。这是新代码。如果你使用通用图片加载器和文件名的URL的一部分,这将把图像保存到你的应用程序中的相册,否则,没有汤给你:

//TODO upon uninstall ensure the files are still there
//TODO make sure this janky stuff don't crash if you save the same stuff twice
private boolean saveToGallery() {
    String imageUrl = imageUrls.get(pager.getCurrentItem());

    int i = imageUrl.length()-1;
    while(imageUrl.charAt(i) != '/')
    {
        i--;
    }
    String newImageUrl = imageUrl.substring(i+1);
    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/Your app name here");

    if (!path.mkdirs()) {
        Log.e("shit", "Directory not created");
    }
    File fileForImage = new File(path, newImageUrl);


    boolean saved = false;

    InputStream sourceStream = null;
    File cachedImage = ImageLoader.getInstance().getDiskCache().get(imageUrl);
    try {
        if (cachedImage != null && cachedImage.exists()) { // if image was cached by UIL
            sourceStream = new FileInputStream(cachedImage);
        } else { // otherwise - download image
            ImageDownloader downloader = new BaseImageDownloader(this);
            sourceStream = downloader.getStream(imageUrl, null);
        }
    } catch (IOException e) {
        L.e(e);
    }

    if (sourceStream != null) {
        try {
            System.out.println(fileForImage.getAbsolutePath());
            OutputStream targetStream = new FileOutputStream(fileForImage);
            IoUtils.copyStream(sourceStream, targetStream, null);
            targetStream.close();
            sourceStream.close();
            saved = true;
        } catch (IOException e) {
            L.e(e);
        }
    }

    //Updates the gallery, dunno how though lol, yay SO
    sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
    return saved;

}

2 个答案:

答案 0 :(得分:2)

我重构了您的方法,如果保存到图库失败则返回false

private boolean saveToGallery() {
    String imageUrl = imageUrls.get(pager.getCurrentItem());
    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File fileForImage = new File(path, imageUrl);

    boolean saved = false;

    InputStream sourceStream = null;
    File cachedImage = ImageLoader.getInstance().getDiskCache().get(imageUrl);
    try {
        if (cachedImage != null && cachedImage.exists()) { // if image was cached by UIL
            sourceStream = new FileInputStream(cachedImage);
        } else { // otherwise - download image
            ImageDownloader downloader = new BaseImageDownloader(this);
            sourceStream = downloader.getStream(imageUrl, null);
        }
    } catch (IOException e) {
        L.e(e);
    }

    if (sourceStream != null) {
        try {
            OutputStream targetStream = new FileOutputStream(fileForImage);
            try {   
                IoUtils.copyStream(sourceStream, targetStream, null);
                saved = true;
            } catch (IOException e) {
                L.e(e);
            } finally {
                targetStream.close();
            }
        } catch (IOException e) {
            L.e(e);
        } finally {
            sourceStream.close();
        }
    }

    return saved;
}

答案 1 :(得分:1)

用户####很高兴为您提供帮助。如果所有的OP都是健谈的并且通知!