How to save and display images with Picasso - android

I'm not too familiar with Picasso, but my app uses it to load images from their URL.
But I want to make a button which when it's clicked, it would mark the image as favorite, displaying it even when it's offline.
I'm saving the other stuff (strings, doubles) with a Content Provider.
So, I think the best way to accomplish this is saving the image to display even offline.
But how to I save them?

There is another good choice for downloading Image with url. Try for this code .
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFile().execute("https://i.stack.imgur.com/w4kCo.jpg");
}
class DownloadFile extends AsyncTask<String,Integer,Long> {
ProgressDialog mProgressDialog = new ProgressDialog(MainActivity.this);// Change Mainactivity.this with your activity name.
String strFolderName;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setMessage("Downloading Image ...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
#Override
protected Long doInBackground(String... aurl) {
int count;
try {
URL url = new URL((String) aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
String targetFileName="downloadedimage.jpg";//Change name and subname
int lenghtOfFile = conexion.getContentLength();
String PATH = Environment.getExternalStorageDirectory()+"/myImage/";
File folder = new File(PATH);
if(!folder.exists()){
folder.mkdir();//If there is no folder it will be created.
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(PATH+targetFileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress ((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(Integer... progress) {
mProgressDialog.setProgress(progress[0]);
if(mProgressDialog.getProgress()==mProgressDialog.getMax()){
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Download Completed !", Toast.LENGTH_LONG).show();
}
}
protected void onPostExecute(String result) {
}
}
And set downloaded image bitmap to Imageview .

This is code. By this strategy Picasso will look for images in cache and if it failed only then image will be downloaded over network.
Picasso.with(context)
.load(Uri.parse(getItem(position).getStoryBigThumbUrl()))
.networkPolicy(NetworkPolicy.OFFLINE)
.into(holder.storyBigThumb, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
// Try again online if cache failed
Picasso.with(context)
.load(Uri.parse(getItem(position)
.getStoryBigThumbUrl()))
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(holder.storyBigThumb);
}
});
Picasso have its own cache you wont be need to handle anything on your own.

Related

How do I disconnect this AsyncTask?

How can I close this connection and Asynctask if url doesn't exist. Please kindly help me .
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFile().execute("https://i.stack.imgur.com/w4kCo.jpg");
}
Download task is below and I can't control it to be stopped, progress is started and still showing if url is invalid.
class DownloadFile extends AsyncTask<String,Integer,Long> {
ProgressDialog mProgressDialog = new ProgressDialog(MainActivity.this);// Change Mainactivity.this with your activity name.
String strFolderName;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setMessage("Downloading Image ...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
#Override
protected Long doInBackground(String... aurl) {
int count;
try {
URL url = new URL((String) aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
String targetFileName="downloadedimage.jpg";//Change name and subname
int lenghtOfFile = conexion.getContentLength();
String PATH = Environment.getExternalStorageDirectory()+"/myImage/";
File folder = new File(PATH);
if(!folder.exists()){
folder.mkdir();//If there is no folder it will be created.
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(PATH+targetFileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress ((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(Integer... progress) {
mProgressDialog.setProgress(progress[0]);
if(mProgressDialog.getProgress()==mProgressDialog.getMax()){
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Download Completed !", Toast.LENGTH_LONG).show();
}
}
protected void onPostExecute(String result) {
}
}
All required permissions added properly.
You can call cancel() on the AsyncTask. Any calls to isCancelled() after that will return true. This doesn't necessarily mean your doInBackground method will stop executing. You have to manually check isCancelled() during that method to exit gracefully. Although once you call cancel(), onPostExecute() will not get called. onCancelled() will get called however.
Change this line in your code
class DownloadFile extends AsyncTask<String,Integer,Boolean> {
protected Boolean doInBackground(String... aurl) {
Now when you url fails on doInBackground method just return false from there
Now you can check this on
#Override
protected void onPostExecute(Boolean result) {
if(!result){
mProgressDialog.dismiss();
}
super.onPostExecute(aLong);
}

Download image from 'download url' Android

There are tons of download image from url codes. But is it possible to download image from url that already action download? I mean ;
Tons of codes about download the this image from that link
But I want to download image to android device from this link
Is it possible ?
Thanks
Nothing hard in this.
public class DownloadImage extends Activity {
String image_URL=http://www.hdwallpapers.in/download/minions_2015-1280x720.jpg; // give image name to save in sd card
String extStorageDirectory;
String sdCard;
Bitmap bitmap;
File file;
String savedFilePath;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonSave = (Button)findViewById(R.id.save);
ImageView bmImage = (ImageView)findViewById(R.id.image);
buttonSave.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
myAsyncTask myWebFetch = new myAsyncTask();
myWebFetch.execute();
}
});
}
class myAsyncTask extends AsyncTask<Void, Void, Void> {
TextView tv;
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dialog.dismiss();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
public ProgressDialog dialog;
dialog = new ProgressDialog(DownloadImage.this);
dialog.setMessage("Loading...");
dialog.setCancelable(false);
dialog.setIndeterminate(true);
dialog.show();
}
protected Void doInBackground(Void... arg0) {
try {
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
URL url = new URL(image_URL);
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,"somefile.jpg");
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
int totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
//updateProgress(downloadedSize, totalSize);
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
Now you downloaded image directly in sd card. Don't forget to give permission in manifest for external storage.
Try to check out this tutorial, was very helpful to me. He uses a custom class called ImageLoader with a public method DisplayImage(String url, int loader, ImageView imageView), you can call it this way:
int loader = R.drawable.loader;
// Imageview to show
ImageView image = (ImageView) findViewById(R.id.image);
// Image url
String image_url = "http://www.example.com/images/sample.jpg";
// ImageLoader class instance
ImageLoader imgLoader = new ImageLoader(getApplicationContext());
imgLoader.DisplayImage(image_url, loader, image);

AsyncTask How to get progress from MainActivity [duplicate]

This question already has answers here:
Download a file with Android, and showing the progress in a ProgressDialog
(16 answers)
Closed 8 years ago.
Hello i am writing a download project and i'm stuck right here.
#Override
protected void onProgressUpdate(Integer... progress) {
}
//I'm using in my mainactivity like that
Download download = new Download();
download.execute("http://");
I want to get progress when updated and yeah i can do this using onProgressUpdate but i wonder about can i get it from my mainactivity i mean where i called the class. I love that kinda dynamic classes because i can use them easily my every project. Thank you btw forgive me for my grammar.
I can see two options here :
You either pass the object where you want to display the progress to your AsyncTask with the constructor and then you store it :
private ProgressObject mObject;
public void MyAsyncTask(ProgressObject object) {
mObject = object
}
And the update in the onProgress() method :
object.setProgress(); //assuming the ProgressObject has a method setProgress() obviously
Or you can set up some kind of listener :
public interface ProgressListener() {
public void onProgress(int progress);
}
private mProgressListener;
public void MyAsyncTask(ProgressListener listener) {
mProgressListener = listener;
}
then use it in the onProgress() method :
mProgressListener.onProgress(80);
Just some examples, not much but I hope that help.
Use this
class DownloadFileAsync extends AsyncTask<String, String, String> {
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
File root = android.os.Environment.getExternalStorageDirectory();
//
File dir = new File (root.getAbsolutePath()+"/downoad"); //make ur folder to put download
if(dir.exists()==false) {
dir.mkdirs();
}
File file = new File(dir, "enter file name");
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1)
{
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#SuppressWarnings("deprecation")
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
Toast.makeText(DisplayActivity.this,"Successfully downloaded in phone memory.", Toast.LENGTH_SHORT).show();
}
}
How to call?
new DownloadFileAsync().execute("your URL");

ProgressBar is not updating from AsyncTask

I'm using ProgressBar to try and display the progress of downloading and saving a file. The ProgressBar shows up, but stays at 0, until it closes when the task is finished. I've tried different approaches, but it just won't update. Is there something wrong with the code?
class downloadData extends AsyncTask<Void, Integer, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params)
{
int count;
try
{
URL url = new URL("http://google.com");
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File(MainActivity.this.getFilesDir(), "downloadedData.txt");
if (!testDirectory.exists())
{
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory+"/downloadedData.txt");
byte data[] = new byte[1024];
long total = 0;
while ((count = is.read(data)) != -1)
{
total += count;
int neki = (int)(((double)total/lenghtOfFile)*100);
this.publishProgress(neki);
fos.write(data, 0, count);
}
is.close();
fos.close();
}
catch (Exception e)
{
Log.e("ERROR DOWNLOADING","Unable to download" + e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values)
{
super.publishProgress(values);
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
}
}
onCreate
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.setMax(100);
progressDialog.setMessage("Downloading Data");
And when the button is clicked that starts the downloading: progressDialog.show();
Try to debug where the progress is calculated. It might be a cast problem, you can try to do it in 2 steps to avoid getting 0 after your division. But again you should create a variable with this progress value, put a breakpoint there and see the casting problem !
I am not sure what the problem might be in your code, but you have have a go at this progressDialog.incrementProgressBy(incrementValue);
This may sound a bit tard but have you tried to invalidate() the ProgressBar after you set the progress? I am not sure it does one automatically when you set the progress.
I was also facing the same problem and spent hours on it. The problem is in calculation of the progress value.
int neki = (int)(((double)total/lenghtOfFile)*100);
Instead you should do calculation in two steps:
int neki = total * 100;
neki = (int)(neki/lengthOfFile);
publishProgress(neki);
This solved my problem. Hope this will help.

How to get back the task completion status in AsyncTask

This is related to my previous post Problem with downloading multiple files using AsyncTask
I'm trying to download two video files and also show a ProgressDialog during the process. For this I'm using AsyncTask. I want the 1st download to complete, free up memory then start the 2nd download. I wrote the following code to achieve this, but it seems the 2nd download never begins.
startDownload() {
DownloadFileAsync d1 = new DownloadFileAsync();
d1.execute(videoPath+fileNames[0],fileNames[0]);
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
Is there a way that I can get back the completion status of my 1st task & then start the 2nd ?
The following is the code of my DownloadFileAsync class:
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
File root = android.os.Environment.getExternalStorageDirectory();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(root.getAbsolutePath() + "/videos/" + aurl[1]);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
}
As DKIT Android suggested, you could start the second download from onPostExecute, but only if for example download2 is null
#Override
protected void onPostExecute(String unused)
{
if (d2 == null)
{
d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
If you need to start more downloads, just write the method outside of your asynctask, which will check which download should be started next.
Start your second download from within your first onPostExecute-method.
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
// Here you start your new AsyncTask...
}
This code:
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
...will execute once, and immediately after the first AsyncTask is executed, thus it will always be false. If you want to go that route, you need to do it in a while loop - which kind of defeats the point of making the task Async in the first place.

Categories

Resources