بسم الله الرحمن الرحيم
في هذه التدوينة إن شاء الله سوف نتعلم كيفية تحميل ملف من الأنترنت لجهازك الأندرويد برمجياً, عن طريق برمجة تطبيقات الأندرويد.
وهذا الدرس سوف يتم تطبيق على المشروع السابق وهو :
في المشروع السابق يوجد الكود كامل مفتوح المصدر لكم, في كيفية بناء تطبيق لتشغيل الملفات الصوتية من السيرفر, وهذا الدرس في كيفية تحميل هذه الملفات لجهاز المستخدم.
إذا سوف تكون الأكواد تابعة للدرس السابق, ولكن تستطيع استخدامها بشكل منفصل بإي مشروع تريده في كيفية تحميل الملفات من السيرفر سواء كانت ملفات صوتية أو غيرها.
وكعادتي في اعطاء الدروس, اعطي الدرس بشكل مبسط وسهل على الجميع, لكي اترك المساحة للآخرين بالابداع بالطرق التي يفضلونها, و كما لاحظنا في المشروع السابق يوجد اكتفتي يتم فتحها بعد النقر على اسم السورة.
والآن هناك قمت بإنشاء عنصر قائمة لكي تقوم بتحميل الملف منها, وتستطيع أنت وضعه زر بجانب أزرار التشغيل.
سوف نقوم بخطوات بسيطة اتبعها بكل هدوء وتركيز :
- قم بإنشاء مجلد بإسم menu بداخل مجلد موارد التطبيق res , وبداخل مجلد الـ menu قم بإنشاء ملف وقم بتسميته بـ download_mp3.xml . إي يصبح مساره بالشكل التالي : \src\main\res\menu\download_mp3.xml
- نقوم بإضافة عنصر بداخله, قم بإضافة الكود التالي داخله :
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/download_1" android:title="تحميل السورة" /> </menu>
هكذا قمنا بإنشاء قائمة للتطبيق.
- الآن نذهب إلى الكلاس PlayerActivity لنقوم بربط القائمة معه, نقوم بفتحه وبآخر الملف إي بعد الدوال وقبل انتهاء الكلاس, إي قبل آخر علامة إغلاق قوس المربع { , نقوم بإضافة الكود التالي لعملية الربط :
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.download_mp3, menu); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.download_1: // هنا يتم كتابة الكود الذي يتم تنفيذه بعد النقر على القائمة واختيار الخيار الذي حددناه return true; default: return super.onOptionsItemSelected(item); } }
لاحظ الكود لعملية ربط ملف القائمة بهذه الاكتفتي ومن ثم برمجة العناصر داخله. إي هكذا تم الربط. والآن ننتقل لموضوع تحميل الملف الصوتي.
- نقوم كذلك بإضافة هذا الكلاس الخاص بتحميل الملفات, أسفل الكود السابق :
private class DownloadFile extends AsyncTask<String, Integer, String> { @Override protected String doInBackground(String... url) { int count; try { URL urls = new URL(url[0]); URLConnection connection = urls.openConnection(); connection.connect(); int lenghtOfFile = connection.getContentLength(); InputStream input = new BufferedInputStream(urls.openStream()); OutputStream output = new FileOutputStream(url[1]); 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) { } return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); Toast.makeText(PlayerActivity.this, "تم تحميل الملف بنجاح", Toast.LENGTH_SHORT).show(); pDialog.cancel(); } }
هكذا أصبح لدينا كلاس لتحميل الملف بداخل الاكتفتي الخاصة بنا, والآن ما نحتاجه هو استخدام هذا الكلاس.
هذا الكلاس للتحميل, وبالأسفل عند الانتهاء من تحميل الملف, تظهر رسالة توست تخبرنا بذلك ويختفي مربع الحوار الذي كان يخبرنا إن هناك عملية تحميل تتم الآن. - والآن لنقوم بإستخدام هذا الكلاس الخاص بتحميل الملف من السيرفر, بعد الضغط على عنصر القائمة, كما لاحظت بالأكواد السابقة الخاصة بعنصر القائمة يوجد فراغ لكتابة الكود داخله الذي يتم تنفيذه بعد الضغط على العنصر.
نقوم بوضع الكود التالي داخله :String Download_Link = getIntent().getExtras().getString("url"); String File_Name = getIntent().getExtras().getString("name"); String downloadAudioPath = Environment.getExternalStorageDirectory() + File.separator + getString(R.string.folder_name) + File.separator + File_Name + ".mp3"; File file_exists = new File(downloadAudioPath); if (!file_exists.exists()){ // إذا لم يكن الملف موجود يقوم بتحويله pDialog = ProgressDialog.show(PlayerActivity.this, "تحميل الملف الصوتي", "جاري التحميل ...", true); DownloadFile downloadAudioFile = new DownloadFile(); downloadAudioFile.execute(Download_Link, downloadAudioPath); }else { // رسالة توست إذا كان الملف موجود مسبقاً Toast.makeText(this, "الملف موجود مسبقاً", Toast.LENGTH_SHORT).show(); }
ما يحدث الآن سوف أخبرك به … أخبرنا البرنامج بعد الضغط على زر عنصر القائمة والذي كان اسمه ” تحميل السورة “, إن يقوم بالتالي :
يقوم بتعريف بيانات من نوع سترنج : الأول اسم الملف وهو اسم الملف الصوتي أو السورة القرآنية, والثاني هو رابط ومسار اي عنوان الملف الصوتي من على السيرفر, والثالث هو مسار هذا الملف الصوتي في جهاز المستخدم.
الاسم ليقوم بتسمية الملف بهذا الاسم كذلك في ملفات المستخدم, والمسار لاستخدامه في تحميل الملف ومن ثم استخدام هذا الأسم, والثالث المسار ليقوم بالتأكد إذا كان هذا الملف بنفس المسار المحدد إنه في جهاز المستخدم لكي لا يقوم بتحميل الملف الصوتي مرة آخرى ويخبر المستخدم بذلك.ثم قمنا بعملية شرط إذا كان الملف موجود أظهر رسالة توست تخبر المستخدم بذلك, إن لم يكن موجود إظهر مربع الحوار يخبر المستخدم إن هناك عملية تحميل للملف, ومن ثم قم بإرسال هذا الأسم والمسار للكلاس الخاص بتحميل الملف لاستخدامه.
- هكذا تكون تمت العملية بنجاح .. لكن دعونا الآن نجعل البرنامج حال تشغيله يقوم بالتأكد إذا كان هذا المجلد الذي يخزن داخله الملفات الصوتية موجود لدى المستخدم , إذا كان موجود تمام لخزن به الملفات بنجاح دون مشاكل, وإن لم يكن موجود يقوم بإنشائه في جهاز المستخدم.
إي لنضيف الكود التالي في دالة الاون كريت إي يتم عمله حال تشغيل هذا الاكتفتي :File audioFolder = new File(Environment.getExternalStorageDirectory() + File.separator , getString(R.string.folder_name)); if(!audioFolder.exists()){ audioFolder.mkdir(); }
لاحظ المسار نفسه الذي يقوم بتخزين الملفات الصوتية داخله لذلك انتبه يجب أن تكون المسارات متشابهة, لهذا الأمر اتبع ما قلت وذكرت لك بدقة وحذر وإذا لم تفهم نقطة حاول قرأتها مرة ومرتين, إذا اشكل عليك أمراً ما لا تتردد في وضع مشكلتك في صندوق التعليقات في الأسفل. وقمت بوضع اسم المجلد في ملفات السترنج لتقوم بتغيره كما شئت.
- إي أذهب الآن إلى ملف السترنج strings.xml وضع داخله السطر التالي :
<string name="folder_name">MyApp</string>
اي من هنا قم بتغيير اسم المجلد كما يناسبك ويحلو لك.
لا تنسى إعطاء صلاحية التخزين للتطبيق.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
وهكذا نكون قد انتهينا من هذه العملية القصيرة والسهلة .. وسوف أعرض لكم الكود لهذا الكلاس بشكل مبسط .. مع حذف الأكواد الخاصة بالمشروع السابق .. تفضلوا :
public class PlayerActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... File audioFolder = new File(Environment.getExternalStorageDirectory() + File.separator , getString(R.string.folder_name)); if(!audioFolder.exists()){ audioFolder.mkdir(); } // ... } // ... @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.download_mp3, menu); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.download_1: String Download_Link = getIntent().getExtras().getString("url"); String File_Name = getIntent().getExtras().getString("name"); String downloadAudioPath = Environment.getExternalStorageDirectory() + File.separator + getString(R.string.folder_name) + File.separator + File_Name + ".mp3"; File file_exists = new File(downloadAudioPath); if (!file_exists.exists()){ // إذا لم يكن الملف موجود يقوم بتحويله pDialog = ProgressDialog.show(PlayerActivity.this, "تحميل الملف الصوتي", "جاري التحميل ...", true); DownloadFile downloadAudioFile = new DownloadFile(); downloadAudioFile.execute(Download_Link, downloadAudioPath); }else { // رسالة توست إذا كان الملف موجود مسبقاً Toast.makeText(this, "الملف موجود مسبقاً", Toast.LENGTH_SHORT).show(); } return true; default: return super.onOptionsItemSelected(item); } } private class DownloadFile extends AsyncTask<String, Integer, String> { @Override protected String doInBackground(String... url) { int count; try { URL urls = new URL(url[0]); URLConnection connection = urls.openConnection(); connection.connect(); int lenghtOfFile = connection.getContentLength(); InputStream input = new BufferedInputStream(urls.openStream()); OutputStream output = new FileOutputStream(url[1]); 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) { } return null; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); Toast.makeText(PlayerActivity.this, "تم تحميل الملف بنجاح", Toast.LENGTH_SHORT).show(); pDialog.cancel(); } } }
بالتوفيق لكم جميعاً … وانتظرونا في المزيد من الدروس الحصرية والجديدة .. ولا تنسوا الاشتراك في قناتنا على اليوتيوب وقروبنا على الفيس بوك والواتس اب ونتشرف بمتابعتك جميعاً .. والسلام عليكم ~
السلام عليكم
اولاً اخي الكريم مشكور جداً جداً على هذه المدونة الرائعة والمواضيع الممتازة وشرحك الجيد
ثانياً انا جربت الكود ولاكن لايحمل الملف الصوتي من الانترنت
ولم اعرف حتى اذا تم التحميل على الجهاز كيف اقوم بتشغيله وشكراً لك