آموزش برنامه نویسی اندروید (Android)
۴۱۹ آموزش
نمایش دسته بندی ها (۴۱۹ آموزش)

دانلود یک فایل از یک آدرس اینترنتی (یک URL) و نمایش میزان پیشرفت (با ProgressDialog) ، در برنامه نوسی اندروید

در زیر، کدهای یک activity را نوشته ایم که دارای نام MainActivity بوده (می توانید نام آن را تغییر بدهید) و برای دانلود یک فایل از یک آدرس اینترنتی و ذخیره آن در حافظه خارجی (external storage) به کار می رود :


package com.kelidestan.download;

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) ذخیره شود، این مسیر و نام را تعیین کرده ایم :


/sdcard/myFile.apk

که باعث می شود فایلی با نام myFile.apk در فولدر اصلی گوشی ساخته شود. در صورت تمایل می توانید نام فایل را تغییر بدهید یا در فولدر اصلی گوشی، یک فولدر ساخته و سپس مسیر آن فولدر را به مسیر اضافه کنید (ساخت فولدر با کدنویسی امکان پذیر است، در مبحثی دیگر در سایت کلیدستان، آن را شرح داده ایم).

در کدها، آدرس فایلی که باید دانلود شود را به صورت زیر تعیین کرده ایم (این آدرس، یک آدرس فرضی است و باید آن را به آدرس اینترنتی مورد نظر خود تغییر بدهید) :


http://www.kelidestan.com/file.apk
نکته

دقت شود که باید کدهای زیر به کدهای فایل AndroidManifest.xml پروژه اندروید افزوده شود (چند اجازه که باید به پروژه اندروید بدهیم) :


<uses-permission android:name="android.permission.INTERNET" />
<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("/sdcard/myFile.apk");  //   /sdcard/file_name.extension

بنابراین توصیه می شود که به جای خط بالا از کدها، کد زیر را بنویسید :


File root = android.os.Environment.getExternalStorageDirectory();
output = new FileOutputStream(root.getAbsolutePath() + "/myFile.apk");

بعد از این تغییر، کلیدهای Ctrl و Shift و O (حرف او) از کیبورد را به صورت همزمان بزنید تا package های مورد نیاز import شوند.

نویسنده علیرضا گلمکانی
شماره کلید 296
گزینه ها
به اشتراک گذاری (Share) در شبکه های اجتماعی
نظرات 9 9 0
مهدی
۱۳۹۶/۰۴/۲۵
۱۴:۳۱

سلام.کد ها رو نوشتم پرمیشن ها رو هم دادم اما ارور میده دانلود نمیشه.یه توست میاد میگه:
permission denied
لطفا کمک کنید

jef313
۱۳۹۸/۰۱/۰۳
۱۶:۰۳

سلام زمانیکه دانلود شد میخوام نصبش کنم ینی پس از دانلود مرحله اول نصب شروع بشه
بایستی چه کدی بزنم؟

admin
۱۳۹۸/۰۱/۰۳
۱۹:۲۳

سلام.
اگر منظورتان نصب فایل apk است، کلید زیر را بخوانید :

کلید شماره 310

البته صرفا صفحه نصب به کاربر نمایش داده می شود و خود کاربر باید آن را نصب کند.

Flower

کریم
۱۳۹۸/۰۲/۱۹
۲۰:۴۶

عالی

goddess
۱۳۹۸/۰۲/۲۳
۱۹:۲۴

عالییییییییییییییییییییییییی, ممنون 

میثم
۱۳۹۸/۰۲/۲۶
۱۲:۴۱

با سلام و تشکر از سایت خوبتون
میشه از این کدها برای یک video view استفاده کرد؟

vahid91vara
۱۳۹۸/۰۴/۱۶
۱۱:۴۰

خود شما کدها رو از کجا کپی کردید Smile

kamizy
۱۳۹۸/۰۵/۲۷
۲۰:۵۵

("output = new FileOutputStream("sdcard/test.jpg
فایل دانلود میشه اما وقتی میخوام برم تو پوشه خودش چیزی رو نمیتونه نمایش بده.اون قسمت test.jpgرو همنام urlفایلم قرار دادم جواب نداد هر اسم دیگه ای هم گذاشتم نشد.
یکی از دوستان لطف کنه زودتر جواب بده خیلی بهش نیاز دارم

هتدی
۱۴۰۰/۰۴/۱۹
۱۴:۴۸

سلام من در محیط کاری اندروید استدیو این کار کردم کد نوشتم اما نشد همش خطا میگرفت حتی مجوز دسترسی محل ذخیره دادم اما همش به آدرس ارور میگرفت

ارسال نظر جدید (بدون نیاز به عضو بودن در وب سایت)