bad bitmap error when setting Uri

后端 未结 6 1837
暗喜
暗喜 2021-02-19 12:00

I would like to make an ImageView display an image on a website. So I create a new ImageView and execute imgView.setImageURI(uri);

When I launch the app the

6条回答
  •  無奈伤痛
    2021-02-19 12:38

    I've wrote a simple AsyncTask, which converts remote HTTPS to local Uri by caching to SD card:

    public class ProfileImageTask extends AsyncTask {
    
        private boolean enforce = false;
        private IProfileImageTask listener;
        private String fileName = "photo.jpg";
        private String sdPath;
        private String url;
    
        /** Constructor */
        @RequiresPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        public ProfileImageTask(@NonNull Context context, @NonNull String url, @NonNull IProfileImageTask listener) {
            this.sdPath = Environment.getExternalStorageDirectory() + "/" + context.getResources().getString(R.string.app_name) + "/";
            this.listener = listener;
            this.url = url;
        }
    
        @Override
        protected void onPreExecute() {
    
            /* setup destination directory */
            File directory = new File(this.sdPath + "temp");
            if (! directory.exists()) {directory.mkdirs();}
    
            /* setup file name */
            String[] parts = this.url.split("/");
            this.fileName = parts[parts.length - 1];
        }
    
        @Override
        protected Uri doInBackground(String... arguments) {
            File file = new File(this.sdPath + "temp", this.fileName);
            if(file.exists() && this.enforce) {file.delete();}
            if (! file.exists()) {
                try {
                    URLConnection conn = new URL(this.url).openConnection();
                    conn.connect();
                    InputStream in = conn.getInputStream();
                    FileOutputStream out = new FileOutputStream(file);
                    byte[] b = new byte[1024]; int c;
                    while ((c = in.read(b)) != -1) {out.write(b, 0, c);}
                    out.close();
                    in.close();
                } catch (IOException e) {
                    Log.e("ProfileImageTask", e.getMessage());
                }
            }    
            return Uri.fromFile(file);
        }
    
        @Override
        protected void onPostExecute(Uri uri) {
            if (listener != null && uri != null) {
                this.listener.OnImageAvailable(uri);
            }
        }
    }
    

    The interface:

    public interface IProfileImageTask {
        void OnImageAvailable(@NonNull Uri uri);    
    }
    

    And the implementation:

    @Override
    public void OnImageAvailable(@NonNull Uri uri) {
        this.photoUrl.setImageURI(uri);
    }
    

    Tested with url alike https://lh3.googleusercontent.com/.../photo.jpg (which has about 179kb). One could still downscale larger images, render a set of thumbnails or pass the intended size.

提交回复
热议问题