我正在尝试使用IntentService下载文件。我的下载队列被中断。
我使用以下代码启动服务
Intent intent = new Intent(ViewShowList.this, DownloadService.class);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(handler);
intent.putExtra("MESSENGER", messenger);
intent.putExtra("url", url);
intent.putExtra("share_id", showID);
intent.putExtra("showname", name);
intent.putExtra("showdatecreated", dateCreated);
intent.putExtra("noofFiles", noofFiles);
startService(intent);
回传的处理程序
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
public void handleMessage(Message message) {
Log.d(TAG, "handleMessage.....................");
//Object path = message.obj;
if (message.arg1 == DownloadService.COMPLETED) {
Toast.makeText(mContext, getResources().getString(R.string.Text_MadeOffline), Toast.LENGTH_SHORT).show();
createOfflineShowsList();
syncShowAssets();
if (showListadapter != null) {
showListadapter.notifyDataSetChanged();
}
} else {
Log.e(TAG, "Download Failed...");
}
}
};
DownloadService.java
这是扩展IntentService
的服务类public class DownloadService
extends IntentService {
private int OFFSET;
private int LIMIT;
String data;
private final String TAG = "DownloadService";
private int result = Activity.RESULT_CANCELED;
public static int COMPLETED = 100;
public static int FAILED = 101;
public static int LOW_SPACE = 102;
public static int NETWORK_PROBLEM = 103;
public static int ASSERT_EXISIT = 104;
public static int PARTIALLY_DOWNLOADED = 105;
public static int NO_FILE = 105;
private NotificationManager notificationManager;
private Notification notification;
ConnectivityManager connMgr;
ArrayList<HashMap<String, String>> showAssetList;
private SharedPreferences sotcPref;
PendingIntent contentIntent;
int i = 1;
String url;
String showname;
String showdatecreated;
String showId;
Messenger messenger;
int noofFiles;
public DownloadService() {
super("DownloadService");
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 5 " + "DownloadService()constructor");
}
if (Constants.DEBUG) {
Log.d(TAG, "DownloadService... Constructor");
}
OFFSET = 0;
LIMIT = 3;
}
@SuppressWarnings("deprecation")
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 6 " + "onHandleIntent");
}
connMgr = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
notificationManager = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
sotcPref = getApplicationContext().getSharedPreferences("SOTCPref", MODE_PRIVATE);
if (Constants.DEBUG) {
Log.d(TAG, "onHandleIntent.........");
}
Bundle extras = intent.getExtras();
url = extras.getString("url");
showname = extras.getString("showname");
showdatecreated = extras.getString("showdatecreated");
//sara
if (showdatecreated.contains("/")) {
data = showdatecreated.replaceAll("/", "#");
if (Constants.DEBUG) {
System.out.println("date");
}
if (Constants.DEBUG) {
System.out.println(data);
}
} else {
data = showdatecreated;
if (Constants.DEBUG) {
System.out.println("date in else");
}
if (Constants.DEBUG) {
System.out.println(showdatecreated);
}
if (Constants.DEBUG) {
System.out.println(data);
}
}
showId = extras.getString("share_id");
noofFiles = extras.getInt("noofFiles");
messenger = (Messenger) extras.get("MESSENGER");
Intent notificationIntent = new Intent();
contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
notification = new Notification(R.drawable.sotc_notification_icon, "", System.currentTimeMillis());
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
notification.contentView = new RemoteViews(getApplicationContext()
.getPackageName(), R.layout.upload_progress_bar);
notification.icon = R.drawable.sotc_notification_icon;
notification.contentView.setTextViewText(R.id.textView1, showname);
notification.contentIntent = contentIntent;
notification.contentView.setProgressBar(R.id.progressBar1, 100, 0, false);
notificationManager.notify(1, notification);
if (Constants.DEBUG) {
Log.i("FOO", "Notification started");
}
if (showname.length() > 18) {
showname = showname.substring(0, 17);
}
if (DownloadAssets.TOTAL_ASSET_COUNT == 0) {
downloadSetofAssets(OFFSET, LIMIT, url);
if (DownloadAssets.TOTAL_ASSET_COUNT > LIMIT) {
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 8 " + "if(DownloadAssets.TOTAL_ASSET_COUNT > LIMIT)");
}
for (OFFSET = LIMIT; OFFSET < DownloadAssets.TOTAL_ASSET_COUNT; ) {
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 8.1 " + "if(DownloadAssets.TOTAL_ASSET_COUNT > LIMIT)");
}
downloadSetofAssets(OFFSET, LIMIT, url);
OFFSET = OFFSET + LIMIT;
}
}
}
if (i > 1) {
result = DownloadService.COMPLETED;
notification.setLatestEventInfo(DownloadService.this, "Downloaded Successfully", "", contentIntent);
Message msg = Message.obtain();
msg.arg1 = result;
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
if (Constants.DEBUG) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
} else {
result = DownloadService.FAILED;
notification.setLatestEventInfo(DownloadService.this, "Downloaded Failed", "", contentIntent);
if (Constants.DEBUG) {
Log.e(TAG, "Download Failed...");
}
}
notification.contentView.setImageViewResource(R.id.image, R.drawable.icon);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1, notification);
}
private void downloadSetofAssets(int OFFSET, int LIMIT, String url) {
// TODO Auto-generated method stub
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 7 " + "downloadSetofAssets");
}
try {
url = url.replace("value1", URLEncoder.encode("" + OFFSET, "UTF-8"));
url = url.replace("value2", URLEncoder.encode("" + LIMIT, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (Constants.DEBUG) {
Log.i(TAG, "Show offline -- Asset URL: " + url);
}
showAssetList = DownloadAssets.hit(getApplicationContext(), url);
for (HashMap<String, String> asset : showAssetList) {
String thumbUrl = asset.get("thumb_url");
String normalUrl = asset.get("normal_url");
String mp4Url = asset.get("mp4_url");
String fileType = asset.get("filetype");
String assetID = asset.get("id");
String assetType = asset.get("asset_type");
if (Constants.DEBUG) {
Log.d(TAG, "Thumb Url :" + thumbUrl);
}
if (Constants.DEBUG) {
Log.d(TAG, "Normal Url :" + normalUrl);
}
if (Constants.DEBUG) {
Log.d(TAG, "Asset ID : " + assetID);
}
if (Constants.DEBUG) {
Log.d(TAG, "Asset Type : " + assetType);
}
if (Constants.DEBUG) {
Log.d(TAG, "MP4 Url : " + mp4Url);
}
if (Constants.DEBUG) {
Log.d(TAG, "FileType : " + fileType);
}
boolean isDownloaded = false;
if (assetType.equals("1")) { // Image
File assetDirectory = createAssetDirectory(showId, showname, data, assetID, assetType);
if (assetDirectory != null) {
File thumb = new File(assetDirectory.getAbsolutePath(), "/Thumb");
thumb.mkdirs();
// Thumbnail
File thumbFile = new File(thumb.getAbsolutePath(), "/Thumb." + getExtention(thumbUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Thumb File ath : " + thumbFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, thumbUrl, thumbFile.getAbsolutePath(), messenger);
File normal = new File(assetDirectory.getAbsolutePath(), "/Normal");
normal.mkdirs();
// Normal
File normalFile = new File(normal.getAbsolutePath(), "/Normal." + getExtention(normalUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Normal File path: " + normalFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, normalUrl, normalFile.getAbsolutePath(), messenger);
}
} else if (assetType.equals("2")) { // Video
File assetDirectory = createAssetDirectory(showId, showname, data, assetID, assetType);
if (assetDirectory != null) {
if (!fileType.equals("Youtube")) { // via AddLink
File thumb = new File(assetDirectory.getAbsolutePath(), "/Thumb");
thumb.mkdirs();
// Thumbnail
File thumbFile = new File(thumb.getAbsolutePath(), "/Thumb." + getExtention(thumbUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Thumb File ath : " + thumbFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, thumbUrl, thumbFile.getAbsolutePath(), messenger);
File mp4url = new File(assetDirectory.getAbsolutePath(), "/Normal");
mp4url.mkdirs();
// mp4_Url
File mp4File = new File(mp4url.getAbsolutePath(), "/Normal." + getExtention(mp4Url));
if (Constants.DEBUG) {
Log.d(TAG, "Normal File path: " + mp4File.getAbsolutePath());
}
isDownloaded = doInBackground(this, mp4Url, mp4File.getAbsolutePath(), messenger);
} else if (Constants.DEBUG) {
Log.d(TAG, "Asset type is video but is Youtube link. So not proceeding for offline");
}
}
} else if (assetType.equals("3")) { // Audio
File assetDirectory = createAssetDirectory(showId, showname, data, assetID, assetType);
if (assetDirectory != null) {
File thumb = new File(assetDirectory.getAbsolutePath(), "/Thumb");
thumb.mkdirs();
// Thumbnail
File thumbFile = new File(thumb.getAbsolutePath(), "/Thumb." + getExtention(thumbUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Thumb File ath : " + thumbFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, thumbUrl, thumbFile.getAbsolutePath(), messenger);
File normal = new File(assetDirectory.getAbsolutePath(), "/Normal");
normal.mkdirs();
// Normal
File normalFile = new File(normal.getAbsolutePath(), "/Normal." + getExtention(normalUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Normal File path: " + normalFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, normalUrl, normalFile.getAbsolutePath(), messenger);
}
} else {
if (!assetType.equals("5")) {
File assetDirectory = createAssetDirectory(showId, showname, data, assetID, assetType);
if (assetDirectory != null) {
File thumb = new File(assetDirectory.getAbsolutePath(), "/Thumb");
thumb.mkdirs();
// Thumbnail
File thumbFile = new File(thumb.getAbsolutePath(), "/Thumb." + getExtention(thumbUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Thumb File ath : " + thumbFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, thumbUrl, thumbFile.getAbsolutePath(), messenger);
File normal = new File(assetDirectory.getAbsolutePath(), "/Normal");
normal.mkdirs();
// Normal
File normalFile = new File(normal.getAbsolutePath(), "/Normal." + getExtention(normalUrl));
if (Constants.DEBUG) {
Log.d(TAG, "Normal File path: " + normalFile.getAbsolutePath());
}
isDownloaded = doInBackground(this, normalUrl, normalFile.getAbsolutePath(), messenger);
} else { //"5" Link
if (Constants.DEBUG) {
Log.d(TAG, "This is Web Link");
}
isDownloaded = true;
}
}
}
}
}
private String getLoginFolders() {
// TODO Auto-generated method stub
File file = null;
int status = Constants.getSDCardStatus();
if (status == Constants.MOUNTED) {
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"/SOTC_OFF/.nomedia");
f.mkdirs();
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"/SOTC_OFF/" + sotcPref.getString("domain", "") + "/" + sotcPref.getString("user_id", ""));
file.mkdirs();
}
return file.getAbsolutePath();
}
private File createAssetDirectory(String showid, String showname,
String data, String assetID, String assetType) {
// TODO Auto-generated method stub
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 10 " + "createAssetDirectory");
}
File file = null;
int status = Constants.getSDCardStatus();
if (status == Constants.MOUNTED) {
if (DownloadAssets.TOTAL_ASSET_COUNT != 0) {
/**
* From to concept here is to avoid duplication of new
* offline shows when show is updated. So, we are here
* renaming previous offline show's folder name with
* updated asset count.
*/
boolean isRenameSuccess = false;
File f = new File(getLoginFolders());
if (!f.exists()) {
f.mkdirs();
}
File[] fileArray = f.listFiles();
File f2 = new File(getLoginFolders(), "/"
+ showid.trim() + ","
+ showname.trim() + ","
+ data);
for (File from : fileArray) {
String s1 = from.getName().substring(0, from.getName().lastIndexOf(","));
if (Constants.DEBUG) {
Log.i(TAG, "s1: " + s1);
}
if (f2.getName().equalsIgnoreCase(s1)) {
//Rename
File to = new File(getLoginFolders(), "/"
+ showid.trim() + ","
+ showname.trim() + ","
+ data + ","
+ noofFiles);
if (Constants.DEBUG) {
Log.i(TAG, "from existence: " + from.exists());
}
try {
isRenameSuccess = from.renameTo(to);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (Constants.DEBUG) {
Log.i(TAG, "isRenameSuccess: " + isRenameSuccess);
}
break;
}
}
file = new File(getLoginFolders(), "/"
+ showid.trim() + ","
+ showname.trim() + ","
+ data + ","
+ noofFiles +
"/File_"
+ assetID + ","
+ assetType.trim());
}
if (file != null) {
if (!file.exists()) {
file.mkdirs();
}
}
}
return file;
}
public static String getExtention(String url) {
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
return extension;
}
@SuppressWarnings({"deprecation", "deprecation"})
boolean doInBackground(Context context, String urlPath, String destinationPath, Messenger messenger) {
boolean isDownloaded = false;
int lastPercent = 0;
File destination = new File(destinationPath);
if (!destination.exists()) {
if (chkConnectionStatus()) {
InputStream stream = null;
FileOutputStream fos = null;
try {
URL imageUrl = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
stream = conn.getInputStream();
int contentLength = conn.getContentLength();
if (Constants.DEBUG) {
Log.i(TAG, "contentLength : " + contentLength);
}
if (contentLength == 0) {
result = DownloadService.NO_FILE;
destination.delete();
isDownloaded = false;
Toast.makeText(getApplicationContext(), getResources().getString(R.string.Text_NoFile), 1000).show();
} else if (contentLength > availablestorageOnExternalDir()) {
//No Space Available
result = DownloadService.LOW_SPACE;
destination.delete();
isDownloaded = false;
Toast.makeText(getApplicationContext(), getResources().getString(R.string.Text_NoSpaceShow), 1000).show();
} else {
fos = new FileOutputStream(destination.getPath());
long total = 0l;
final int buffer_size = 4 * 1024;
try {
byte[] bytes = new byte[buffer_size];
for (; ; ) {
int count = stream.read(bytes, 0, buffer_size);
if (count == -1) {
break;
}
fos.write(bytes, 0, count);
total += count;
int percent = (int) ((total * 100) / contentLength);
if (percent > lastPercent) {
notification.contentView.setProgressBar(R.id.progressBar1, 100, percent, false);
lastPercent = percent;
}
}
if (destination.length() < contentLength) {
result = DownloadService.PARTIALLY_DOWNLOADED;
destination.delete();
isDownloaded = false;
} else {
if (Constants.DEBUG) {
Log.e(TAG, "Sucessful downloaded-------------------------------------------------" + i++);
}
// Sucessful finished
//i++;
result = Activity.RESULT_OK;
isDownloaded = true;
}
} catch (Exception ex) {
}
}
conn.disconnect();
Message msg = Message.obtain();
msg.arg1 = result;
msg.obj = destination.getAbsolutePath();
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
if (Constants.DEBUG) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
if (Constants.DEBUG) {
Log.v(TAG, "Completed.............. ");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
/// no network connection
result = DownloadService.NETWORK_PROBLEM;
notification.setLatestEventInfo(context, "Please check your network connection", "", contentIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1, notification);
isDownloaded = true;
Message msg = Message.obtain();
msg.arg1 = result;
msg.obj = destination.getAbsolutePath();
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
if (Constants.DEBUG) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
}
} else {
result = DownloadService.ASSERT_EXISIT;
Message msg = Message.obtain();
msg.arg1 = result;
msg.obj = destination.getAbsolutePath();
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
if (Constants.DEBUG) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
isDownloaded = true;
}
return isDownloaded;
}
public long availablestorageOnExternalDir() //Get Available space(in Bytes)
{
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
long megAvailable = bytesAvailable / (1024 * 1024);
if (Constants.DEBUG) {
Log.e("", "Available MB : " + megAvailable);
}
if (Constants.DEBUG) {
Log.e("", "Available Bytes : " + bytesAvailable);
}
return bytesAvailable;
}
public boolean chkConnectionStatus() {
final android.net.NetworkInfo wifi =
connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile =
connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable()) {
if (wifi.isConnected()) {
return true;
}
return false;
} else if (mobile.isAvailable()) {
if (mobile.isConnected()) {
return true;
}
return false;
} else {
return false;
}
}
}
DownloadAssets.java
//To download
//files into
//created folders
public class DownloadAssets {
private static final String TAG = "DownloadAssets";
public static int TOTAL_ASSET_COUNT;
static synchronized ArrayList<HashMap<String, String>> hit(Context context, String url) {
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 9 " + "hit url" + url);
}
ArrayList<HashMap<String, String>> mList = new ArrayList<HashMap<String, String>>();
String message = null;
String result = null;
try {
result = Constants.queryRESTurl(url);
if (result != null) {
if (result.equals("timeout")) {
message = context.getResources().getString(R.string.Text_TimeOut);
} else {
JSONObject json = Constants.convertStringtoJsonObject(result);
try {
JSONObject results = json.getJSONObject(ThumbnailFragment.JSON_RESPONSE_ATTR_RESULTSET);
String totalAssetCount = results.getString(ThumbnailFragment.JSON_RESPONSE_ATTR_ASSET_COUNT);
TOTAL_ASSET_COUNT = Integer.parseInt(totalAssetCount);
if (Constants.DEBUG) {
Log.i("5" + TAG, "totalAssetCount : " + totalAssetCount);
}
if (TOTAL_ASSET_COUNT != 0) {
JSONArray assetData = results.getJSONArray(ThumbnailFragment.JSON_RESPONSE_ATTR_ASSET_ARRAY);
if (Constants.DEBUG) {
Log.i(TAG, "6Madhu " + assetData.toString());
}
int nObjects = assetData.length();
if (Constants.DEBUG) {
Log.i(TAG, "7Madhu " + nObjects);
}
if (nObjects != 0) {
for (int i = 0; i < nObjects; i++) {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = assetData.getJSONObject(i);
map.put("id", "" + e.getString("assets_id"));
map.put("asset_name", "" + e.getString("asset_name"));
map.put("thumb_url", "" + e.getString("thumb_url"));
map.put("asset_type", "" + e.getString("asset_type"));
map.put("large_url", "" + e.getString("large_url"));
map.put("mp4_url", "" + e.getString("mp4_url"));
map.put("normal_url", "" + e.getString("normal_url"));
map.put("description", "" + e.getString("description"));
map.put("filetype", "" + e.getString("filetype"));
map.put("filename", "" + e.getString("original_filename"));
map.put("filesize", "" + e.getString("filesize"));
mList.add(map);
if (Constants.DEBUG) {
Log.i(TAG, "Size in Loop " + mList.size());
}
}
} else if (Constants.DEBUG) {
Log.i(TAG, "EXECUTING ELSE nObjects");
}
} else if (Constants.DEBUG) {
Log.i(TAG, "EXECUTING ELSE count");
}
} catch (JSONException e) {
if (Constants.DEBUG) {
Log.e("8log_tag", "Error parsing data " + e.toString());
}
message = context.getResources().getString(R.string.Text_InvalidResponse);
} catch (Exception e) {
if (Constants.DEBUG) {
Log.e("8log_tag", "Error parsing data " + e.toString());
}
message = context.getResources().getString(R.string.Text_InvalidResponse);
e.printStackTrace();
}
}
} else {
if (Constants.DEBUG) {
Log.i(TAG, "EXECUTING ELSE result");
}
message = context.getResources().getString(R.string.Text_InvalidResponse);
}
} catch (Exception e) {
// TODO Auto-generated catch block
message = context.getResources().getString(R.string.Text_ServerProblem);
e.printStackTrace();
}
if (Constants.DEBUG) {
Log.e(TAG, "Message : " + message);
}
if (Constants.DEBUG) {
Log.d(TAG, "Offline step 9 End " + "hit return " + mList);
}
return mList;
}
}
我的疑问是 文件正在下载但不是所有文件第一次从服务器。如果我下载更多文件夹,例如Folder1,Folder2然后Folder3,Folder1和Folder2中断(即1个文件被下载)但Folder3完全下载... 如何保存要下载的文件/文件夹队列? !
答案 0 :(得分:0)
为了加快和维护意图队列,请遵循以下方法
protected void onHandleIntent(Intent intent) {
synchronized (intent) {
final Intent intentCpy=intent;
new Thread(new Runnable() {
@Override
public void run() {
//onHandleIntent code which is in question post
}
}
}
在以下方法中使用ConcurrentHashMap for Thread-Safty
private synchronized void downloadSetofAssets(int OFFSET , int LIMIT , String url)
有关ConcurrentHashMap的更多详细信息,请访问 http://www.cs.umd.edu/class/spring2013/cmsc433/Notes/14-CMSC433-ConcurrentCollections.pdf