Плохая ошибка растрового изображения при настройке Uri

Я хотел бы сделать ImageView отображением изображения на веб-сайте. Поэтому я создаю новый ImageView и выполняю imgView.setImageURI(uri);

Когда я запускаю приложение, изображение не появляется, и я получаю сообщение об ошибке: "resolveUri не удалось сбой Bitmap Uri (uri)".

Любые идеи о том, как это решить?

Ответ 2

Если это не URI содержимого, эта ссылка может помочь. Кажется, это означает, что imgView.setImageURI() не следует использовать для регулярных URI. Копирование в соответствующем бите:

Да, ImageView.setImageURI(ContentURI uri) работает, но он предназначен для URI содержимого, особенно для платформы Android, а не для URI, определяющих интернет-ресурсы. Соглашение применяется к двоичным объектам (например, изображениям), которые не могут быть представлены непосредственно через методы ContentProvider Cursor. Вместо этого ссылка String используется для ссылки на отдельный URI контента, который может быть разрешен отдельным запросом против поставщика контента. Метод setImageURI - это просто оболочка для выполнения этих шагов для вас.

Я тестировал это использование setImageView, и он работает так, как ожидалось. Однако для вашего использования я бы посмотрел на BitmapFactory.decodeStream() и URL.openStream().

Кроме того, чтобы сделать этот ответ самодостаточным, пример кода из другого сообщения по этой ссылке, показывающий, как это сделать:

private Bitmap getImageBitmap(String url) {
    Bitmap bm = null;
    try {
        URL aURL = new URL(url);
        URLConnection conn = aURL.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
    } catch (IOException e) {
        Log.e(TAG, "Error getting bitmap", e);
    }
    return bm;
} 

Я не тестировал этот код, я просто параноик и хотел бы гарантировать, что ответы SO полезны, даже если каждый другой сайт в сети исчезает: -)

Ответ 3

Сначала вы должны загрузить изображение и сохранить его в своем device(sdcard or memory). Затем получите путь к файлу, используя Uri.parse(filePath), чтобы преобразовать путь к uri наконец, вызовите ImageView setImageURI(Uri) в fullfill. - Я использую этот способ для достижения своей цели, и есть ошибка: если изображение будет большим (возможно, более 1 Мб или около того, оно может сообщать об исключенииOfMemeroy!!!)

Ответ 4

Я написал простую AsyncTask, которая конвертирует удаленный HTTPS в локальный Uri путем кэширования на SD-карту:

public class ProfileImageTask extends AsyncTask<String, Void, Uri> {

    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);
        }
    }
}

Интерфейс:

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

И реализация:

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

Протестировано с URL-адресом https://lh3.googleusercontent.com/.../photo.jpg (который имеет около 179 КБ). Можно по-прежнему уменьшать масштаб изображения большего размера, отображать набор миниатюр или передавать нужный размер.

Ответ 5

Glide - потрясающая библиотека для отображения изображений!

 Glide.with(context)
                    .load(uri)
                    .into(imageView);