Nevercom
دوشنبه 29 آبان 1391, 22:09 عصر
سلام دوستان
من در یکی از اکتویتی های برنامه یک فایل XML رو Parse میکنم و لیست پکیج های موجود برای دانلود رو در یک ListView نمایش میدم، کنار هر آیتم یه CheckBox هست که کاربر میتونه انتخاب کنه کدوم پکیج ها دانلود بشن.
چندتا سوال در این زمینه دارم.
از چه روشی برای دانلود چند فایل استفاده کنم که برای API 7 هم جواب بده ؟
آیا کلاسی رو میشناسید که بتونه بصورت مطمئن دانلود فایل ها رو مدیریت کنه ؟
خودم تصمیم دارم از این کلاس استفاده کنم، اما در مورد کاراییش و اینکه فایل ها رو درست دانلود کنه (با توجه به حجیم بودن بعضی از پکیج ها و سرعت نه چندان مناسب اینترنت اپراتورهای موبایل):
package org.test.download;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.ProgressBar;
public class DownloadService extends Service {
String downloadUrl;
LocalBroadcastManager mLocalBroadcastManager;
ProgressBar progressBar;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/org.test.download/");
double fileSize = 0;
DownloadAsyncTask dat;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
public DownloadService(String url,Context c, ProgressBar pBar){
downloadUrl = url;
mLocalBroadcastManager = LocalBroadcastManager.getInstance(c);
progressBar = pBar;
dat = new DownloadAsyncTask();
dat.execute(new String[]{downloadUrl});
}
private boolean checkDirs(){
if(!dir.exists()){
return dir.mkdirs();
}
return true;
}
public void cancel(){
dat.cancel(true);
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, String>{
@Override
protected String doInBackground(String... params) {
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")+1);
if(!checkDirs()){
return "Making directories failed!";
}
try {
URL url = new URL(downloadUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
fileSize = urlConnection.getContentLength();
FileOutputStream fos = new FileOutputStream(new File(dir,fileName));
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[500];
int bufferLength = 0;
int percentage = 0;
double downloadedSize = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
if(isCancelled()){
break;
}
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
percentage = (int) ((downloadedSize / fileSize) * 100);
publishProgress(percentage);
}
fos.close();
urlConnection.disconnect();
} catch (Exception e) {
Log.e("Download Failed",e.getMessage());
}
if(isCancelled()){
return "Download cancelled!";
}
return "Download complete";
}
@Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values[0]);
if(progressBar != null){
progressBar.setProgress(values[0]);
}else{
Log.w("status", "ProgressBar is null, please supply one!");
}
}
@Override
protected void onPreExecute(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_STARTED"));
}
@Override
protected void onPostExecute(String str){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FINISHED"));
}
@Override
protected void onCancelled(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_CANCELLED"));
}
}
}
سوال بعد اینکه با فرض اینکه کاربر ۱۰ فایل برای دانلود انتخاب کرده، حالا راه درست برای دانلود چی هست (از لحاظ کد نویسی اصولی)، بهتره مثلاً لیست دانلود رو بصورت آرایه به کلاس پاس بدیم و اون عملیات دانلود فایل ها رو انجام بده ؟
چطور میشه به نحوی کلاس رو ویرایش کرد که خودش عملیات دانلود تعدادی فایل رو که بصورت آرایه بهش پاس دادیم مدیریت کنه ؟
و مورد بعد نحوه ی نمایش درصد پیشرفت هست. همین کلاس یک آرگومان میگیره که شئ ProgressBarی هست که درصد پیشرفت براش ارسال میشه.
ایده آل ی که دنبالشم چیزی شبیه به مدیریت دانلود برنامه ی بازار هست، رو همه ی ورژن ها ی اندروید جواب میده، اکتیویتی درصد پیشرفت خوب طراحی شده و در حین دانلود میشه از کاربرد های دیگه ی برنامه استفاده کرد (همین کلاس هم چون در یک ترد جداگانه اجرا میشه نباید وابسته به اکتیویتی خاصی باشه) و درصد پیشرفت رو در Notification Bar نمایش میده.
ممنون میشم راهنماییم کنید.
من در یکی از اکتویتی های برنامه یک فایل XML رو Parse میکنم و لیست پکیج های موجود برای دانلود رو در یک ListView نمایش میدم، کنار هر آیتم یه CheckBox هست که کاربر میتونه انتخاب کنه کدوم پکیج ها دانلود بشن.
چندتا سوال در این زمینه دارم.
از چه روشی برای دانلود چند فایل استفاده کنم که برای API 7 هم جواب بده ؟
آیا کلاسی رو میشناسید که بتونه بصورت مطمئن دانلود فایل ها رو مدیریت کنه ؟
خودم تصمیم دارم از این کلاس استفاده کنم، اما در مورد کاراییش و اینکه فایل ها رو درست دانلود کنه (با توجه به حجیم بودن بعضی از پکیج ها و سرعت نه چندان مناسب اینترنت اپراتورهای موبایل):
package org.test.download;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.ProgressBar;
public class DownloadService extends Service {
String downloadUrl;
LocalBroadcastManager mLocalBroadcastManager;
ProgressBar progressBar;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/org.test.download/");
double fileSize = 0;
DownloadAsyncTask dat;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
public DownloadService(String url,Context c, ProgressBar pBar){
downloadUrl = url;
mLocalBroadcastManager = LocalBroadcastManager.getInstance(c);
progressBar = pBar;
dat = new DownloadAsyncTask();
dat.execute(new String[]{downloadUrl});
}
private boolean checkDirs(){
if(!dir.exists()){
return dir.mkdirs();
}
return true;
}
public void cancel(){
dat.cancel(true);
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, String>{
@Override
protected String doInBackground(String... params) {
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")+1);
if(!checkDirs()){
return "Making directories failed!";
}
try {
URL url = new URL(downloadUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
fileSize = urlConnection.getContentLength();
FileOutputStream fos = new FileOutputStream(new File(dir,fileName));
InputStream inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[500];
int bufferLength = 0;
int percentage = 0;
double downloadedSize = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
if(isCancelled()){
break;
}
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
percentage = (int) ((downloadedSize / fileSize) * 100);
publishProgress(percentage);
}
fos.close();
urlConnection.disconnect();
} catch (Exception e) {
Log.e("Download Failed",e.getMessage());
}
if(isCancelled()){
return "Download cancelled!";
}
return "Download complete";
}
@Override
protected void onProgressUpdate(Integer... values){
super.onProgressUpdate(values[0]);
if(progressBar != null){
progressBar.setProgress(values[0]);
}else{
Log.w("status", "ProgressBar is null, please supply one!");
}
}
@Override
protected void onPreExecute(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_STARTED"));
}
@Override
protected void onPostExecute(String str){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_FINISHED"));
}
@Override
protected void onCancelled(){
mLocalBroadcastManager.sendBroadcast(new Intent("org.test.download.DOWNLOAD_CANCELLED"));
}
}
}
سوال بعد اینکه با فرض اینکه کاربر ۱۰ فایل برای دانلود انتخاب کرده، حالا راه درست برای دانلود چی هست (از لحاظ کد نویسی اصولی)، بهتره مثلاً لیست دانلود رو بصورت آرایه به کلاس پاس بدیم و اون عملیات دانلود فایل ها رو انجام بده ؟
چطور میشه به نحوی کلاس رو ویرایش کرد که خودش عملیات دانلود تعدادی فایل رو که بصورت آرایه بهش پاس دادیم مدیریت کنه ؟
و مورد بعد نحوه ی نمایش درصد پیشرفت هست. همین کلاس یک آرگومان میگیره که شئ ProgressBarی هست که درصد پیشرفت براش ارسال میشه.
ایده آل ی که دنبالشم چیزی شبیه به مدیریت دانلود برنامه ی بازار هست، رو همه ی ورژن ها ی اندروید جواب میده، اکتیویتی درصد پیشرفت خوب طراحی شده و در حین دانلود میشه از کاربرد های دیگه ی برنامه استفاده کرد (همین کلاس هم چون در یک ترد جداگانه اجرا میشه نباید وابسته به اکتیویتی خاصی باشه) و درصد پیشرفت رو در Notification Bar نمایش میده.
ممنون میشم راهنماییم کنید.