دانلود یک فایل از یک آدرس اینترنتی (یک URL) و نمایش میزان پیشرفت (با ProgressDialog) ، در برنامه نوسی اندروید
در زیر، کدهای یک activity را نوشته ایم که دارای نام MainActivity بوده (می توانید نام آن را تغییر بدهید) و برای دانلود یک فایل از یک آدرس اینترنتی و ذخیره آن در حافظه خارجی (external storage) به کار می رود :
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.widget.Toast;
public class MainActivity extends Activity {
public ProgressDialog mProgressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(MainActivity.this); // MainActivity = activity name
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(MainActivity.this); // MainActivity = activity name
downloadTask.execute("http://www.kelidestan.com/file.apk"); // the url to the file you want to download
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadTask(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... sUrl) {
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wl.acquire();
try {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/myFile.apk"); // /sdcard/file_name.extension
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled())
return null;
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
}
catch (IOException ignored) { }
if (connection != null)
connection.disconnect();
}
} finally {
wl.release();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(String result) {
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
}
}
}
در کدهای بالا، نام package پروژه اندروید، در اولین خط نوشته شده که باید آن را بر اساس پروژه اندروید خود تغییر بدهید. همچنین هنگام تغییر نام Activity ، دقت کنید که نام Activity در چند جای کدها نوشته شده و باید همگی آنها را تغییر بدهید.
در کد بالا، برای مسیر و نام فایلی که باید در حافظه خارجی (external storage) ذخیره شود، این مسیر و نام را تعیین کرده ایم :
که باعث می شود فایلی با نام myFile.apk در فولدر اصلی گوشی ساخته شود. در صورت تمایل می توانید نام فایل را تغییر بدهید یا در فولدر اصلی گوشی، یک فولدر ساخته و سپس مسیر آن فولدر را به مسیر اضافه کنید (ساخت فولدر با کدنویسی امکان پذیر است، در مبحثی دیگر در سایت کلیدستان، آن را شرح داده ایم).
در کدها، آدرس فایلی که باید دانلود شود را به صورت زیر تعیین کرده ایم (این آدرس، یک آدرس فرضی است و باید آن را به آدرس اینترنتی مورد نظر خود تغییر بدهید) :
دقت شود که باید کدهای زیر به کدهای فایل AndroidManifest.xml پروژه اندروید افزوده شود (چند اجازه که باید به پروژه اندروید بدهیم) :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
در برخی از گوشی ها، شیوه آدرس دهی زیر باعث بروز خطا می شود (به دلیل شیوه آدرس دهی به فولدر اصلی حافظه خارجی) :
بنابراین توصیه می شود که به جای خط بالا از کدها، کد زیر را بنویسید :
output = new FileOutputStream(root.getAbsolutePath() + "/myFile.apk");
بعد از این تغییر، کلیدهای Ctrl و Shift و O (حرف او) از کیبورد را به صورت همزمان بزنید تا package های مورد نیاز import شوند.
سلام.کد ها رو نوشتم پرمیشن ها رو هم دادم اما ارور میده دانلود نمیشه.یه توست میاد میگه:
permission denied
لطفا کمک کنید
سلام زمانیکه دانلود شد میخوام نصبش کنم ینی پس از دانلود مرحله اول نصب شروع بشه
بایستی چه کدی بزنم؟
سلام.
اگر منظورتان نصب فایل apk است، کلید زیر را بخوانید :
البته صرفا صفحه نصب به کاربر نمایش داده می شود و خود کاربر باید آن را نصب کند.
عالی
عالییییییییییییییییییییییییی, ممنون
با سلام و تشکر از سایت خوبتون
میشه از این کدها برای یک video view استفاده کرد؟
خود شما کدها رو از کجا کپی کردید
("output = new FileOutputStream("sdcard/test.jpg
فایل دانلود میشه اما وقتی میخوام برم تو پوشه خودش چیزی رو نمیتونه نمایش بده.اون قسمت test.jpgرو همنام urlفایلم قرار دادم جواب نداد هر اسم دیگه ای هم گذاشتم نشد.
یکی از دوستان لطف کنه زودتر جواب بده خیلی بهش نیاز دارم
سلام من در محیط کاری اندروید استدیو این کار کردم کد نوشتم اما نشد همش خطا میگرفت حتی مجوز دسترسی محل ذخیره دادم اما همش به آدرس ارور میگرفت