आप एंड्रॉइड में दिए गए यूआरएल से एक छवि को कैसे डाउनलोड और सहेज सकते हैं?
जवाबों:
अंतिम प्रमुख अपडेट: मार्च 31 2016
TL; DR उर्फ बात करना बंद करो, बस मुझे कोड दे दो !!
इस पोस्ट के नीचे पर जाएं, कॉपी
BasicImageDownloader
(जावाडोक संस्करण यहां अपने प्रोजेक्ट में), को लागूOnImageLoaderListener
इंटरफेस और बस हो गया।ध्यान दें : हालांकि
BasicImageDownloader
संभावित त्रुटियों को संभालता है और कुछ भी गलत होने की स्थिति में आपके ऐप को दुर्घटनाग्रस्त होने से बचाएगा, यह डाउनलोड होने पर कोई भी पोस्ट-प्रोसेसिंग (जैसे डाउनसाइज़िंग) नहीं करेगाBitmaps
।
चूँकि इस पोस्ट पर काफ़ी ध्यान दिया गया है, इसलिए मैंने पूरी तरह से इसे रीक्रिएटेड टेक्नोलॉजी, खराब प्रोग्रामिंग प्रैक्टिस या सिर्फ मूर्खतापूर्ण काम करने से रोकने के लिए इसे फिर से काम करने का फैसला किया है - जैसे कि मुख्य थ्रेड पर नेटवर्क चलाने के लिए "हैक्स" की तलाश है या सभी SSL सेर स्वीकार करें।
मैंने "इमेज डाउनलोडर" नाम का एक डेमो प्रोजेक्ट बनाया है जो यह दर्शाता है कि मेरे अपने डाउनलोडर कार्यान्वयन, एंड्रॉइड बिल्ट-इन के DownloadManager
साथ-साथ कुछ लोकप्रिय ओपन-सोर्स लाइब्रेरी का उपयोग करके एक छवि को कैसे डाउनलोड (और सहेजना) किया जाता है । आप पूरा स्रोत कोड देख सकते हैं या GitHub पर प्रोजेक्ट डाउनलोड कर सकते हैं ।
नोट : मैंने एसडीके 23+ (मार्शमैलो) के लिए अनुमति प्रबंधन को अभी तक समायोजित नहीं किया है, इस प्रकार यह परियोजना एसडीके 22 (लॉलीपॉप) को लक्षित कर रही है।
इस पोस्ट के अंत में अपने निष्कर्ष में मैंने अपने द्वारा बताए गए चित्र को डाउनलोड करने के प्रत्येक विशेष तरीके के उचित उपयोग के मामले में अपनी विनम्र राय साझा की है ।
आइए अपने स्वयं के कार्यान्वयन से शुरू करें (आप पोस्ट के अंत में कोड पा सकते हैं)। सबसे पहले, यह एक बेसिक ImageDownloader है और यही है। यह सब कुछ दिए गए url से जुड़ रहा है, डेटा को पढ़ रहा है और उपयुक्त होने पर इंटरफ़ेस कॉलबैक Bitmap
को ट्रिगर करते हुए इसे डिकोड करने की कोशिश कर रहा है OnImageLoaderListener
। इस दृष्टिकोण का लाभ - यह सरल है और आपके पास जो चल रहा है उसका स्पष्ट अवलोकन है। जाने के लिए एक अच्छा तरीका है अगर आप सभी की जरूरत है डाउनलोड / प्रदर्शित करने और कुछ छवियों को बचाने, जबकि आप एक स्मृति / डिस्क कैश बनाए रखने के बारे में परवाह नहीं है।
नोट: बड़ी छवियों के मामले में, आपको उन्हें स्केल करने की आवश्यकता हो सकती है ।
-
Android DownloadManager सिस्टम को आपके लिए डाउनलोड को संभालने देने का एक तरीका है। यह वास्तव में किसी भी प्रकार की फ़ाइलों को डाउनलोड करने में सक्षम है, न कि केवल चित्र। आप उपयोगकर्ता को चुपचाप और अदृश्य रूप से डाउनलोड करने दे सकते हैं, या आप उपयोगकर्ता को अधिसूचना क्षेत्र में डाउनलोड देखने के लिए सक्षम कर सकते हैं। BroadcastReceiver
डाउनलोड पूरा होने के बाद आप सूचना प्राप्त करने के लिए पंजीकरण भी कर सकते हैं । सेटअप बहुत सीधा है, नमूना कोड के लिए लिंक की गई परियोजना को देखें।
DownloadManager
यदि आप भी छवि को प्रदर्शित करना चाहते हैं, तो आम तौर पर इसका उपयोग करना एक अच्छा विचार नहीं है, क्योंकि आपको केवल डाउनलोड की Bitmap
गई सेटिंग को सेट करने के बजाय सहेजे गए फ़ाइल को पढ़ना और डिकोड करना होगा ImageView
। यह DownloadManager
भी डाउनलोड प्रगति को ट्रैक करने के लिए आप एप्लिकेशन के लिए कोई एपीआई प्रदान नहीं करता है।
-
अब महान सामान का परिचय - पुस्तकालयों। वे केवल छवियों को डाउनलोड करने और प्रदर्शित करने की तुलना में बहुत कुछ कर सकते हैं, जिनमें शामिल हैं: मेमोरी / डिस्क कैश बनाना और प्रबंधित करना, छवियों का आकार बदलना, उन्हें बदलना और अधिक।
मैं वॉली के साथ शुरू करूंगा , जो Google द्वारा बनाई गई एक शक्तिशाली लाइब्रेरी है और आधिकारिक दस्तावेज द्वारा कवर किया गया है। छवियों पर विशेषज्ञता प्राप्त न करने वाला एक सामान्य-उद्देश्य नेटवर्किंग लाइब्रेरी होने के नाते, वॉली छवियों को प्रबंधित करने के लिए काफी शक्तिशाली एपीआई की सुविधा देता है।
आपको वॉली अनुरोधों को प्रबंधित करने के लिए एक सिंगलटन वर्ग को लागू करने की आवश्यकता होगी और आप जाने के लिए अच्छे हैं।
आप अपने ImageView
वॉली की जगह लेना चाहते हैं NetworkImageView
, इसलिए डाउनलोड मूल रूप से वन-लाइनर बन सकता है:
((NetworkImageView) findViewById(R.id.myNIV)).setImageUrl(url, MySingleton.getInstance(this).getImageLoader());
यदि आपको अधिक नियंत्रण की आवश्यकता है, तो यह ImageRequest
वोली के साथ बनाने के लिए कैसा दिखता है :
ImageRequest imgRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
//do stuff
}
}, 0, 0, ImageView.ScaleType.CENTER_CROP, Bitmap.Config.ARGB_8888,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//do stuff
}
});
यह ध्यान देने योग्य है कि वॉली एक उत्कृष्ट त्रुटि हैंडलिंग तंत्र प्रदान VolleyError
करता है जो उस वर्ग को प्रदान करता है जो आपको एक त्रुटि का सटीक कारण निर्धारित करने में मदद करता है। यदि आपका ऐप बहुत सारी नेटवर्किंग करता है और छवियों को प्रबंधित करना इसका मुख्य उद्देश्य नहीं है, तो वोली आपके लिए एक आदर्श फिट है।
-
स्क्वायर का पिकासो एक प्रसिद्ध पुस्तकालय है जो आपके लिए सभी छवि लोड करने वाले सामान का काम करेगा। पिकासो का उपयोग करके एक छवि प्रदर्शित करना उतना ही सरल है:
Picasso.with(myContext)
.load(url)
.into(myImageView);
डिफ़ॉल्ट रूप से, पिकासो डिस्क / मेमोरी कैश का प्रबंधन करता है, इसलिए आपको इसके बारे में चिंता करने की आवश्यकता नहीं है। अधिक नियंत्रण के लिए आप Target
इंटरफ़ेस को लागू कर सकते हैं और अपनी छवि को लोड करने के लिए इसका उपयोग कर सकते हैं - यह वॉली उदाहरण के समान कॉलबैक प्रदान करेगा। उदाहरण के लिए डेमो प्रोजेक्ट की जाँच करें।
पिकासो आपको डाउनलोड की गई छवि में परिवर्तन लागू करने देता है और आसपास अन्य पुस्तकालय भी हैं जो उन एपीआई का विस्तार करते हैं। RecyclerView
/ ListView
/ में भी बहुत अच्छी तरह से काम करता है GridView
।
-
यूनिवर्सल इमेज लोडर एक और बहुत लोकप्रिय पुस्तकालय है जो छवि प्रबंधन के उद्देश्य से काम कर रहा है। यह अपना स्वयं का उपयोग करता है ImageLoader
कि (एक बार आरंभिक) में एक वैश्विक उदाहरण है जिसका उपयोग कोड की एक पंक्ति में छवियों को डाउनलोड करने के लिए किया जा सकता है:
ImageLoader.getInstance().displayImage(url, myImageView);
यदि आप डाउनलोड प्रगति को ट्रैक करना चाहते हैं या डाउनलोड को एक्सेस करना चाहते हैं Bitmap
:
ImageLoader.getInstance().displayImage(url, myImageView, opts,
new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
//do stuff
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
//do stuff
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//do stuff
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
//do stuff
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
//do stuff
}
});
opts
इस उदाहरण में तर्क एक है DisplayImageOptions
वस्तु। अधिक जानने के लिए डेमो प्रोजेक्ट देखें।
वॉली के समान, यूआईएल वह FailReason
वर्ग प्रदान करता है जो आपको यह जांचने में सक्षम बनाता है कि डाउनलोड विफलता पर क्या गलत हुआ। यदि आप स्पष्ट रूप से ऐसा नहीं करने के लिए कहते हैं, तो डिफ़ॉल्ट रूप से, UIL एक मेमोरी / डिस्क कैश रखता है।
नोट : लेखक ने उल्लेख किया है कि वह अब 27 नवंबर 2015 तक परियोजना का रखरखाव नहीं कर रहा है। लेकिन चूंकि कई योगदानकर्ता हैं, इसलिए हम उम्मीद कर सकते हैं कि यूनिवर्सल इमेज लोडर पर काम करेगा।
-
Facebook का फ्रेस्को सबसे नया और (IMO) सबसे उन्नत पुस्तकालय है जो छवि प्रबंधन को एक नए स्तर पर ले जाता है: एनिमेटेड प्रारूप और प्रगतिशील JPEG स्ट्रीमिंगBitmaps
का समर्थन करने के लिए जावा हीप (लॉलीपॉप से पहले) को बंद रखने से ।
फ्रेस्को के पीछे के विचारों और तकनीकों के बारे में अधिक जानने के लिए, इस पोस्ट को देखें ।
मूल उपयोग काफी सरल है। ध्यान दें कि आपको Fresco.initialize(Context);
केवल एक बार कॉल करने की आवश्यकता होगी , Application
कक्षा में बेहतर । एक से अधिक बार फ्रेस्को को शुरू करने से अप्रत्याशित व्यवहार और ओओएम त्रुटियां हो सकती हैं।
फ्रेस्को Drawee
छवियों को प्रदर्शित करने के लिए एस का उपयोग करता है , आप उन्हें एस के रूप में सोच सकते हैं ImageView
:
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/drawee"
android:layout_width="match_parent"
android:layout_height="match_parent"
fresco:fadeDuration="500"
fresco:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/placeholder_grey"
fresco:failureImage="@drawable/error_orange"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImageScaleType="centerInside"
fresco:retryImageScaleType="centerCrop"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:roundAsCircle="false" />
जैसा कि आप देख सकते हैं, बहुत सारे सामान (परिवर्तन विकल्प सहित) पहले से ही एक्सएमएल में परिभाषित हो जाते हैं, इसलिए आपको एक छवि प्रदर्शित करने के लिए बस इतना करना होगा:
mDrawee.setImageURI(Uri.parse(url));
फ्रेस्को एक विस्तारित अनुकूलन एपीआई प्रदान करता है, जो परिस्थितियों में, काफी जटिल हो सकता है और उपयोगकर्ता को डॉक्स को ध्यान से पढ़ने की आवश्यकता होती है (हाँ, कभी-कभी आपको आरटीएफएम की आवश्यकता होती है )।
मैंने नमूना परियोजना में प्रगतिशील जेपीईजी और एनिमेटेड छवियों के लिए उदाहरणों को शामिल किया है।
ध्यान दें कि निम्न पाठ मेरी व्यक्तिगत राय को दर्शाता है और इसे एक पोस्टऑउट के रूप में नहीं लिया जाना चाहिए।
Recycler-/Grid-/ListView
और प्रदर्शन-तैयार होने के लिए चित्रों की एक पूरी गुच्छा की आवश्यकता नहीं है, BasicImageDownloader को आपकी आवश्यकताओं के अनुरूप होना चाहिए।JSON
है, तो डेटा ट्रांसमिट / प्राप्त करता है, छवियों के साथ काम करता है, लेकिन वे ऐप का मुख्य उद्देश्य नहीं हैं, वॉली के साथ जाएं ।यदि आप चूक गए हैं, तो डेमो प्रोजेक्ट के लिए जीथब लिंक ।
और यहाँ है BasicImageDownloader.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashSet;
import java.util.Set;
public class BasicImageDownloader {
private OnImageLoaderListener mImageLoaderListener;
private Set<String> mUrlsInProgress = new HashSet<>();
private final String TAG = this.getClass().getSimpleName();
public BasicImageDownloader(@NonNull OnImageLoaderListener listener) {
this.mImageLoaderListener = listener;
}
public interface OnImageLoaderListener {
void onError(ImageError error);
void onProgressChange(int percent);
void onComplete(Bitmap result);
}
public void download(@NonNull final String imageUrl, final boolean displayProgress) {
if (mUrlsInProgress.contains(imageUrl)) {
Log.w(TAG, "a download for this url is already running, " +
"no further download will be started");
return;
}
new AsyncTask<Void, Integer, Bitmap>() {
private ImageError error;
@Override
protected void onPreExecute() {
mUrlsInProgress.add(imageUrl);
Log.d(TAG, "starting download");
}
@Override
protected void onCancelled() {
mUrlsInProgress.remove(imageUrl);
mImageLoaderListener.onError(error);
}
@Override
protected void onProgressUpdate(Integer... values) {
mImageLoaderListener.onProgressChange(values[0]);
}
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = null;
HttpURLConnection connection = null;
InputStream is = null;
ByteArrayOutputStream out = null;
try {
connection = (HttpURLConnection) new URL(imageUrl).openConnection();
if (displayProgress) {
connection.connect();
final int length = connection.getContentLength();
if (length <= 0) {
error = new ImageError("Invalid content length. The URL is probably not pointing to a file")
.setErrorCode(ImageError.ERROR_INVALID_FILE);
this.cancel(true);
}
is = new BufferedInputStream(connection.getInputStream(), 8192);
out = new ByteArrayOutputStream();
byte bytes[] = new byte[8192];
int count;
long read = 0;
while ((count = is.read(bytes)) != -1) {
read += count;
out.write(bytes, 0, count);
publishProgress((int) ((read * 100) / length));
}
bitmap = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
} else {
is = connection.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
}
} catch (Throwable e) {
if (!this.isCancelled()) {
error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
this.cancel(true);
}
} finally {
try {
if (connection != null)
connection.disconnect();
if (out != null) {
out.flush();
out.close();
}
if (is != null)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if (result == null) {
Log.e(TAG, "factory returned a null result");
mImageLoaderListener.onError(new ImageError("downloaded file could not be decoded as bitmap")
.setErrorCode(ImageError.ERROR_DECODE_FAILED));
} else {
Log.d(TAG, "download complete, " + result.getByteCount() +
" bytes transferred");
mImageLoaderListener.onComplete(result);
}
mUrlsInProgress.remove(imageUrl);
System.gc();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public interface OnBitmapSaveListener {
void onBitmapSaved();
void onBitmapSaveError(ImageError error);
}
public static void writeToDisk(@NonNull final File imageFile, @NonNull final Bitmap image,
@NonNull final OnBitmapSaveListener listener,
@NonNull final Bitmap.CompressFormat format, boolean shouldOverwrite) {
if (imageFile.isDirectory()) {
listener.onBitmapSaveError(new ImageError("the specified path points to a directory, " +
"should be a file").setErrorCode(ImageError.ERROR_IS_DIRECTORY));
return;
}
if (imageFile.exists()) {
if (!shouldOverwrite) {
listener.onBitmapSaveError(new ImageError("file already exists, " +
"write operation cancelled").setErrorCode(ImageError.ERROR_FILE_EXISTS));
return;
} else if (!imageFile.delete()) {
listener.onBitmapSaveError(new ImageError("could not delete existing file, " +
"most likely the write permission was denied")
.setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
return;
}
}
File parent = imageFile.getParentFile();
if (!parent.exists() && !parent.mkdirs()) {
listener.onBitmapSaveError(new ImageError("could not create parent directory")
.setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
return;
}
try {
if (!imageFile.createNewFile()) {
listener.onBitmapSaveError(new ImageError("could not create file")
.setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
return;
}
} catch (IOException e) {
listener.onBitmapSaveError(new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION));
return;
}
new AsyncTask<Void, Void, Void>() {
private ImageError error;
@Override
protected Void doInBackground(Void... params) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
image.compress(format, 100, fos);
} catch (IOException e) {
error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
this.cancel(true);
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
@Override
protected void onCancelled() {
listener.onBitmapSaveError(error);
}
@Override
protected void onPostExecute(Void result) {
listener.onBitmapSaved();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public static Bitmap readFromDisk(@NonNull File imageFile) {
if (!imageFile.exists() || imageFile.isDirectory()) return null;
return BitmapFactory.decodeFile(imageFile.getAbsolutePath());
}
public interface OnImageReadListener {
void onImageRead(Bitmap bitmap);
void onReadFailed();
}
public static void readFromDiskAsync(@NonNull File imageFile, @NonNull final OnImageReadListener listener) {
new AsyncTask<String, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(String... params) {
return BitmapFactory.decodeFile(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null)
listener.onImageRead(bitmap);
else
listener.onReadFailed();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageFile.getAbsolutePath());
}
public static final class ImageError extends Throwable {
private int errorCode;
public static final int ERROR_GENERAL_EXCEPTION = -1;
public static final int ERROR_INVALID_FILE = 0;
public static final int ERROR_DECODE_FAILED = 1;
public static final int ERROR_FILE_EXISTS = 2;
public static final int ERROR_PERMISSION_DENIED = 3;
public static final int ERROR_IS_DIRECTORY = 4;
public ImageError(@NonNull String message) {
super(message);
}
public ImageError(@NonNull Throwable error) {
super(error.getMessage(), error.getCause());
this.setStackTrace(error.getStackTrace());
}
public ImageError setErrorCode(int code) {
this.errorCode = code;
return this;
}
public int getErrorCode() {
return errorCode;
}
}
}
Cursor
( onActivityResult()
विधि में) से अपना रास्ता प्राप्त कर रहा है , फिर Bitmap
उस पथ का उपयोग करके। और हाँ, आप इस छवि को एसडी में सहेजना चाहते हैं FileOutputStream
और ए का उपयोग करने से दूर नहीं होंगे ByteArrayOutputStream
।
मैं अभी इस समस्या को हल करने से आया हूं और मैं पूरा कोड साझा करना चाहूंगा जो डाउनलोड कर सकता है, एसडीकार्ड को सहेज सकता है (और फ़ाइल नाम को छिपा सकता है) और छवियों को पुनः प्राप्त कर सकता है और अंत में यह जांचता है कि क्या छवि पहले से ही है। यूआरएल डेटाबेस से आता है इसलिए फ़ाइल नाम का उपयोग करके आसानी से फ़ाइल नाम दिया जा सकता है।
पहले छवियों को डाउनलोड करें
private class GetImages extends AsyncTask<Object, Object, Object> {
private String requestUrl, imagename_;
private ImageView view;
private Bitmap bitmap ;
private FileOutputStream fos;
private GetImages(String requestUrl, ImageView view, String _imagename_) {
this.requestUrl = requestUrl;
this.view = view;
this.imagename_ = _imagename_ ;
}
@Override
protected Object doInBackground(Object... objects) {
try {
URL url = new URL(requestUrl);
URLConnection conn = url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
} catch (Exception ex) {
}
return null;
}
@Override
protected void onPostExecute(Object o) {
if(!ImageStorage.checkifImageExists(imagename_))
{
view.setImageBitmap(bitmap);
ImageStorage.saveToSdCard(bitmap, imagename_);
}
}
}
फिर फ़ाइलों को सहेजने और पुनर्प्राप्त करने के लिए एक वर्ग बनाएं
public class ImageStorage {
public static String saveToSdCard(Bitmap bitmap, String filename) {
String stored = null;
File sdcard = Environment.getExternalStorageDirectory() ;
File folder = new File(sdcard.getAbsoluteFile(), ".your_specific_directory");//the dot makes this directory hidden to the user
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), filename + ".jpg") ;
if (file.exists())
return stored ;
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
public static File getImage(String imagename) {
File mediaImage = null;
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
if (!myDir.exists())
return null;
mediaImage = new File(myDir.getPath() + "/.your_specific_directory/"+imagename);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mediaImage;
}
public static boolean checkifImageExists(String imagename)
{
Bitmap b = null ;
File file = ImageStorage.getImage("/"+imagename+".jpg");
String path = file.getAbsolutePath();
if (path != null)
b = BitmapFactory.decodeFile(path);
if(b == null || b.equals(""))
{
return false ;
}
return true ;
}
}
फिर छवियों को एक्सेस करने के लिए पहले जांचें कि क्या यह पहले से ही है अगर नहीं तो डाउनलोड करें
if(ImageStorage.checkifImageExists(imagename))
{
File file = ImageStorage.getImage("/"+imagename+".jpg");
String path = file.getAbsolutePath();
if (path != null){
b = BitmapFactory.decodeFile(path);
imageView.setImageBitmap(b);
}
} else {
new GetImages(imgurl, imageView, imagename).execute() ;
}
AsyncTask
फायदे (पैराड्राइज़ेशन का समानांतर उपयोग, समानांतर निष्पादन ..) की कुछ बुनियादी समझ का भी अभाव है । कृपया विवरण के लिए नीचे मेरे उदाहरण देखें। पुनश्च । उन लोगों के लिए जो सोच सकते हैं कि मैंने जो भी कारण के लिए अपने स्वयं के कोड को बढ़ावा देने के लिए यह लिखा है: नहीं, मैं सिर्फ उन मुद्दों को इंगित कर रहा हूं जो मैं दिए गए उदाहरण में देख सकता हूं।
download
विधि, विशेष रूप से doInBackground
मेरे द्वारा उपयोग किए जाने वाले कार्य की विधि पर करीब से नज़र डालें । ब्लॉक IOException
में एक लैंड होगा catch (Throwable e)
, जिसके परिणामस्वरूप ImageError
वापसी की जाएगी और onError()
कॉलबैक को ट्रिगर किया जाएगा। ImageError
वस्तु मूल स्टैक ट्रेस और हुआ के कारण शामिल होंगेException
इसे डाउनलोड करने के लिए आपको वास्तव में अपने कोड की आवश्यकता क्यों है? कैसे बस के बारे में अपने URI डाउनलोड प्रबंधक को पारित करने के लिए?
public void downloadFile(String uRl) {
File direct = new File(Environment.getExternalStorageDirectory()
+ "/AnhsirkDasarp");
if (!direct.exists()) {
direct.mkdirs();
}
DownloadManager mgr = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(uRl);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false).setTitle("Demo")
.setDescription("Something useful. No, really.")
.setDestinationInExternalPublicDir("/AnhsirkDasarp", "fileName.jpg");
mgr.enqueue(request);
}
यह आपकी मदद कर सकता है ..
Button download_image = (Button)bigimagedialog.findViewById(R.id.btn_downloadimage);
download_image.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
boolean success = (new File("/sdcard/dirname")).mkdir();
if (!success)
{
Log.w("directory not created", "directory not created");
}
try
{
URL url = new URL("YOUR_URL");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
String data1 = String.valueOf(String.format("/sdcard/dirname/%d.jpg",System.currentTimeMillis()));
FileOutputStream stream = new FileOutputStream(data1);
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outstream);
byte[] byteArray = outstream.toByteArray();
stream.write(byteArray);
stream.close();
Toast.makeText(getApplicationContext(), "Downloading Completed", Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
मेरे पास एक सरल समाधान है जो पूरी तरह से काम कर रहा है। कोड मेरा नहीं है, मुझे यह इस लिंक पर मिला । यहाँ चरणों का पालन करें:
1. छवि को डाउनलोड करने से पहले, आइए एंड्रॉइड में आंतरिक भंडारण में एक छवि फ़ाइल में बिटमैप को सहेजने के लिए एक विधि लिखें। यह एक संदर्भ की जरूरत है, getApplicationContext () द्वारा आवेदन के संदर्भ में पास का उपयोग करने के लिए बेहतर है। इस विधि को आपके गतिविधि वर्ग या अन्य उपयोग कक्षाओं में डंप किया जा सकता है।
public void saveImage(Context context, Bitmap b, String imageName)
{
FileOutputStream foStream;
try
{
foStream = context.openFileOutput(imageName, Context.MODE_PRIVATE);
b.compress(Bitmap.CompressFormat.PNG, 100, foStream);
foStream.close();
}
catch (Exception e)
{
Log.d("saveImage", "Exception 2, Something went wrong!");
e.printStackTrace();
}
}
2. अब हमारे पास andorid में एक इमेज फाइल में बिटमैप को सेव करने का एक तरीका है, आइए url द्वारा इमेज डाउनलोड करने के लिए AsyncTask लिखते हैं। इस निजी वर्ग को एक उपवर्ग के रूप में आपकी गतिविधि कक्षा में रखा जाना चाहिए। छवि डाउनलोड होने के बाद, ऑनपोस्ट एक्स्यूट विधि में, यह इमेज को बचाने के लिए ऊपर दिए गए saveImage विधि को कॉल करता है। ध्यान दें, छवि नाम "my_image.png" के रूप में हार्डकोड किया गया है।
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
private String TAG = "DownloadImage";
private Bitmap downloadImageBitmap(String sUrl) {
Bitmap bitmap = null;
try {
InputStream inputStream = new URL(sUrl).openStream(); // Download Image from URL
bitmap = BitmapFactory.decodeStream(inputStream); // Decode Bitmap
inputStream.close();
} catch (Exception e) {
Log.d(TAG, "Exception 1, Something went wrong!");
e.printStackTrace();
}
return bitmap;
}
@Override
protected Bitmap doInBackground(String... params) {
return downloadImageBitmap(params[0]);
}
protected void onPostExecute(Bitmap result) {
saveImage(getApplicationContext(), result, "my_image.png");
}
}
3. छवि डाउनलोड करने के लिए AsyncTask परिभाषित किया गया है, लेकिन हमें उस AsyncTask को चलाने के लिए इसे निष्पादित करने की आवश्यकता है। ऐसा करने के लिए, अपनी गतिविधि कक्षा में अपनी ऑनक्रिट विधि में, या एक बटन या अन्य स्थानों पर जो आप फिट देखते हैं, इस पंक्ति को लिखें।
new DownloadImage().execute("http://developer.android.com/images/activity_lifecycle.png");
छवि को /data/data/your.app.packagename/files/my_image.jpeg में सहेजा जाना चाहिए, अपने डिवाइस से इस निर्देशिका तक पहुंचने के लिए इस पोस्ट को देखें।
IMO इस मुद्दे को हल करता है! यदि आप आगे के चरणों को चाहते हैं जैसे कि छवि को लोड करें तो आप इन अतिरिक्त चरणों का पालन कर सकते हैं:
4. छवि डाउनलोड होने के बाद, हमें आंतरिक संग्रहण से छवि बिटमैप को लोड करने का एक तरीका चाहिए, इसलिए हम इसका उपयोग कर सकते हैं। आइए इमेज बिटमैप लोड करने की विधि लिखें। यह विधि दो पैरामीटर्स लेती है, एक संदर्भ और एक छवि फ़ाइल का नाम, पूर्ण पथ के बिना, संदर्भ ।openFileInput (imageName) फ़ाइल को सेव डायरेक्टरी में देखेगा जब यह फ़ाइल नाम ऊपर दिए गए saveIage मेथड में सहेजा गया था।
public Bitmap loadImageBitmap(Context context, String imageName) {
Bitmap bitmap = null;
FileInputStream fiStream;
try {
fiStream = context.openFileInput(imageName);
bitmap = BitmapFactory.decodeStream(fiStream);
fiStream.close();
} catch (Exception e) {
Log.d("saveImage", "Exception 3, Something went wrong!");
e.printStackTrace();
}
return bitmap;
}
5. अब हमारे पास एक ImageView या किसी भी अन्य दृश्य की छवि को सेट करने के लिए आवश्यक सब कुछ है जिसे आप छवि का उपयोग करना पसंद करते हैं। जब हम छवि को सहेजते हैं, तो हम "my_image.jpeg" के रूप में छवि नाम को हार्डकोड करते हैं, अब हम बिटमैप को पाने के लिए इस छवि का नाम उपरोक्त loadImageBitmap विधि से पारित कर सकते हैं और इसे एक ImageView पर सेट कर सकते हैं।
someImageView.setImageBitmap(loadImageBitmap(getApplicationContext(), "my_image.jpeg"));
6. छवि नाम से छवि को पूर्ण पथ प्राप्त करने के लिए।
File file = getApplicationContext().getFileStreamPath("my_image.jpeg");
String imageFullPath = file.getAbsolutePath();
7. जांचें कि क्या छवि फ़ाइल मौजूद है।
फ़ाइल फ़ाइल =
getApplicationContext().getFileStreamPath("my_image.jpeg");
if (file.exists()) Log.d("file", "my_image.jpeg exists!");
छवि फ़ाइल को हटाने के लिए।
फ़ाइल फ़ाइल = getApplicationContext ()। GetFileStreamPath ("my_image.jpeg"); if (file.delete ()) Log.d ("file", "my_image.jpeg हटाया गया!");
यह कोड पूरी तरह से मेरे प्रोजेक्ट में चलता है
downloadImagesToSdCard(imagepath,imagepath);
private void downloadImagesToSdCard(String downloadUrl,String imageName)
{
try
{
URL url = new URL("www.xxx.com"+downloadUrl);
/* making a directory in sdcard */
// String sdCard=Environment.getExternalStorageDirectory().toString();
ContextWrapper cw = new ContextWrapper(getActivity());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("files", Context.MODE_PRIVATE);
File myDir = new File(directory,"folder");
/* if specified not exist create new */
if(!myDir.exists())
{
myDir.mkdir();
Log.v("", "inside mkdir");
}
/* checks the file and if it already exist delete */
String fname = imageName;
File file = new File (myDir, fname);
Log.d("file===========path", ""+file);
if (file.exists ())
file.delete ();
/* Open a connection */
URLConnection ucon = url.openConnection();
InputStream inputStream = null;
HttpURLConnection httpConn = (HttpURLConnection)ucon;
httpConn.setRequestMethod("GET");
httpConn.connect();
inputStream = httpConn.getInputStream();
/*if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
{
inputStream = httpConn.getInputStream();
}*/
FileOutputStream fos = new FileOutputStream(file);
int totalSize = httpConn.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) >0 )
{
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
}
fos.close();
Log.d("test", "Image Saved in sdcard..");
viewimage();
}
catch(IOException io)
{
io.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void viewimage()
{
String path = serialnumber+".png";
ContextWrapper cw = new ContextWrapper(getActivity());
//path to /data/data/yourapp/app_data/dirName
File directory = cw.getDir("files", Context.MODE_PRIVATE);
File mypath=new File(directory,"folder/"+path);
Bitmap b;
try {
b = BitmapFactory.decodeStream(new FileInputStream(mypath));
// b.compress(format, quality, stream)
profile_image.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
Bitmap bmp = null;
URL url = new URL("Your_URL");
URLConnection conn = url.openConnection();
bmp = BitmapFactory.decodeStream(conn.getInputStream());
File f = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".jpg");
if(f.exists())
f.delete();
f.createNewFile();
Bitmap bitmap = bmp;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();
Log.e(TAG, "imagepath: "+f );
}
catch (Exception e)
{
e.printStackTrace();
}
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) {
try {
URL 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);
saveImage(data);
}
private void saveImage(Bitmap data) {
File createFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"test");
createFolder.mkdir();
File saveImage = new File(createFolder,"downloadimage.jpg");
try {
OutputStream outputStream = new FileOutputStream(saveImage);
data.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
सुनिश्चित करें कि आपने मेमोरी में डेटा लिखने की अनुमति जोड़ी है
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
जैसा कि Google बताता है, अभी के लिए, प्रकट में बाह्य संग्रहण पर भी पढ़ने योग्य जोड़ना न भूलें:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
स्रोत: http://developer.android.com/training/basics/data-storage/files.html#GetWritePermission