آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

آموزش ساخت دانلودر (به روش دانلود از طریق دانلود منیجر اندروید)

Hajhosseini  9 سال پیش  6 سال پیش
+58 0

قابلیت ها:
-فعال یا غیر فعال کردن نوتیفیکیشن.
-ست کردن Title برای نوتیفیکیشن (اگر ست نکنید زمان باقی مانده از دانلود رو میزنه).
-ست کردن Description برای نوتیفیکیشن.
-ست کردن نام فایل خروجی(باید با پسوند باشد).
-ست کردن نوع فایل خروجی. 
-OnDownloadCompleteListener
-OnDownloadProgressListener
توضیحات: چند پارامتر ورودی در کانستراکتور وجود دارد، دلیل وجود این پارامترها، الزام وجود آنهاست. (مثلا url حتما باید پرشده باشه و امکان خالی گذاشتنش نباید وجود داشته باشه)
سورس:

  package helper;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;

/**
 * Created by Hajhosseini on 10/31/2015.
 */
public class DownloadManagerHelper extends AsyncTask {
    private Activity activity;
    private String url;
    private String downloadPath;
    private String fileName;
    private String requestType;

    public DownloadManagerHelper(Activity _activity,String _url,String _downloadPath){
        activity = _activity;
        downloadPath = _downloadPath;
        url = _url;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if(fileName == null)
            fileName = getFileName(url);
    }

    @Override
    protected Object doInBackground(Object[] params) {
        downloadFile();
        return null;
    }

    @Override
    protected void onPostExecute(Object object) {
        super.onPostExecute(object);
        if (downloadCompleteListener != null)
        downloadCompleteListener.onDownloadComplete();
    }

    private void downloadFile() {
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        request.setDescription(notificationTitle);
        request.setTitle(notificationDescription);
        if(requestType != null && !requestType.equals(""))
            request.setMimeType(requestType);
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            request.allowScanningByMediaScanner();
            if (SHOW_NOTIFICATION_PROGRESS)
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
            else
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION);
        }
        request.setDestinationInExternalPublicDir(downloadPath, fileName);

        final DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
        final long downloadId = manager.enqueue(request);
        DownloadManager.Query q = new DownloadManager.Query();
        q.setFilterById(downloadId);


        boolean downloading = true;
        while (downloading) {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);

            Cursor cursor = manager.query(query);
            cursor.moveToFirst();
            int downloadedSize = cursor.getInt(cursor
                    .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
            int totalSize = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

            if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
                downloading = false;
            }
            final int percent = (int) (100.0f * (float) downloadedSize / totalSize);
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (downloadProgressListener != null)
                        downloadProgressListener.onDownloadProgressListener(percent);
                }
            });
            cursor.close();
        }
    }

    private DownloadProgressListener downloadProgressListener;
    private DownloadCompleteListener downloadCompleteListener;
    private boolean SHOW_NOTIFICATION_PROGRESS = false;
    private String notificationTitle = "";
    private String notificationDescription = "";

    public DownloadManagerHelper showNotificationProgress(){
        SHOW_NOTIFICATION_PROGRESS = true;
        return this;
    }
    public DownloadManagerHelper setDownloadFileName(String _fileName){
        fileName = _fileName;
        return this;
    }
    public DownloadManagerHelper setNotificationTitle(String _notificationTitle){
        notificationTitle = _notificationTitle;
        return this;
    }
    public DownloadManagerHelper setNotificationDescription(String _notificationDescription){
        notificationDescription = _notificationDescription;
        return this;
    }
    public interface DownloadCompleteListener{
        void onDownloadComplete();
    }
    public interface DownloadProgressListener{
        void onDownloadProgressListener(int percent);
    }

    public DownloadManagerHelper setDownloadProgressListener(DownloadProgressListener progressListener){
        downloadProgressListener = progressListener;
        return this;
    }
    public DownloadManagerHelper setDownloadCompleteListener(DownloadCompleteListener completeListener){
        downloadCompleteListener = completeListener;
        return this;
    }
    public DownloadManagerHelper setRequestType(String _requestType){
        requestType = _requestType;
        return this;
    }

    public void startDownload(){
        this.execute();
    }

    private String getFileName(String url){
        return (url.substring( url.lastIndexOf('/')+1, url.length()));
    }
}

طریقه استفاده:

 new DownloadManagerHelper(getActivity(),"http://orig15.deviantart.net/4eb3/f/2014/004/8/0/__i_m_so_pathetic____no_background__by_liamwhite1-d70v94v.png",Environment.DIRECTORY_DOWNLOADS)
                        .showNotificationProgress()
                        .setDownloadFileName("pony.jpg")
                        .setRequestType("image/JPG")
                        .setNotificationTitle("some title")
                        .setNotificationDescription("some desc")
                        .setDownloadCompleteListener(new DownloadManagerHelper.DownloadCompleteListener() {
                            @Override
                            public void onDownloadComplete() {
                                Toast.makeText(getActivity(),"DONE",Toast.LENGTH_LONG).show();
                            }
                        })
                        .setDownloadProgressListener(new DownloadManagerHelper.DownloadProgressListener() {
                            @Override
                            public void onDownloadProgressListener(int percent) {
                                Log.i("LOG","Percent is : "+percent);
                            }
                        })
                        .startDownload();
+1 0
سلام Hajhosseini جان ...یه سوال -> اگه از این دانلود منیجر استفاده کنم و در حین اینکه داره یه فایلی دانلود میشه کاربر اپلیکیشن رو به طور کامل ببنده چه اتفاقی برای اون دانلود میفته؟ برای اینکه مشکلی پیش نیاد باید از سرویس استفاده بشه درسته؟ (9 سال پیش)
+2 0
سلام، هیچ اتفاقی نمی افته. برنامه شما در هیچ قسمت دانلود دخیل نیست ولی امکان اینکه بعد از دانلود کاری انجام بشه وجود داره.(که در صورت لزوم باید به کدها اضافه بشه). جالب ترین قسمت این دانلودر اینه که حتی اگر شما گوشی رو ریست کنید، پس از بوت شدن گوشی، دانلود ادامه میده تا زمانی که تکمیل شه. تنها راه متوقف کردن دانلود اینه که به برنامه دانلود منیجر اندروید برید و cache رو پاک کنید. (9 سال پیش)
+3 0
یک اشکالی که دانلود منیجر گوگل داره (شاید هم حسن!) اینه که نمیشه در حین دانلود اون را کنسل کرد. فرض کنید اینترنت قطع بشه و یا اصلا کاربر تصمیم بگیره ادامه یک فایل را دریافت نکنه. اونوقت چکار باید کرد؟ من متاسفانه به نتیجه خاصی نرسیدم. (9 سال پیش)
0 0
حاج حسینی جان این دانلودر اگه در لیستنر کامل شدن دانلود دستور آپدیت دیتابیس بهش بدیم آیا بعد از بسته شدنه برنامه ی ما هم عمل میکنه یا حتما باید برنامه در حال اجرا باشه تا دستوراتی که به لیستنر هاش میدیم عمل کنن ؟ (8 سال پیش)
+1 0
اگر کانتکست مورد نظرتون توی مموری باشه، عملیات انجام میشه، اگر نباشه خیر. برای این کار باید از سرویس استفاده کنید. سرویس ها میتونن دائم فعال باشند و یا حتی در زمان دانلود فعال باشند و بعد از دانلود غیر فعال شوند. (8 سال پیش)
0 0
سلام . ممنونم از این آموزش خوب . من اینو درست کردم . روی شبیه ساز nox کار میکنه . روی گوشی کار نمیکنه . همه چی هم درسته . چطور ممکنه آخه ؟؟ (8 سال پیش)
0 0
سعید کاظمی. چون گوشی و سرور توی یه شبکه نیستن. گوشی و لپتاپ رو به یه وایفای وصل کن یا گوشیو هات اسپات کن و لپتاپو بهش وص کن. (8 سال پیش)
0 0
لینک من از یه سایته دیگس . منظورم اینه که لینک لوکال نیست (8 سال پیش)
0 0
سلام . من اینو توی Service دارم استفاده میکنم . چطوری اون پارامتر Activity رو پر کنم . من بهش G.activity دادم . ولی وقتی برنامه رو میبندم و سرویس همچنان در حال اجراس . میزنم چیزی دانلود کنه . کرش میکنه . خطا هم از اون پارامتر activity میگیره . چه کنم دوستان (8 سال پیش)
0 0
میشه جواب بدید . خیلی مهمه . چه کنم . مرسی (8 سال پیش)
0 0
شما توی سرویس یک کانتکس دارید. توی کلاس DownloadManagerHelper هرجا اکتیویتی دیدید بزنید کانتکست و پارامتر ورودی رو هم به کانتکست تبدیل کنید. از سرویستون کانتکست رو پاس بدید به کلاس. فقط برای اون قسمتی که نوشتم activity.runOnUiThread فکر کنم باید از Handler استفاده کنید. (8 سال پیش)
+1 0
میشه بگید چطوری از Handler استفاده کنم . مهم ترین قسمتش همون جایی هستش که نوشته activity.runOnUiThread . ممنون (8 سال پیش)
0 0
ببخشید می تونید از طریق سرویس هم این دانلودر رو آموزش بدید؟ در دانلودر من باید پس از دانلود به دیتابیس داده ای اضافه بشه ولی زمانی که از اپ خارج می شیم دانلود تمام می شود ولی هیچ داده ای اضافه نمی شود! (6 سال پیش)
 برای این سوال 7 پاسخ وجود دارد. مشاهده پاسخ صحیح
پاسخ به سوال 
Hajhosseini  9 سال پیش
+11 0

 پاسخ صحیح

به نکته خوبی اشاره کردید حامد جان. این قابلیت وجود داره و استفاده ازش بسیار راحته:

زمان ساخت دانلودر باید یک آیدی به اینستنس اون اختصاص بدیم:

 long id = downloadManager.enqueue(request);

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

 downloadManager.remove(id);

downloadManager همون اینستنسی هست که دانلود رو استارت کرده. پس شما باید اون دانلود منیجر رو نگه داری یا فقط یک دانلود منیجر توی برنامه داشته باشی که بتونی با آیدی های مختلف، دانلود ها رو مدیریت کنی.

+1 0
دوستان کسی هست درباره امکان توقف دانلود بیشتر توضیح بده فکر نکنم آقای حاج حسینی الان باشن ، این request از کجا باید بیارم ؟ (8 سال پیش)
+2 0
request داخل متد downloadFile تعریف شده دیگه یه بار برو کد رو بررسی کن ! (8 سال پیش)
0 0
من می خوام مثل دانلود منیجر ازش استفاده کنم یعنی چند تا دانلود داخل یک رسایکلرویو . این request داخل کلاس DownloadManagerHelper هست چطوری باید از داخل کلاسی دیگه دانلود مورد نظرمو حذف کنم و به manager.remove( id ربطش بدم ؟ (8 سال پیش)
+1 0
برای این کار شما باید یک instance از دانلود منیجر بسازی (به جای new کردن)، هر زمانی که میخوای یک فایل دانلود کنی یک id جدید براش ست کنی و هر زمانی که خواستی کنسل کنی، از همون instance از دانلود منیجر، متد remove رو کال کنی. برای این کار میتونید یک کلاس مانند app - application یا G داشته باشید که دانلود منیجر توی اون ساخته میشه، ولی تفاوت اینجاست که شما باید یک constructor جدید برای دانلود منیجر تعریف کنید، و در زمانی که میخواید دانلود رو استارد کنید، اول کانتکست و آدرس و ... رو به کلاس ارسال کنید و بعد استارت زده بشه. (8 سال پیش)
0 0
تا اینجاشو پیش رفتم که تونستم download Id شو بگیرم و دانلودشو متوقف کنم اما بعد از کنسل کردنه دانلود وقتی دوباره روی دکمه دانلود میزنم دیگه دانلود نمیشه ، این چطوری حلش کنم حاج حسینی جان توی دانلودر های دیگه معمولا متدی به اسم release هست که کلا داده های مربوط به اون download id رو پاک میکنه اینجا باید چطور این کارو بکنم ؟ (8 سال پیش)
0 0
با استفاده از دیتابیس download id شونو ذخیره میکنم و بعد با استفاده از شرط برار بودنه آیدی آیتم مورد نظر download id شو میکشم بیرون آیا بازم نیاز به instance هست ؟ (8 سال پیش)
+1 0
خیر نیازی نیست، میتونید از یک DownloadManager دیگه استفاده کنید. (8 سال پیش)
+1 0
DownloadManager manager = (DownloadManager) MainActivity.this.getSystemService(Context.DOWNLOAD_SERVICE); manager.remove(id); (8 سال پیش)
+1 0
برای سوال اولتون، به نظرم اگر دنبال قابلیت های خاص مثل resume,pause, دانلود در فولدر cache و ... هستید، استفاده از این دانلود منیجر خیلی کمکتون نمیکنه. این دانلود منیجر 2 قابلیت منحصر به فرد داره. 1 اینکه کاربر نمیتونه کنسلش کنه اگر شما نخواید(حتی با بستن اپلیکیشن و یا حتی پاک کردنش)، 2 اینکه تنها راه دانلود فایل های حجم بالا همینه. شما میتونید چند دانلود منیجر داشته باشید، و هر زمان که این 2 قابلیت رو میخواستید از این استفاده کنید، و زمانی که قابلیت های دیگه رو میخواستید از کتابخانه های دیگتون استفاده کنید. (8 سال پیش)
+1 0
مرسی از راهنماییتون حاج حسینی عزیز (8 سال پیش)
پاسخ به سوال 
alisherafat01  9 سال پیش
+1 0

سلام من دو تا سوال دارم : 

1- من وقتی روی Environment.DIRECTORY_DOWNLOADS ذخیره میکنم همه چی درست کار میکنه ولی نمیدونم چرا فایل ها رو توی دایرکتوری های sd card نمیریزه!!!       

این مسیر دایرکتوری منه که ساخته شده از قبل :

 Environment.getExternalStorageDirectory().getAbsolutePath()+"/folder"

permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2- اگه یه آدرس url اشتباه بهش بدیم تا ابد میره تلاش میکنه و بی نتیجه می مونه!!!  

چجوری میشه متد timeOut  براش پیاده سازی کرد؟

+1 0
جواب سوال اول رو فهمیدم : Environment.getExternalStorageDirectory().getAbsolutePath رو دیگه نباید بزاریم!! ولی همچنان جوابی برای سوال دو پیدا نکردم (9 سال پیش)
+2 0
برای سوال دوم 2-3 راه وجود داره.1: چون دانلود منیجر timeout نداره، باید خودمون دستی بنویسیم. 2: آدرس رو ping کنیم و بعد دانلود رو شروع کنید. 3: هر 3 ثانیه چک کنیم ببینیم درصد داره تغییر میکنه یا خیر. ممکنه راه های دیگه های هم باشه، ولی اصولیش همون اولیه، بعد روش دوم رو پیشنهاد میکنم، بعد سومی. (9 سال پیش)
پاسخ به سوال 
mohsen-jj  8 سال پیش
+1 0

سلام ممنونم از کدهاتون خیلی مفید بود . چندتا سوال داشتم :

1 - دانلود ها فقط باید در پوشه download قرار بگیرند ؟ منظورم همون Environment.DIRECTORY_DOWNLOADS هست چون فقط تو این مسیر درست کار میکنه و وقتی مسیر خودم رو میدم خطا میده . همچنین وقتی میخوام از پوشه download فایل رو به مسیر خودم کپی کنم هم این کار انجام نمی شه .

2 - قابلیت resume در این دانلود منیجر وجود نداره ؟چون با دستور downloadmanager.remove(id)d که دانلود رو متوقف میکنم بعد دوباره دانلود رو شروع میکنم ، فایل از اول شروع به دانلود می شه .

0 0
سلام ... جواب سوال اولتون یه وجب بالا تر نوشته شده D: (8 سال پیش)
0 0
سلام . بله ممنون از یاداوری تون :)) (8 سال پیش)
+2 0
سلام، این دانلود منیجر خودش قابلیت auto resume داره، شما اگر اینترنت رو قطع و وصل کنید خودش ادامه میده. (8 سال پیش)
پاسخ به سوال 
Hajhosseini  8 سال پیش
+1 0

طریقه استفاده از Handler:
کد زیر رو میتونید توی کلاس App - Application یا G تعریف کنید.

 public static final Handler HANDLER = new Handler();

اگر فقط یک جا استفاده میکنید، نیازی نیست static final رو بنویسید، ولی اگر چند جا استفاده میکنید میتونه استاتیک باشه.
و همچنین اگر static final نمیذارید میتونید توی کلاس دانلودر تعریفش کنید.
حالا کد زیر رو

 activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (downloadProgressListener != null)
                    downloadProgressListener.onDownloadProgressListener(percent);
            }
        });

به کد زیر تغییر بدید 

 HANDLER.post(new Runnable() {
            @Override
            public void run() {
                if (downloadProgressListener != null)
                    downloadProgressListener.onDownloadProgressListener(percent);
            }
        });

با توجه به اینکه AsyncTask خودش یک متد refresh داره که روی Main Thread اجرا میشه، بهتر بود که من از اون متد استفاده میکردم، ولی چون این کد خیلی قدیمیه و هیچ تفاوتی میان این 2 کد نیست، شما همینو تغییر بدید. 
توضیحات: توی با توجه به اینکه ما میخوایم در هنگام دانلود فایل، اپلیکیشن Freez نشه و کاربر بتونه کارهای دیگه هم انجام بده، باید از Worker Thread ها استفاده کنیم، مشکل زمانی به وجود میاد که شما میخواید درصد دانلود رو روی صفحه نمایش بدید، در این قسمت نیازه که این عملیات بر روی Main Thread انجام بشه(کد بالا)، به همین منظور از Handler یا UiThread که همون Main Thread هست استفاده میکنیم.

+1 0
خیلی ممنونم . تست کنم . خبر میدم . خیلی لطف کردی داداش (8 سال پیش)
+1 0
درست شد / دستت درد نکنه / خدا خیرت بده داداش (8 سال پیش)
0 0
توی کلاس روی handler که میزارم ارور میده و برنامه از کار میفته... شما گفتید اگر میخواید روی صفحه پروگرس رو نشون بدیم باید از main thread ها یا همون handler استفاده کنیم درسته ؟ خوب منم همین کارو ک کردم برنامه خارج میشه ولی اون بالا ناتیفیکیشن بار کار میکنه... (7 سال پیش)
پاسخ به سوال 
Shadow  7 سال پیش
+1 0

ببخشید اقای حاج حسینی من از یه customCircle استفاده می کنم که میزان درصد دانلود رو نمایش میده میشه این کلاس دانلود رو کاری کرد که از 0 تا 100 رو بشماره نه یهو یه حجمی رو دانلود کنه چون اینجوری این ویوو سفارشی یهو پر میشه و زیاد جالب نیست

+1 0
از onDownloadProgressListener استفاده کنید. این قابلیت در حال حاضر در دانلودر وجود داره (7 سال پیش)
0 0
توی onprogressdownloadlistener میزارم و پروگرس رو هم نشون میده ولی همون حالتی که دوستمون گقت یکدفه میره روی 50 درصد و یهو صد میشه .... ولی نسخه استاد باز خوبیش این بود که درصد رو نشون میداد دونه دونه... اینو با اون مقایسه کردم دیدم توی نحوه نوشتن روی sd تفاوت داره میشه راهنمایی کنی چطور باید درصد رو دونه دونه نشون بدیم (7 سال پیش)
پاسخ به سوال 
h_uk2009  7 سال پیش
0 0

برادر حاج حسینی عزیز... هنگ میکنه این دانلودر روی امولیتور ! بعد از چندین بار اجرا کردن برنامه متوجه شدم که کلا قاط میزنه... الان به هیچ وجه جلو نمیره کلا روی 8 تا دانلود مونده توی صف ... هرکاریم میکنم نمیره.... نه دانلود میکنه که بره ناتیفیکیشنش و نه دانلودهای جدید که میفرستم رو اجرا میکنه

پاسخ به سوال 
mosafer  7 سال پیش
0 0

با سلام خدمت همه دوستان گرامی

و تشکر از آقای حاج حسینی عزیز

آقای حاج حسینی من سوالی در این لینک کردم که البته خواستم که با کتابخانه Volley بشه ولی یه چیزی اضافه بر کدی هست که باید بذارم ولی نمیدونم چطور!

حالا میخوام از دانلودر شما استفاده کنم و اینکه چطور Authorization Basic رو به Header بفرستم تا بتونم دانلودم رو انجام بدم. و اینکه فایلهایی که میخوام از سرور بگیرم از همه نوع هست ینی همون File Mime Type. با این دانلودر میشه همه نوع فایل رو دان کرد؟

مهمترین مسئله من همون فرستادن Authorization Basic به Header هست که باید انجام بشه. آیا میشه با این کد این کارو کرد؟ اگر میشه به چه شکل؟!

ممنون میشم راهنمایی کنید و یه سری به لینکی که گفتم بزنید.

با تشکر فراوان

0 0
دوستان کسی نیست به من راهنمایی بده و بگه راه صحیح به چه شکلی هست؟ (7 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .