I’m working on Android application which is taking content from internet using JSON, I load the JSON in the local database using a service, I have two main doubts:
1- How to tell the application that the DB is loaded with new data to reload the display.
2- I have images URL stored in the DB which needs to be displayed as will, to display that I’ve extended the default FrameLayout with progressBar and Image view, the new Frame Layout will display the progressBar if the Image is not loaded yet and if the image is loaded it will be shown, moreover the new FreamLayout is having a class extending AsyncTask which takes URL check the Image is existing on the file system and if it is not existing the download of image takes place. below is the sample of the class I’ve done. Is this the correct way of doing it? and in this case I have some images getting corrupted while downloading, how to overcome that issue?
Thanks for the assist.
public class ImageLoader extends FrameLayout
{
private String imageURL;
private ImageView img;
private ProgressBar pb;
private boolean isLoaded;
File rootDir = new File("/data/data/com.ait.kw.pharmacy/files");
private static final String TAG = "FrameLayoutExpander";
//defining file name and url
public String fileName = "";
public String fileURL = "";
public ImageLoader(Context context , AttributeSet attr) {
super(context,attr);
isLoaded = false;
img = new ImageView(context , null);
pb = new ProgressBar(context,null , android.R.attr.progressBarStyle);
img.setVisibility(View.INVISIBLE);
pb.setVisibility(View.VISIBLE);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
super.addView(img,params);
super.addView(pb,params);
checkAndCreateDirectory("/images");
}
public ImageLoader(Context context, AttributeSet attr, int defaultStyle)
{
super(context, attr, defaultStyle);
isLoaded = false;
img = new ImageView(context , null);
pb = new ProgressBar(context,null , android.R.attr.progressBarStyle);
img.setVisibility(View.INVISIBLE);
pb.setVisibility(View.VISIBLE);
super.addView(img);
super.addView(pb);
checkAndCreateDirectory("/images");
isLoaded = checkImaeExists(rootDir.getAbsolutePath()+"/images/"+fileName);
}
public void setImageResource(int resId) {
pb.setVisibility(View.GONE);
img.setVisibility(View.VISIBLE);
img.setImageResource(resId);
}
public void setImageDrawable(Drawable drawable) {
pb.setVisibility(View.GONE);
img.setVisibility(View.VISIBLE);
img.setImageDrawable(drawable);
}
public void startLoad(String url)
{
setImageURL(url);
loadImage();
}
public void setImageURL(String url)
{
imageURL = url;
fileName = imageURL.substring(imageURL.lastIndexOf("/")+1);
isLoaded = checkImaeExists(rootDir.getAbsolutePath()+"/images/"+fileName);
}
public void loadImage()
{
if(! isLoaded)
{
DownloadFileAsync d = new DownloadFileAsync();
d.execute(imageURL);
}
else
{
Drawable d = Drawable.createFromPath(rootDir + "/images/" + fileName);
setImageDrawable(d);
}
}
//this is our download file asynctask
class DownloadFileAsync extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... aurl) {
try {
//connecting to url
URL u = new URL(imageURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
//lenghtOfFile is used for calculating download progress
int lenghtOfFile = c.getContentLength();
//this is where the file will be seen after the download
FileOutputStream f = new FileOutputStream(new File(rootDir + "/images/", fileName));
//file input is from the url
InputStream in = c.getInputStream();
//here's the download code
byte[] buffer = new byte[1024];
int len1 = 0;
long total = 0;
while ((len1 = in.read(buffer)) > 0) {
total += len1; //total = total + len1
publishProgress("" + (int)((total*100)/lenghtOfFile));
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(String unused)
{
//dismiss the dialog after the file was downloaded
isLoaded = true;
Drawable d = Drawable.createFromPath(rootDir + "/images/" + fileName);
setImageDrawable(d);
}
}
//function to verify if directory exists
public void checkAndCreateDirectory(String dirName){
File new_dir = new File( rootDir + dirName );
if( !new_dir.exists() ){
new_dir.mkdirs();
}
}
public boolean checkImaeExists(String filename)
{
File file = new File(filename);
return file.exists();
}
}
I found this great library on github.com (nostra13 / Android-Universal-Image-Loader (Java)) it is perfect and do the job with options like caching on disk and memory and cashing size.
The gold ole is: Don’t reinvent the wheel 🙂