failedFiles);
/**
*
* @return
*/
abstract protected int getNotificationIcon();
/**
* override this function to customize progress view on notification
*
*
* ex)
*
*
* <?xml version="1.0" encoding="utf-8"?>
* <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
* android:orientation="horizontal" android:layout_width="fill_parent"
* android:layout_height="fill_parent" android:padding="3dp">
* <ImageView android:id="@+id/image" android:layout_width="30dip"
* android:layout_height="30dip" android:layout_marginRight="10dp" />
* <LinearLayout android:orientation="vertical"
* android:layout_width="fill_parent" android:layout_height="fill_parent"
* android:padding="3dp">
* <ProgressBar android:id="@+id/progress"
* android:layout_width="200dip" android:layout_height="20dip"
* style="?android:attr/progressBarStyleHorizontal" android:max="100"
* android:progress="0" />
* <TextView android:id="@+id/text" android:layout_width="wrap_content"
* android:layout_height="20dip" android:textColor="#000" />
* </LinearLayout>
* </LinearLayout>
*
* and
*
*
*
* protected RemoteViews getProgressView(int currentNumFile, int totalNumFiles, int currentReceivedBytes, int totalNumBytes)
* {
* RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.progress);
* contentView.setImageViewResource(R.id.image, R.drawable.icon);
* contentView.setTextViewText(R.id.text, String.format("Progress (%d / %d)", currentNumFile, totalNumFiles));
* contentView.setProgressBar(R.id.progress, 100, 100 * currentReceivedBytes / totalNumBytes, false);
* return contentView;
* }
*
*
* @param currentNumFile
* @param totalNumFiles
* @param currentReceivedBytes
* @param totalNumBytes
* @return
*/
protected RemoteViews getProgressView(int currentNumFile, int totalNumFiles, int currentReceivedBytes, int totalNumBytes)
{
return null;
}
/**
*
* @param title
* @param content
*/
protected void showNotification(String ticker, String title, String content)
{
Notification notification = new Notification(getNotificationIcon(), ticker, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, getIntentForLatestInfo()), Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.setLatestEventInfo(getApplicationContext(), title, content, contentIntent);
notification.flags = getNotificationFlag();
notificationManager.notify(SERVICE_ID, notification);
}
/**
*
* @param remoteView
* @param ticker
*/
protected void showNotification(RemoteViews remoteView, String ticker)
{
Notification notification = new Notification(getNotificationIcon(), ticker, System.currentTimeMillis());
notification.contentView = remoteView;
notification.contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, getIntentForLatestInfo()), Intent.FLAG_ACTIVITY_CLEAR_TOP);
notification.flags = getNotificationFlag();
notificationManager.notify(SERVICE_ID, notification);
}
/**
* override this function to alter socket connect timeout value
* @return
*/
protected int getConnectTimeout()
{
return 1000;
}
/**
* override this function to alter socket read timeout value
* @return
*/
protected int getReadTimeout()
{
return 1000;
}
/**
*
* AsyncTask for downloading multiple files
*
* @author meinside@gmail.com
* @since 10.11.05.
*
* last update 11.03.13.
*
*/
private class AsyncDownloadTask extends AsyncTask
{
private int successCount;
private int numTotalFiles;
private HashMap targetFiles = null;
private HashMap failedFiles = null;
@Override
protected void onPreExecute()
{
super.onPreExecute();
successCount = 0;
targetFiles = getTargetFiles();
numTotalFiles = targetFiles.size();
failedFiles = new HashMap();
}
/**
* get file's size at given url (using http header)
*
* @param url
* @return -1 when failed
*/
public int getFileSizeAtURL(URL url)
{
int filesize = -1;
try
{
HttpURLConnection http = (HttpURLConnection)url.openConnection();
filesize = http.getContentLength();
http.disconnect();
}
catch(Exception e)
{
//Logger.e(e.toString());
}
return filesize;
}
/* (non-Javadoc)
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Void doInBackground(Void... params)
{
String remoteFilepath, localFilepath;
for(Entry entry: targetFiles.entrySet())
{
remoteFilepath = entry.getKey();
localFilepath = entry.getValue();
// Logger.v("downloading: '" + remoteFilepath + "' => '" + localFilepath + "'");
try
{
if(isCancelled())
return null;
URL url = new URL(remoteFilepath);
int filesize = getFileSizeAtURL(url);
int loopCount = 0;
if(filesize > 0)
{
URLConnection connection = url.openConnection();
connection.setConnectTimeout(getConnectTimeout());
connection.setReadTimeout(getReadTimeout());
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
FileOutputStream fos = new FileOutputStream(new File(localFilepath));
int bytesRead, totalBytesRead = 0;
byte[] bytes = new byte[BYTES_BUFFER_SIZE];
String progress, kbytes;
while(!isCancelled() && (bytesRead = bis.read(bytes)) != -1)
{
totalBytesRead += bytesRead;
fos.write(bytes, 0, bytesRead);
//don't show notification too often
if(!isCancelled() && loopCount++ % 20 == 0)
{
RemoteViews progressView = getProgressView(successCount + 1, numTotalFiles, totalBytesRead, filesize);
if(progressView == null)
{
progress = String.format("Download Progress (%d / %d)", successCount + 1, numTotalFiles);
kbytes = String.format("%s / %s", getStringByteSize(totalBytesRead), getStringByteSize(filesize));
if(!isCancelled())
showNotification("Downloading File(s)", progress , kbytes);
}
else
{
if(!isCancelled())
showNotification(progressView, "Downloading File(s)");
}
}
}
fos.close();
bis.close();
if(isCancelled())
return null;
successCount ++;
}
else
{
// Logger.i("file size unknown for remote file: " + remoteFilepath);
failedFiles.put(remoteFilepath, localFilepath);
}
}
catch(Exception e)
{
// Logger.e(e.toString());
showNotification("Download Failed", "Download Progress", "Failed: " + (new File(remoteFilepath)).getName());
failedFiles.put(remoteFilepath, localFilepath);
}
}
return null;
}
@Override
protected void onCancelled()
{
super.onCancelled();
// Logger.v("download task cancelled");
showNotification("Download Cancelled", "Download Progress", "Cancelled");
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
onFinishDownload(successCount, failedFiles);
String finished;
if(successCount != numTotalFiles)
finished = String.format("Finished (%d download(s) failed)", numTotalFiles - successCount);
else
finished = "Finished";
showNotification("Download Finished", "Download Progress", finished);
// Logger.v("download task finished");
}
}
/**
*
* @param size
* @return
*/
protected String getStringByteSize(int size)
{
if(size > 1024 * 1024) //mega
{
return String.format("%.1f MB", size / (float)(1024 * 1024));
}
else if(size > 1024) //kilo
{
return String.format("%.1f KB", size / 1024.0f);
}
else
{
return String.format("%d B");
}
}
}