【问题标题】:Saving image from url using Picasso?使用毕加索从网址保存图像?
【发布时间】:2015-12-24 07:11:48
【问题描述】:

我正在尝试使用 API Picasso 保存图像。为此,我正在尝试使用 Target 进行保存,但我无法完成这项工作。

我该怎么做?

尝试

//save image
    public static void imageDownload(Context ctx){
        Picasso.with(ctx)
                .load("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png")
                .into(getTarget("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png"));
    }

    //target to save
    private static Target getTarget(final String url){
        Target target = new Target(){

            @Override
            public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //Log.i("PRODUTOS_FOLDER", CreateAppFolder.getProdutosFolder());
                        File file = new File(Environment.getExternalStorageDirectory() + url);

                        try {
                            file.createNewFile();
                            FileOutputStream ostream = new FileOutputStream(file);
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
                            ostream.flush();
                            ostream.close();
                        }
                        catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        };
        return target;
    }

例外

java.io.IOException: open failed: ENOENT (No such file or directory)

【问题讨论】:

  • 你的问题到底是什么,回调不起作用,或者你的位图没有保存,或者其他什么?
  • @VasylGlodan 确实抛出异常 java.io.IOException: open failed: ENOENT (No such file or directory)
  • 嗯,我不确定,但你的文件路径应该是这样的/storage/emulated/0/http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png,并且系统试图找到名为/storage/emulated/0/http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/的目录,但是没有这样的目录。尝试从文件名中删除所有特殊字符。
  • @FernandoPaiva 有同样的问题。尝试将您的文件名设置为其他名称,问题是当您想使用您的 url 创建文件名时。尝试使用当前时间或其他东西。

标签: android picasso


【解决方案1】:

解决了。现在工作正常!

我做到了

//save image
    public static void imageDownload(Context ctx, String url){
        Picasso.with(ctx)
                .load("http://blog.concretesolutions.com.br/wp-content/uploads/2015/04/Android1.png")
                .into(getTarget(url));
    }

    //target to save
    private static Target getTarget(final String url){
        Target target = new Target(){

            @Override
            public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {

                        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + url);
                        try {
                            file.createNewFile();
                            FileOutputStream ostream = new FileOutputStream(file);
                            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, ostream);
                            ostream.flush();
                            ostream.close();
                        } catch (IOException e) {
                            Log.e("IOException", e.getLocalizedMessage());
                        }
                    }
                }).start();

            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        };
        return target;
    }

【讨论】:

  • 它给了我错误:打开失败:EACCES(权限被拒绝)。在清单上我已经声明了
  • @AEMLoviji 首先使用Environment.getExternalStorageState == Environment.MEDIA_MOUNTED检查外部存储状态
  • 为什么不散列图像 url 并将其转换为长整数,以生成文件名?
【解决方案2】:

我可以看到 2 个可能的问题:

  1. 尝试在清单中没有写入权限的情况下保存到外部存储
  2. 尝试更改文件名,使其不是整个 url,这可能是您的问题,因为您的 url 中的字符作为文件名字符无效。

【讨论】:

  • 我使用了这个代码。在我的 android 清单上,我将权限标记为:。文件名很简单:“simpleFileName”。现在,当我尝试保存它时,它给了我错误:java.io.IOException:打开失败:EACCES(权限被拒绝)。我该怎么办?
【解决方案3】:

我修改了解决方案,添加了权限和一个按钮来加载和保存图片,PhotoLoader类保持不变!

private static final String[] STORAGE_PERMISSIONS = { Manifest.permission.WRITE_EXTERNAL_STORAGE};
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);

        verifyPermissions();
    }
    public void save(View view)
    {
        Picasso.with(this)
                .load("https://www.w3schools.com/howto/img_fjords.jpg")
                .into(new PhotoLoader("myImg.jpg" , imageView));
    }

    public void verifyPermissions()
    {
        // This will return the current Status
        int permissionExternalMemory = ActivityCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if(permissionExternalMemory != PackageManager.PERMISSION_GRANTED)
        {
            // If permission not granted then ask for permission real time.
            ActivityCompat.requestPermissions(MainActivity.this,STORAGE_PERMISSIONS,1);
        }
    }

【讨论】:

    【解决方案4】:

    我认为您需要检查您是否真的在请求许可。 在 Android 中,权限从 6.0 版开始是动态的。要么您必须在运行时请求它,要么只需将您的 targetSdk 版本降级到 22。

    【讨论】:

      【解决方案5】:

      我的 kotlin 解决方案,将文件存储到内部存储中,无需用户权限:

      因为我必须一次下载多个图像,所以必须创建一个名为 shareTargetsArray 的 MutableList 并用多个目标填充它,否则垃圾收集器会删除它们,除了最后一个一。完成后请记住清理该数组。

          private var shareTargetsArray: MutableList<Target?> = ArrayList()
      
          fun downloadImage(context: Context, url: String?, slug: String) {
      
              val shareTarget = object : Target {
                  override fun onBitmapLoaded(bitmap: Bitmap, from: LoadedFrom?) {
      
                          val contextWrapper = ContextWrapper(context)
                          val directory: File =
                              contextWrapper.getDir("customDirectory", Context.MODE_PRIVATE)
                          val file = File(directory, slug + ".png")
      
                          var outputStream: FileOutputStream? = null
      
                          try {
                              outputStream = FileOutputStream(file)
      
                              bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
                              outputStream.flush()
                          } catch (e: IOException) {
                              e.printStackTrace()
                          } finally {
                              try {
                                  outputStream!!.close()
                              } catch (e: IOException) {
                                  e.printStackTrace()
                              }
                          }
                      }
      
                  override fun onBitmapFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {}
      
                  override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
              }
      
              shareTargetsArray.add(shareTarget)
              Picasso.get().load(url).into(shareTarget)
          }
      }
      

      文件下载到 /data/data/com.***.***/customDirectory/ 您可以使用View &gt; Tool Windows &gt; Device File Explorer查看它们

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-10
        • 1970-01-01
        相关资源
        最近更新 更多