دانلود فایل در اندروید
دانلود کردن بعنوان یکی از مهمترین امکانات موجود در اپلیکیشن های اندرویدی ، با توجه به نقشی که این امر در جهت کارکرد مطلوب برنامه ها دارد ، می تواند وسیله ای مهم و تاثیرگذار محسوب شود. استفاده از این امکان ، در آپدیت کردن ورژن ها ، بروزرسانی محتوانی درونی برنامه ، و حتی در توسعه هر چه بیشتر برنامه همواره مورد توجه برنامه نویسان خلاق و پیشرفته بوده است. علی رغم وجود منابع وافر در این زمینه (در اینترنت)، متاسفانه ناآگاهی کاربران و نومیدی آنان در جستجوی منابع بیشتر ، منجر به اتلاف هزینه های بسیاری برای کاربران شده است. از این رو برآن شدیم که در این پست به آموزش این امر بپردازیم.
لازم است که بدانیم نداشتن اطلاعت کافی در این زمینه بخصوص در زمینه برنامه نویسی سوکت ، قدری موجب کند شدن سرعت یادگیری ما خواهد شد اگر در این زمینه از اطلاعات کافی برخوردار نیستید اینجا کلیک کنید. یادتان باشد تا حد ممکن از کپی کردن کدها خودداری کنید و همزمان با یادگیری مفاهیم اساسی در این زمینه ، از حداکثر حافظه خود بهره ببرید.
در این مثال ما فرایند این کار را (یعنی دانلود کردن ) را با استفاده از progress bar برای شما آموزش خواهیم داد.
اگر در داخل برنامه اکلیپس یا اندروید استودیو قرار دارید پروژه جدیدی را ایجاد کنید
اکلیپس :File ⇒ New Android ⇒ Application Project
اندروید استودیو :File ⇒ New ⇒ New Project
اما اگر هنوز برنامه خود را باز نکرده اید یکی از برنامه های فوق را باز نموده و بعد از تعیین مشخصات(نامگذاری) ، تعیین حداقل sdk و نوع اکتیویتی (blank یا Empty) ، نام اکتیویتی ابتدایی و اصلی خود را همان MainActivity قرار دهید. بعد از لود کامل برنامه ، در مسیر res ⇒layout لایه متناظر اکتیوتی اصلی یعنی activity_main را پیدا نمود و کدهای مندرج و پیش فرض آن را پاک کرده و کدهای xml زیر را به آن اضافه کنید:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- Download Button --> <ImageView android:id="@+id/Showimage" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/btnDownload" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="Download " android:layout_gravity="center_horizontal" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="202dp" /> </RelativeLayout>
حال در کلاس MainActivity ابتدا کلاس های مورد نیاز را import کرده و سپس با تعریف کلاس و Extend آن به نوع Activity ، ضمن تعریف لایوت متناظر درSetcontentView(R.layou.activity_main) ،کلاس Download را با OnClickListener کردن باتن تعبیه شده در لایوت و تعریف شده در کلاس فراخوانی می کنیم.
public class MainActivity extends Activity { private ProgressDialog pDialog; public static final int progress_bar_type = 0; private String file_url = "http://psrd.ir/wp-content/uploads/2017/06/imagedownload.jpg"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // show progress bar button Button btnDownload = (Button) findViewById(R.id.btnDownload); // Image view to show image after downloading btnDownload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // starting new Async Task new Download().execute(file_url); } }); } protected Dialog onCreateDialog(int id) { switch (id) { case progress_bar_type: // we set this to 0 pDialog = new ProgressDialog(this); pDialog.setMessage("Downloading file. Please wait..."); pDialog.setIndeterminate(false); pDialog.setMax(100); pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pDialog.setCancelable(true); pDialog.show(); return pDialog; default: return null; } }
به دنبال نوشتن کدهای فوق در کلاس MainActivity ، خواهیم دهید که کلاس نوشته شده در متد OnClick به شکل قرمز رنگ(نشانه خطا) درخواهد آمد. باhighlight کردن بر روی آن و فشردن همزمان دکمه های Alt و Enter ، خواهیم دید آپشن هایی بنام create class ‘Download و create inner class ‘Download ظاهر خواهد شد که با کلیک بر روی دومین آن یعنی ایجاد کلاس درونی(در صورت کلیک بر روی اولین آیتم اشاره شده ، کلاسی خارج از کلاس MainActivity ایجاد خواهد شد ) ، کلاسی با نام Download به شکل زیر در پایین صفحه ظاهر خواهد شد.
private class Download { }
اما چون در کلاس مورد اشاره و فراخوانده شده در باتن ، که به شکل زیر می باشد
new Download().execute(file_url);
کلاس فراخوانده شده را با asynctask تعریف کرده (execute از متدهای asynctask می باشد)از این رو لازم است متدهای آن نیز باید implement گردد . در این کلاس asynctask دارای سه متد به شرح زیر می باشد که در
1- doInBackground
در این متد همانطور که از نامش پیداست عملیات اصلی یعنی فرایند خواندن آدرس(Url) ، کانکت شدن به آن ، تعیین حجم بافر، inputStream کردن از سرور و outputStream کردن در لوکیشن تعیین شده در دیوایس، تبدیل به رشته های بیتی و بستن دو نوع استریم در پشت زمینه انجام می شود.
2- onProgressUpdate
در این مرحله همانطور که از نامش پیداست در حین انجام فرایند فوق ، عملیات مشخصی در برنامه بروز پیدا می کند که نشانگر تداوم وضعیت فوق است. در این مثال نیز progress bar به کاربر نشان داده می شود که در آن میزان پیشرفت دانلود را نشان می دهد .
3-onPostExecute
این مرحله نیز از زمان اتمام عملیات اصلی شروع می شود . یعنی برنامه نویس در این متد تعیین می کند که بعد از عملیات اصلی که در این مثال دانلود عکس از سرور است چه واکنشی از طرف برنامه صادر شود. که در این مثال نشان دادن عکس در imageView می باشد.
بنابراین کلاس درونی ما به شکل زیر خواهد بود.
class Download extends AsyncTask<String, String, String> { /** * Before starting background thread * Show Progress Bar Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); showDialog(progress_bar_type); } /** * Downloading file in background thread * */ @Override protected String doInBackground(String... f_url) { int count; try { URL url = new URL(f_url[0]); URLConnection conection = url.openConnection(); conection.connect(); // getting file length int lenghtOfFile = conection.getContentLength(); // input stream to read file - with 8k buffer InputStream input = new BufferedInputStream(url.openStream(), 8192); // Output stream to write file OutputStream output = new FileOutputStream("/sdcard/imagedownload.jpg"); byte data[] = new byte[1024]; long total = 0; while ((count = input.read(data)) != -1) { total += count; // publishing the progress.... // After this onProgressUpdate will be called publishProgress(""+(int)((total*100)/lenghtOfFile)); // writing data to file output.write(data, 0, count); } // flushing output output.flush(); // closing streams output.close(); input.close(); } catch (Exception e) { Log.e("Error: ", e.getMessage()); } return null; } /** * Updating progress bar * */ protected void onProgressUpdate(String... progress) { // setting progress percentage pDialog.setProgress(Integer.parseInt(progress[0])); } /** * After completing background task * Dismiss the progress dialog * **/ @Override protected void onPostExecute(String file_url) { // dismiss the dialog after the file was downloaded dismissDialog(progress_bar_type); // Displaying downloaded image into image view // Reading image path from sdcard String imagePath = Environment.getExternalStorageDirectory().toString()+"/imagedownload.jpg"; // setting downloaded into image view displayimage.setImageDrawable(Drawable.createFromPath(imagePath)); } } }
کدهای ادغام شده و نهایی ما به شکل زیر خواهد بود.
import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; public class MainActivity extends Activity { private ProgressDialog pDialog; public static final int progress_bar_type = 0; private String file_url = "http://psrd.ir/wp-content/uploads/2017/12/imagedownload.jpg"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnDownload = (Button) findViewById(R.id.btnDownload); btnDownload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Download().execute(file_url); } }); } protected Dialog onCreateDialog(int id) { switch (id) { case progress_bar_type: // we set this to 0 pDialog = new ProgressDialog(this); pDialog.setMessage("Downloading file. Please wait..."); pDialog.setIndeterminate(false); pDialog.setMax(100); pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pDialog.setCancelable(true); pDialog.show(); return pDialog; default: return null; } } class Download extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); showDialog(progress_bar_type); } @Override protected String doInBackground(String... f_url) { int count; try { URL url = new URL(f_url[0]); URLConnection conection = url.openConnection(); conection.connect(); int lenghtOfFile = conection.getContentLength(); InputStream input = new BufferedInputStream(url.openStream(), 8192); OutputStream output = new FileOutputStream("mnt/sdcard/imagedownload.jpg"); byte data[] = new byte[1024]; long total = 0; while ((count = input.read(data)) != -1) { total += count; publishProgress(""+(int)((total*100)/lenghtOfFile)); output.write(data, 0, count); } output.flush(); output.close(); input.close(); } catch (Exception e) { Log.e("Error: ", e.getMessage()); } return null; } protected void onProgressUpdate(String... progress) { pDialog.setProgress(Integer.parseInt(progress[0])); } @Override protected void onPostExecute(String file_url) { final ImageView displayimage = (ImageView) findViewById(R.id.Showimage); dismissDialog(progress_bar_type); String imagePath = Environment.getExternalStorageDirectory().toString() + "/imagedownload.jpg"; displayimage.setImageDrawable(Drawable.createFromPath(imagePath)); } } }
ودر آخر به سراغ فایل Androidmanifest.xml می رویم و با افزودن مجوز دسترسی به اینترنت و رایت کردن به حافظه خارجی به به شکل زیر :
<uses-permission android:name="android.permission.INTERNET"> </uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission>
مجوز دسترسی اپلیکیشن به اینترنت و رایت فایل دانلود شده به حافظه خارجی را تعریف می کنیم. در نهایت کدهای AndroidManifest.xml را به شکل زیر تنظیم می کنیم. توجه داشته باشد که در صورت کپی کردن کدها نام پکیج خودرا با پکیج ارائه شده در مثال مقایسه کنید و پکیج پروژه خود را در آن لحاظ کنید.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.site.psrd.downloadandroid"> <uses-permission android:name="android.permission.INTERNET"> </uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
حال پروژه را اجرا کرده و از آن در آموزش هر چه بیشتر خود استفاده کنید. اگر مشکلی در اجرای کدها وجود دارد یا سوال مشخصی از نویسنده سایت دارید سوالات خود را در قسمت دیدگاه ها بیان کنید.
کپی برداری از محتوای سایت psrd، ممنوع بوده و پیگرد قانونی دارد. (تنها استفاده شخصی کاربران ، مجاز است) (کپی برداری توسط سایر وب سایت ها غیرقانونی بوده و در صورت رویت به ستادسازماندهی اطلاع داده خواهد شد.
منبع اصلی این مقاله :
http://www.androidhive.info/2012/04/android-downloading-file-by-showing-progress-bar/
0 دیدگاه