In my program i am downloading a Json array file contating data of notices. Each notice contain an address field from where senders image is to be downloaded. So I run another async task to download the images for each json array object. But only 1st image is downloaded no matter how many element json array has. I even tried executeOnExecutor but only folders were created and no images were downloaded.
The onpostexecute method is as below
#Override
protected void onPostExecute(JSONObject jsonObject) {
// TODO Auto-generated method stub
super.onPostExecute(jsonObject);
try {
if (jsonObject.getString("status").equalsIgnoreCase("true")) {
// refining the notices sent by server
JSONArray jsonArray = jsonObject.optJSONArray("notices");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonArrayChild = jsonArray.getJSONObject(i);
// Retrieving data for each notice item
String name = jsonArrayChild.optString("name");
String heading = jsonArrayChild.optString("heading");
String date = jsonArrayChild.optString("date");
String noticeContent = jsonArrayChild
.optString("content");
imageaddress = jsonArrayChild.optString("image");
imageName = imageaddress.substring(
imageaddress.lastIndexOf("/") + 1,
imageaddress.length());
// first we need to download the image from location
// specified in string imageaddress
new ProcessDownloadNoticeSenderImage()
.execute(imageaddress);
// now inserting the overall data into database
// storing the local address of downloaded image in
// database
File file = new File(
Environment.getExternalStorageDirectory()
+ "/veda/images/" + imageName);
String localImageAddress = file.getAbsolutePath();
// storing data in database
noticeMainDatabase.insertNotice(name, heading, date,
noticeContent, localImageAddress);
// first we need to download the image from location
// specified in string imageaddress
}
}
}
and ProcessDownloadNoticeSenderImage is as below
private class ProcessDownloadNoticeSenderImage extends
AsyncTask<String, Integer, Bitmap> {
Bitmap bitmap = null;
#Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
File folder = new File(Environment.getExternalStorageDirectory()
+ "/veda/images");
boolean success = false;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
Toast.makeText(
getApplicationContext(),
"veda/images folder is successfully created to store the images",
Toast.LENGTH_SHORT).show();
}
// saving the downloaded image into folder
File f = new File(Environment.getExternalStorageDirectory(),
"/veda/images/" + imageName);
if (f.exists()) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (Throwable ignore) {
}
}
} else if (!f.exists()) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (Throwable ignore) {
}
}
}
try {
bitmap = downloadImageFromServer(params[0]);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
help me in how to download multiple images so that i can show them in list.
Related
I have parsed JSON successfully but now i want to Cache it for offline usage, even internet is not available, and if any new entry comes i want to cache that as well.
And what would be the best option to cache data ? SharedPreferences or SQLite database
Here is my code, which i am using to Parse JSON:
public class MainActivity extends Activity {
ArrayList<Actors> actorsList;
ActorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actorsList = new ArrayList<Actors>();
new JSONAsyncTask().execute("http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors");
ListView listview = (ListView)findViewById(R.id.list);
adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long id) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), actorsList.get(position).getName(), Toast.LENGTH_LONG).show();
}
});
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Loading, please wait");
dialog.setTitle("Connecting server");
dialog.show();
dialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Actors actor = new Actors();
actor.setName(object.getString("name"));
actor.setDescription(object.getString("description"));
actorsList.add(actor);
}
return true;
}
//------------------>>
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if(result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
Why not just save it to cache folder of your app using something like this:
String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
path += "data";
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(actorsList);
objectOutputStream.close();
And after, you can read it in any time using:
List<?> list = null;
File data = new File(path);
try {
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
list = (List<Object>) objectInputStream.readObject();
objectInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
UPDATE: Okay, make class named ObjectToFileUtil, paste this code to created class
package <yourpackagehere>;
import android.os.Environment;
import java.io.*;
public class ObjectToFileUtil {
public static String objectToFile(Object object) throws IOException {
String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
path += "data";
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(object);
objectOutputStream.close();
return path;
}
public static Object objectFromFile(String path) throws IOException, ClassNotFoundException {
Object object = null;
File data = new File(path);
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
object = objectInputStream.readObject();
objectInputStream.close();
}
return object;
}
}
Change < yourpackagehere > to your package name and don't forget to add WRITE_EXTERNAL_STORAGE permission to AndroidManifest.xml. In your MainActivity add field
private String dataPath;
and replace your onPostExecute method of JSONAsyncTask class to
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if(result) {
try {
dataPath = objectToFile(arrayList);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
Now you can access get actorsList from File anytime when you want, by using
try {
actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
If you want to save path of file after closing application you must save dataPath string (and load on application start), for example, using SharedPreferences.
And what would be the best option to cache data ? SharedPreferences or SQLite database
Which is purely based on the data you received.
If the data is Small,Unstructured data then use Shared Pref.
If the data is Large,Structured data then use SQLite.
But for store the full data better you can use file concept. Store the string data in your code String data = EntityUtils.toString(entity); the data you have to save to the file.If any changes in the data from the server add that to file.And retrieve the data if internet not present. Get the example code for file operations from the above link.
I am using JSON format to save some data in a file. When i add one or 2 records, evrything is fine. I can easly check that they are correct or process them on my whish. However, when i adding 3rd record, eclipse and AVD frezees and never respond after that, so i need to kill process. i believe that reason is liying inside code below. Tell me please how can i deal with this problem.
Logs shows, that problem is not in infinite for loop.
Can it be cause by LinkedHashSet?
private void writeJSONtoFile(String jsnStr) {
FileOutputStream fos;
Set<String> copy = new LinkedHashSet<String>();
List<String> adds = new ArrayList<String>();
try {
File file = getBaseContext().getFileStreamPath("json_local.xml");
if(file.exists()){
JSONObject json1=null;
try {
json1 = new JSONObject(readData());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String fav = json1.toString();
String record = fav.substring(fav.indexOf('[')+1, fav.indexOf(']'));
Log.d("RECORD",record);
int stop = 0;
for (stop=0; stop < record.lastIndexOf('}');) {
String rec = record.substring(
record.indexOf('{', stop),
record.indexOf('}', stop + 1) + 1);
stop = record.indexOf('}', stop);
Log.d("RECORD",rec);
adds.add(rec);
}
}
String record = jsnStr.substring(jsnStr.indexOf('[')+1, jsnStr.indexOf(']'));
String rec = record.substring(record.indexOf('{'), record.indexOf('}')+1);
adds.add(rec);
copy.clear();
copy.addAll(adds);
adds.clear();
adds.addAll(copy);
int pages=(int) Math.ceil(adds.size()/10.0);
int total=adds.size();
String result = "{\"count_page\":"+pages+",\"count\":\""+total+"\",\"results\":[";
for (String temp : adds) {
result+=temp;
result+=",";
}
result = result.substring(0, result.length() - 1);
result+="]}";
fos = openFileOutput("json_local.xml", Context.MODE_WORLD_WRITEABLE);
fos.write(result.getBytes());
Log.i("json_convert", result);
fos.flush();
fos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.i("Favorites", "" + jsnStr);
Toast.makeText(getApplicationContext(),
item_title + " добавлено в избранное", Toast.LENGTH_SHORT)
.show();
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Downloading multiple files one by one using AsyncTask?
I am trying to download images (probably about 20?) and then saving them into cache.
How do I implement a download progress bar? Each image is from a individual link, if i implement a download progress bar.. would it load the download bar twenty times in my case?
this is the way i download the image and save them as cache:
/**
* Background Async Task to Load all product by making HTTP Request
* */
class downloadMagazine extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading.." + "\n" + "加载中..");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
/**
* getting preview url and then load them
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_magazine, "GET", params);
// Check your log cat for JSON reponse
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// magazines found
// Getting array of magazines
mag = json.getJSONArray(TAG_MAGAZINE);
for (int i = 0; i < mag.length(); i++) {
JSONObject c = mag.getJSONObject(i);
// Storing each json item in variable
String magazineUrl = c.getString(TAG_MAGAZINE_URL);
//String issueName = c.getString(TAG_MAGAZINE_NAME);
urlList.add(magazineUrl);
//issueNameList.add(issueName);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
// Building Parameters
List<NameValuePair> param = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json1 = jParser.makeHttpRequest(urlList.get(pos), "GET", param);
// CHECKING OF JSON RESPONSE
// Log.d("All guide: ", json.toString());
try {
issues = json1.getJSONArray(TAG_ISSUE);
for (int i = 0; i < issues.length(); i++) {
JSONObject c = issues.getJSONObject(i);
String image = c.getString(TAG_IMAGE);
imageList.add(image);
//System.out.println(imageList);
}
// STOP THE LOOP
//break;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
/**
* Updating parsed JSON data into ListView
* */
progressDialog.dismiss();
getBitmap();
buttonsCheck();
}
}
private Bitmap getBitmap() {
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory() + folderName+"/Issues/"+issueNumber);
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
for (int i=0; i<=imageList.size()-1; i++)
{
String image= imageList.get(i);
try
{
String filename = String.valueOf(image.hashCode());
Log.v("TAG FILE :", filename);
File f = new File(cacheDir, filename);
// Is the bitmap in our cache?
Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
// Download it
try {
bitmap = BitmapFactory.decodeStream(new URL(image)
.openConnection().getInputStream());
// save bitmap to cache for later
writeFile(bitmap, f);
}
catch (FileNotFoundException ex)
{
ex.printStackTrace();
Log.v("FILE NOT FOUND", "FILE NOT FOUND");
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
return null;
}
private void writeFile(Bitmap bmp, File f) {
FileOutputStream out = null;
try {
out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (Exception ex) {
}
}
}
PS: the progress bar I meant was those that shows the % to completion
count the total size of all images,
show progressbar and start downloading your files,
while downloading update your progress,
only after all files are downloaded remove your bar.
I created this AsyncTask to download an image and save it to the phone. If the image already exists is should just skip the code that downloads the image, yet every time it gets to f.exists() it's false even when the image has already been saved previously. Why would this be?
private class fanartDownloader extends AsyncTask<String, Integer, String> {
//First argument is image url and the second is the show id
#Override
protected String doInBackground(String... args) {
String fanartUrl = args[0];
fanartUrl = fanartUrl.substring(0, fanartUrl.length() - 4);
//Add proper end for small image
fanartUrl += SMALL_FANART_URL_END;
try {
String path = getApplicationContext().getFilesDir().toString();
path = path + "/" + args[1] + "/";
File f = new File(path, "fanart.jpg");
if (f.exists()) {
}
else {
f.mkdir();
URL url_value = new URL(fanartUrl);
Bitmap fanart = BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
FileOutputStream out = new FileOutputStream(path);
fanart.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
Now I've solved the issue with this slightly different iteration:
private class fanartDownloader extends AsyncTask<String, Integer, String> {
//First argument is image url and the second is the show id
#Override
protected String doInBackground(String... args) {
String fanartUrl = args[0];
fanartUrl = fanartUrl.substring(0, fanartUrl.length() - 4);
//Add proper end for small image
fanartUrl += SMALL_FANART_URL_END;
try {
String file = args[1] + "_" + "fanart.jpg";
String path = getApplicationContext().getFilesDir().toString();
path = path + "/" + file;
File f = new File(path);
if (f.exists()) {
}
else {
URL url_value = new URL(fanartUrl);
Bitmap fanart = BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
FileOutputStream out = getApplicationContext().openFileOutput(file, MODE_PRIVATE);
fanart.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
Does anyone know why the first AsyncTask wouldn't work?
So I've been looking around for an explanation on how to download a URL image (.png) to the phone itself-
I have a method going off on a menu select once they choose the photo- and it sends over the URL path as well as the filename i would like it to be called(test.png for the time being)
I am trying to do this AsynC as well to keep the UI free-
The code below actually goes off fine, but it doesn't seem to save any image though-
(I don't have an SD card on my phone, but I tried saving to the data folder for testing as well, with same results)
protected void saveImage(String imageUrl, String fileName){
class SendPostReqAsyncTask extends AsyncTask<String, Void, String>{
private String imageUrl;
private String fileName;
public SendPostReqAsyncTask (String imageUrl, String fileName)
{
super();
this.imageUrl=imageUrl;
this.fileName=fileName;
}
#Override
protected String doInBackground(String... params) {
String newfilename="";
try {
File externalStorageDirectory = Environment.getExternalStorageDirectory();
URL urlTmp = new URL(imageUrl);
newfilename = urlTmp.getFile();
newfilename = externalStorageDirectory + "/" + fileName;
Bitmap bitmap = BitmapFactory.decodeStream(urlTmp.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(newfilename);
if (bitmap != null) {
bitmap.compress(CompressFormat.PNG, 50, fileOutputStream);
return newfilename;
}
} catch (MalformedURLException e) {
Log.w("errorSaving", "Could not save image with url: " + imageUrl, e);
} catch (IOException e) {
Log.w("errorSaving", "Could not save image with url: " + imageUrl, e);
}
Log.d("errorSaving", "Failed to save image " + fileName);
return newfilename;
}
//handle result when done
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), "Photo saved to phone: " + result, Toast.LENGTH_LONG).show();
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask(imageUrl,fileName);
sendPostReqAsyncTask.execute();
}
//To download image from a url
Drawable image;
try {
InputStream is = (InputStream) this.fetch(your_image_url);
image = Drawable.createFromStream(is,"src");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Convert drawable to Bitmap
Bitmap bitmap = ((BitmapDrawable)image).getBitmap();
//Save Bitmap to a file
try {image
FileOutputStream out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
Also make sure that you set the internet permission in manifest file,
<uses-permission android:name="android.permission.INTERNET" />