Лучший способ загрузки изображения с url в Android

Я использую ниже метод для загрузки одного изображения из URL

public static Bitmap getBitmap(String url) {
    try {
        InputStream is = (InputStream) new URL(url).getContent();
        Bitmap d = BitmapFactory.decodeStream(is);
        is.close();
        return d;
    } catch (Exception e) {
        return null;
    }
}

Иногда я получаю исключение outofmemory.

Я не могу исключить исключение из памяти. Приложение закроется. Как предотвратить это?

Есть ли лучший способ загрузки изображений, который также быстрее?

Ответ 1

Попробуйте использовать это:

public Bitmap getBitmapFromURL(String src) {
    try {
        java.net.URL url = new java.net.URL(src);
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

И для проблемы OutOfMemory:

 public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // CREATE A MATRIX FOR THE MANIPULATION
    Matrix matrix = new Matrix();
    // RESIZE THE BIT MAP
    matrix.postScale(scaleWidth, scaleHeight);

    // "RECREATE" THE NEW BITMAP
    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
            matrix, false);

    return resizedBitmap;
}

Ответ 2

Я использую эту библиотеку, это действительно здорово, когда вам приходится иметь дело с большим количеством изображений. Он загружает их асинхронно, кэширует их и т.д.

Что касается исключений OOM, использование этого и этого класса резко сократило их для меня.

Ответ 3

            public void DownloadImageFromPath(String path){
            InputStream in =null;
            Bitmap bmp=null;
             ImageView iv = (ImageView)findViewById(R.id.img1);
             int responseCode = -1;
            try{

                 URL url = new URL(path);//"http://192.xx.xx.xx/mypath/img1.jpg
                 HttpURLConnection con = (HttpURLConnection)url.openConnection();
                 con.setDoInput(true);
                 con.connect();
                 responseCode = con.getResponseCode();
                 if(responseCode == HttpURLConnection.HTTP_OK)
                 {
                     //download 
                     in = con.getInputStream();
                     bmp = BitmapFactory.decodeStream(in);
                     in.close();
                     iv.setImageBitmap(bmp);
                 }

            }
            catch(Exception ex){
                Log.e("Exception",ex.toString());
            }
        }

Ответ 4

вы можете скачать изображение Asyn task используйте этот класс:

public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {

private final WeakReference<ImageView> imageViewReference;
private final MemoryCache memoryCache;
private final BrandItem brandCatogiriesItem;
private Context context;
private String url;

public ImageDownloaderTask(ImageView imageView, String url, Context context) {
    imageViewReference = new WeakReference<ImageView>(imageView);
    memoryCache = new MemoryCache();
    brandCatogiriesItem = new BrandItem();
    this.url = url;
    this.context = context;
}

@Override
protected Bitmap doInBackground(String... params) {

    return downloadBitmap(params[0]);
}

@Override
protected void onPostExecute(Bitmap bitmap) {
    if (isCancelled()) {
        bitmap = null;
    }

    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {
            if (bitmap != null) {
                memoryCache.put("1", bitmap);
                brandCatogiriesItem.setUrl(url);
                brandCatogiriesItem.setThumb(bitmap);
                // BrandCatogiriesItem.saveLocalBrandOrCatogiries(context, brandCatogiriesItem);
                imageView.setImageBitmap(bitmap);
            } else {
                Drawable placeholder = imageView.getContext().getResources().getDrawable(R.drawable.placeholder);
                imageView.setImageDrawable(placeholder);
            }
        }

    }
}

private Bitmap downloadBitmap(String url) {
    HttpURLConnection urlConnection = null;
    try {
        URL uri = new URL(url);
        urlConnection = (HttpURLConnection) uri.openConnection();

        int statusCode = urlConnection.getResponseCode();
        if (statusCode != HttpStatus.SC_OK) {
            return null;
        }

        InputStream inputStream = urlConnection.getInputStream();
        if (inputStream != null) {

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            return bitmap;
        }
    } catch (Exception e) {
        Log.d("URLCONNECTIONERROR", e.toString());
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        Log.w("ImageDownloader", "Error downloading image from " + url);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();

        }
    }
    return null;
}

}

и назовите это так:

  new ImageDownloaderTask(thumbImage, item.thumbnail, context).execute(item.thumbnail);

Ответ 5

Вы можете использовать функцию ниже, чтобы загрузить изображение с URL.

private Bitmap getImage(String imageUrl, int desiredWidth, int desiredHeight)
    {   
           private Bitmap image = null;
           int inSampleSize = 0;


            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inJustDecodeBounds = true;

            options.inSampleSize = inSampleSize;

            try
            {
                URL url = new URL(imageUrl);

                HttpURLConnection connection = (HttpURLConnection)url.openConnection();

                InputStream stream = connection.getInputStream();

                image = BitmapFactory.decodeStream(stream, null, options);

                int imageWidth = options.outWidth;

                int imageHeight = options.outHeight;

                if(imageWidth > desiredWidth || imageHeight > desiredHeight)
                {   
                    System.out.println("imageWidth:"+imageWidth+", imageHeight:"+imageHeight);

                    inSampleSize = inSampleSize + 2;

                    getImage(imageUrl);
                }
                else
                {   
                    options.inJustDecodeBounds = false;

                    connection = (HttpURLConnection)url.openConnection();

                    stream = connection.getInputStream();

                    image = BitmapFactory.decodeStream(stream, null, options);

                    return image;
                }
            }

            catch(Exception e)
            {
                Log.e("getImage", e.toString());
            }

        return image;
    }

Смотрите полное объяснение здесь

Ответ 6

Добавьте эту зависимость для сети Android в свой проект

compile 'com.amitshekhar.android:android-networking:1.0.0

    String url = "http://ichef.bbci.co.uk/onesport/cps/480/cpsprodpb/11136/production/_95324996_defoe_rex.jpg";
    File file;
    String dirPath, fileName;
    Button downldImg;

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

        // Initialization Of DownLoad Button
        downldImg = (Button) findViewById(R.id.DownloadButton);

        // Initialization Of DownLoad Button
        AndroidNetworking.initialize(getApplicationContext());

        //Folder Creating Into Phone Storage
        dirPath = Environment.getExternalStorageDirectory() + "/Image";

        fileName = "image.jpeg";

        //file Creating With Folder & Fle Name
        file = new File(dirPath, fileName);

        //Click Listener For DownLoad Button
        downldImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                AndroidNetworking.download(url, dirPath, fileName)
                        .build()
                        .startDownload(new DownloadListener() {
                            @Override
                            public void onDownloadComplete() {

                                Toast.makeText(MainActivity.this, "DownLoad Complete", Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onError(ANError anError) {

                            }
                        });
            }
        });
    }
}

После запуска этого кода Проверка памяти телефона Вы можете увидеть там папку - ИзображениеПроверьте внутри этой папки, вы видите там файл изображения с именем "image.jpeg"

Спасибо!

Ответ 8

public class testCrop extends AppCompatActivity {
    ImageView iv;
    String imagePath = "https://style.pk/wp-content/uploads/2015/07/omer-Shahzad-performed-umrah-600x548.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testcrpop);
        iv = (ImageView) findViewById(R.id.testCrop);
        imageDownload image = new imageDownload(testCrop.this, iv);
        image.execute(imagePath);
    }

    class imageDownload extends AsyncTask<String, Integer, Bitmap> {
        Context context;
        ImageView imageView;
        Bitmap bitmap;
        InputStream in = null;
        int responseCode = -1;
//constructor.
        public imageDownload(Context context, ImageView imageView) {
            this.context = context;
            this.imageView = imageView;
        }
        @Override
        protected void onPreExecute() {


        }
        @Override
        protected Bitmap doInBackground(String... params) {

            URL url = null;
            try {
                url = new URL(params[0]);

                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setDoOutput(true);
                httpURLConnection.connect();
                responseCode = httpURLConnection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    in = httpURLConnection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }
        @Override
        protected void onPostExecute(Bitmap data) {
            imageView.setImageBitmap(data);
        }
    }
}

OUTPUT

введите описание изображения здесь

Ответ 9

Шаг 1. Объявление разрешения в манифесте Android

Первое, что нужно сделать в своем первом Android-проекте, - это указать необходимые разрешения в файле ‘AndroidManifest.xml.

Для загрузки изображения Android с URL-адреса нам необходимо разрешение на доступ к Интернету для загрузки файла, чтения и записи во внутреннее хранилище для сохранения изображения во внутреннем хранилище.

Добавьте следующие строки кода в верхней части тега файла AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Шаг 2. Запросите требуемое разрешение у пользователя

Android позволяет запускать каждое приложение в песочнице. Если приложению требуется доступ к определенным ресурсам или информации за пределами этой изолированной программной среды, оно должно запросить разрешение у пользователя.

Начиная с Android 6.0, Google хочет, чтобы разработчики запрашивали разрешение у пользователя из приложения, чтобы узнать больше о разрешениях, прочитайте это.

Поэтому для загрузки изображения Android с URL-адреса вам потребуется запросить чтение хранилища и запись

Для этого мы будем использовать следующие строки кода, чтобы сначала проверить, предоставлено ли пользователю необходимое разрешение, а если нет, то мы запросим разрешение на чтение и запись в хранилище.

Мы создавали метод la Downlaod Image, вы можете просто вызывать его везде, где вам нужно загрузить изображение.

void DownloadImage(String ImageUrl) {

    if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 123);
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123);
        showToast("Need Permission to access storage for Downloading Image");
    } else {
        showToast("Downloading Image...");
       //Asynctask to create a thread to downlaod image in the background 
        new DownloadsImage().execute(ImageUrl);
    }
}

Теперь, когда мы запросили и получили разрешение пользователя, чтобы начать загрузку образа Android с URL-адреса, мы создадим AsyncTask, поскольку вам не разрешено запускать фоновый процесс в главном потоке.

class DownloadsImage extends AsyncTask<String, Void,Void>{

    @Override
    protected Void doInBackground(String... strings) {
        URL url = null;
        try {
            url = new URL(strings[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        Bitmap bm = null;
        try {
            bm =    BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        //Create Path to save Image
        File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+ "/AndroidDvlpr"); //Creates app specific folder

        if(!path.exists()) {
            path.mkdirs();
        }

        File imageFile = new File(path, String.valueOf(System.currentTimeMillis())+".png"); // Imagename.png
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(imageFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try{
            bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
            out.flush();
            out.close();
            // Tell the media scanner about the new file so that it is
            // immediately available to the user.
            MediaScannerConnection.scanFile(MainActivity.this,new String[] { imageFile.getAbsolutePath() }, null,new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                    // Log.i("ExternalStorage", "Scanned " + path + ":");
                    //    Log.i("ExternalStorage", "-> uri=" + uri);
                }
            });
        } catch(Exception e) {
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        showToast("Image Saved!");
    }
}

В приведенных выше строках кода создается URL-адрес и растровое изображение, с использованием BitmapFactory.decodeStream файл загружается.

Путь к файлу создается для сохранения изображения (мы создали папку с именем AndroidDvlpr в DIRECTORY_PICTURES), и загрузка инициализируется.

После загрузки файла MediaScannerConnection вызывается для чтения метаданных из файла и добавления файла к поставщику медиа-контента, чтобы изображение было доступно для пользователя.

В приведенных выше строках кода мы также создали метод showToast() для отображения Toast. полный код здесь:

void showToast(String msg){
Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
}

Подробнее здесь

Ответ 10

Сначала объявите разрешение в манифесте Android: -

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

MainActivityForDownloadImages.java

public class MainActivityForDownloadImages extends AppCompatActivity {


//    String urls = "https://stimg.cardekho.com/images/carexteriorimages/930x620/Kia/Kia-Seltos/6232/1562746799300/front-left-side-47.jpg";
    String urls = "https://images5.alphacoders.com/609/609173.jpg";
    Button button;
     public final Context context = this;
    ProgressDialog progressDialog ;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_for_download_images);
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
        }


        progressDialog = new ProgressDialog(context);
        button = findViewById(R.id.downloadImagebtn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // initialize the progress dialog like in the first example
                // this is how you fire the downloader

                Intent intent = new Intent(context, DownloadService.class);
                intent.putExtra("url", urls);
                intent.putExtra("receiver", new DownloadReceiver(new Handler()));
                startService(intent);


            }
        });


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 0) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED) {


            }
        }
    }

    private class DownloadReceiver extends ResultReceiver {

        public DownloadReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            super.onReceiveResult(resultCode, resultData);

            if (resultCode == DownloadService.UPDATE_PROGRESS) {

                int progress = resultData.getInt("progress"); //get the progress
                progressDialog.setProgress(progress);
                progressDialog.setMessage("Images Is Downloading");
                progressDialog.show();

                if (progress == 100) {

                    progressDialog.dismiss();

                }
            }
        }
    }

}

DownloadService.java

public class DownloadService extends IntentService {

public static final int UPDATE_PROGRESS = 8344;
String folder_main = "ImagesFolder";


public DownloadService() {
    super("DownloadService");
}


@Override
protected void onHandleIntent(Intent intent) {

    String urlToDownload = intent.getStringExtra("url");
    ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");

    try {

        //create url and connect
        URL url = new URL(urlToDownload);
        URLConnection connection = url.openConnection();
        connection.connect();

        // this will be useful so that you can show a typical 0-100% progress bar
        int fileLength = connection.getContentLength();

        // download the file
        InputStream input = new BufferedInputStream(connection.getInputStream());


        File outerFolder = new File(Environment.getExternalStorageDirectory(), folder_main);
        File inerDire = new File(outerFolder.getAbsoluteFile(), System.currentTimeMillis() + ".jpg");


        if (!outerFolder.exists()) {
            outerFolder.mkdirs();
        }

        inerDire.createNewFile();


        FileOutputStream output = new FileOutputStream(inerDire);

        byte data[] = new byte[1024];
        long total = 0;
        int count;
        while ((count = input.read(data)) != -1) {
            total += count;

            // publishing the progress....
            Bundle resultData = new Bundle();
            resultData.putInt("progress", (int) (total * 100 / fileLength));
            receiver.send(UPDATE_PROGRESS, resultData);
            output.write(data, 0, count);
        }

        // close streams
        output.flush();
        output.close();
        input.close();

    } catch (IOException e) {
        e.printStackTrace();

    }

    Bundle resultData = new Bundle();
    resultData.putInt("progress", 100);

    receiver.send(UPDATE_PROGRESS, resultData);
}

}

Ответ 11

Я все еще изучаю Android, поэтому я не могу предоставить богатый контекст или причину моего предложения, но это то, что я использую для извлечения файлов из https и локальных URL-адресов. Я использую это в своем отчете onActivity (как для съемки, так и для выбора из галереи), а также в AsyncTask для извлечения https-адресов.

InputStream input = new URL("your_url_string").openStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);