بسم الله الرحمن الرحيم
بالمشروع السابق, عرضنا لكم مشروع مشغل ملفات صوتية اون لاين بالكود كامل مفتوح المصدر لكم, والآن سوف نتعلم كيفية جعل هذا المشروع اوف لاين إي تشغيل الملفات الصوتية دون الحاجة للسيرفر او الاتصال بالانترنت, يتم تشغيل الملفات من ملفات المشروع, إي الملفات الصوتية بداخل التطبيق.
- لتحميل التطبيق مفتوح المصدر اون لاين : تطبيق تشغيل ملفات صوتية اون لاين مفتوح المصدر
بعد تحميله, سوف نقوم ببعض التعديلات عليه, ليصبح اوف لاين, في البداية قم بإنشاء مجلد بإسم raw بداخل res .
ثم ضع داخله الملفات الصوتية التي تريدها, ولا تنسى القيام بضغط الملفات الصوتية, كي لا يصبح حجم التطبيق مرتفع.
طرق ضغط الملفات الصوتية كثيرة, يوجد مواقع انترنت لضغطها وكذلك يوجد برامج كثيرة, وسابقاً قد جربت برنامج فورمات فاكتوري وكانت نتائجه مذهلة بعد اختيار دقة منخفضة ولم تتأثر الملفات الصوتية, وتستطيع كذلك التحويل بين الصيغ لتجد الصيغة الأخف والمناسبة لك, وإذا كانت ملفات كثيرة وكبيرة الحجم وتريد تشغيلها من ملفات التطبيق, تستطيع اتباع طريقة قد قمت بها سابقاً وهي, رفع الملفات الصوتية في ملف مضغوط على الانترنت, وعند تشغيل التطبيق لأول مرة يقوم بتحميل هذا الملف المضغوط في مسار معين ومن ثم فك الضغط عنه, والتطبيق يستخدم هذه الملفات. وهكذا التطبيق خفيف الحجم جداً ..
عموماً لنكمل ما بدأنا به, وهو كيفية تشغيل الملفات الصوتية من مجلد raw.
لو رجعنا إلى الكود السابق, في الكلاس “List” نجد هناك مصفوفة من نوع سترنج واسمها AndRody_Subject وتحتوي على أسماء الملفات الصوتية إي السور القرآنية, والمصوفة الأخرى كذلك من نوع سترنج واسمها AndRody_Link , وتحتوي على روابط الملفات ومسارها من الانترنت.
الآن نقوم بتغيير اسم المصفوفة الثانية إلى AndRody_Path ونقوم بتغيير نوعها إلى Integer. ونضع داخلها مسارات الملفات الصوتية بواسطة الآي دي, بالطريقة التالية : R.raw.mp1 حيث mp1 اسم الملف الصوتي.
وهكذا .. الملف الصوتي الأول في مصفوفة الانتجر, تأخذ الاسم الأول في مصفوفة السترنج .. لا تقلق الفكرة سوف توضح لك شيئاً فشيء.
و الآن نذهب إلى الكلاس “Data” نجد لدينا subject و link من نوع سترنج, نقوم بتغيير link إلى path و نجعلها من نوع انتجر Integer .
و الآن في الكلاس “ListAdapterr” نقوم بتغيير قيمة الارسال من url إلى path .
والآن في الملف الرئيسي لتشغيل الملفات الصوتية “PlayerActivity” نقوم بالتعديلات التالية :
- نقوم بحذف شرط التحقق من توفر الانترنت.
- نقوم بحذف مربع الحوار ProgressDialog لم نعد بحاجته.
- نقوم بحذف شرط التحقق من صحة الرابط.
- في دالة الـ playSong :
نقوم بحذف setAudioStreamType و setDataSource ونقوم بإستبدالها بـ MediaPlayer.create ونقوم باستخدام داخلها المسار القادم من path.
لا مشكلة إن لم تفهم ما تحدثت به سابقاً, فسوف أعرض عليكم الكود كاملاً .. فقط لكي تحدثت ما قمنا به لكي تفهم ما حدث.
الآن الكود بعد التعديلات السابقة :
Data
public class Data { String subject; Integer path; public Data(String tt1, Integer tt2) { this.subject = tt1; this.path = tt2; } public String getSubject() { return this.subject; } public Integer getPath() { return this.path; } }
ListAdapterr
public class ListAdapterr extends BaseAdapter { LayoutInflater inflater; private List<Data> Datalist = null; private ArrayList<Data> arraylist; Context context; public ListAdapterr(Activity context, List<Data> openSite) { this.context=context; this.Datalist = openSite; inflater = LayoutInflater.from(context); this.arraylist = new ArrayList<>(); this.arraylist.addAll(openSite); } @Override public int getCount() { return Datalist.size(); } @Override public Object getItem(int position) { return Datalist.get(position); } @Override public long getItemId(int position) { return position; } public View getView(final int position, View view, ViewGroup parent) { View Item =inflater.inflate(R.layout.listview_item, null,true); LinearLayout LL = (LinearLayout) Item.findViewById(R.id.Ll_); LL.setBackgroundColor(Color.parseColor("#099806")); TextView txtTitle = (TextView) Item.findViewById(R.id.titleid); txtTitle.setTextColor(Color.parseColor("#099806")); txtTitle.setText(Datalist.get(position).getSubject()); Item.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Intent i = new Intent(context,PlayerActivity.class); i.putExtra("name",Datalist.get(position).getSubject()); i.putExtra("path",Datalist.get(position).getPath()); context.startActivity(i); } }); if (position % 2 == 0){ LL.setBackgroundColor(Color.parseColor("#038001")); txtTitle.setTextColor(Color.parseColor("#038001")); } return Item; }; }
List
public class List extends AppCompatActivity { ListView listView; ArrayList<Data> arraylist = new ArrayList<>(); ListAdapterr adapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getSupportActionBar().setCustomView(R.layout.custom_actionbar); TextView mTitleTextView = (TextView) findViewById(R.id.title_text); mTitleTextView.setText(getString(R.string.app_name)); listView = (ListView) findViewById(R.id.listviewid); String[] AndRody_Subject = {getString(R.string.Sura1), getString(R.string.Sura2), getString(R.string.Sura3), getString(R.string.Sura4), getString(R.string.Sura5), getString(R.string.Sura6), getString(R.string.Sura7) , getString(R.string.Sura8), getString(R.string.Sura9), getString(R.string.Sura10) , getString(R.string.Sura11), getString(R.string.Sura12), getString(R.string.Sura13), getString(R.string.Sura14), getString(R.string.Sura15), getString(R.string.Sura16), getString(R.string.Sura17) , getString(R.string.Sura18), getString(R.string.Sura19), getString(R.string.Sura20) , getString(R.string.Sura21), getString(R.string.Sura22), getString(R.string.Sura23), getString(R.string.Sura24), getString(R.string.Sura25), getString(R.string.Sura26), getString(R.string.Sura27) , getString(R.string.Sura28), getString(R.string.Sura29), getString(R.string.Sura30) , getString(R.string.Sura31), getString(R.string.Sura32), getString(R.string.Sura33), getString(R.string.Sura34), getString(R.string.Sura35), getString(R.string.Sura36), getString(R.string.Sura37) , getString(R.string.Sura38), getString(R.string.Sura39), getString(R.string.Sura40) , getString(R.string.Sura41), getString(R.string.Sura42), getString(R.string.Sura43), getString(R.string.Sura44), getString(R.string.Sura45), getString(R.string.Sura46), getString(R.string.Sura47) , getString(R.string.Sura48), getString(R.string.Sura49), getString(R.string.Sura50) , getString(R.string.Sura51), getString(R.string.Sura52), getString(R.string.Sura53), getString(R.string.Sura54), getString(R.string.Sura55), getString(R.string.Sura56), getString(R.string.Sura57) , getString(R.string.Sura58), getString(R.string.Sura59), getString(R.string.Sura60) , getString(R.string.Sura61), getString(R.string.Sura62), getString(R.string.Sura63), getString(R.string.Sura64), getString(R.string.Sura65), getString(R.string.Sura66), getString(R.string.Sura67) , getString(R.string.Sura68), getString(R.string.Sura69), getString(R.string.Sura70) , getString(R.string.Sura71), getString(R.string.Sura72), getString(R.string.Sura73), getString(R.string.Sura74), getString(R.string.Sura75), getString(R.string.Sura76), getString(R.string.Sura77) , getString(R.string.Sura78), getString(R.string.Sura79), getString(R.string.Sura80) , getString(R.string.Sura81), getString(R.string.Sura82), getString(R.string.Sura83), getString(R.string.Sura84), getString(R.string.Sura85), getString(R.string.Sura86), getString(R.string.Sura87) , getString(R.string.Sura88), getString(R.string.Sura89), getString(R.string.Sura90) , getString(R.string.Sura91), getString(R.string.Sura92), getString(R.string.Sura93), getString(R.string.Sura94), getString(R.string.Sura95), getString(R.string.Sura96), getString(R.string.Sura97) , getString(R.string.Sura98), getString(R.string.Sura99), getString(R.string.Sura100) , getString(R.string.Sura101), getString(R.string.Sura102), getString(R.string.Sura103), getString(R.string.Sura104), getString(R.string.Sura105), getString(R.string.Sura106), getString(R.string.Sura107) , getString(R.string.Sura108), getString(R.string.Sura109), getString(R.string.Sura110) , getString(R.string.Sura111), getString(R.string.Sura112), getString(R.string.Sura113), getString(R.string.Sura114)}; Integer[] AndRody_Path = {R.raw.m1, R.raw.m2, R.raw.m3, R.raw.m4, R.raw.m5, R.raw.m6, R.raw.m7 , R.raw.m8, R.raw.m9, R.raw.m10 , R.raw.m11, R.raw.m12, R.raw.m13, R.raw.m14, R.raw.m15, R.raw.m16, R.raw.m17 , R.raw.m18, R.raw.m19, R.raw.m20 , R.raw.m21, R.raw.m22, R.raw.m23, R.raw.m24, R.raw.m25, R.raw.m26, R.raw.m27 , R.raw.m28, R.raw.m29, R.raw.m30 , R.raw.m31, R.raw.m32, R.raw.m33, R.raw.m34, R.raw.m35, R.raw.m36, R.raw.m37 , R.raw.m38, R.raw.m39, R.raw.m40 , R.raw.m41, R.raw.m42, R.raw.m43, R.raw.m44, R.raw.m45, R.raw.m46, R.raw.m47 , R.raw.m48, R.raw.m49, R.raw.m50 , R.raw.m51, R.raw.m52, R.raw.m53, R.raw.m54, R.raw.m55, R.raw.m56, R.raw.m57 , R.raw.m58, R.raw.m59, R.raw.m60 , R.raw.m61, R.raw.m62, R.raw.m63, R.raw.m64, R.raw.m65, R.raw.m66, R.raw.m67 , R.raw.m68, R.raw.m69, R.raw.m70 , R.raw.m71, R.raw.m72, R.raw.m73, R.raw.m74, R.raw.m75, R.raw.m76, R.raw.m77 , R.raw.m78, R.raw.m79, R.raw.m80 , R.raw.m81, R.raw.m82, R.raw.m83, R.raw.m84, R.raw.m85, R.raw.m86, R.raw.m87 , R.raw.m88, R.raw.m89, R.raw.m90 , R.raw.m91, R.raw.m92, R.raw.m93, R.raw.m94, R.raw.m95, R.raw.m96, R.raw.m97 , R.raw.m98, R.raw.m99, R.raw.m100 , R.raw.m101, R.raw.m102, R.raw.m103, R.raw.m104, R.raw.m105, R.raw.m106, R.raw.m107 , R.raw.m108, R.raw.m109, R.raw.m110 , R.raw.m111, R.raw.m112, R.raw.m113, R.raw.m114}; for (int i = 0; i < AndRody_Subject.length; i++) { Data abboudi = new Data(AndRody_Subject[i], AndRody_Path[i]); arraylist.add(abboudi); } adapter = new ListAdapterr(this, arraylist); listView.setAdapter(adapter); } @Override public void onBackPressed() { AlertDialog.Builder builder = new AlertDialog.Builder(List.this); builder.setTitle("إغلاق التطبيق"); // العنوان builder.setMessage("هل متأكد من خروج من التطبيق :("); // المحتوى builder.setPositiveButton("نعم", // الزر الاول new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // الاوامر التي تحدث بعد الضغط على الزر الأاول finish(); } }); builder.setNegativeButton("لا", // الزر الثاني new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // اوامر الزر الثاني } }); builder.show(); }
هنا اسماء ومسارات الملفات الصوتية, قم بتغيرها حسب الملفات لديك.
PlayerActivity
public class PlayerActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { SeekBar seek_bar; ImageButton button_Play; ImageView image_Rhythm; TextView txt_Status, current_time, sound_duration; MediaPlayer media_voice; AnimationDrawable mAnimation; Handler mHandler = new Handler(); Utilities utils; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.player); media_voice = new MediaPlayer(); processing_actionBar(); linking_elements(); utils = new Utilities(); seek_bar.setOnSeekBarChangeListener(this); seek_bar.setMax(media_voice.getDuration()); playSong(); // برمجة زر التشغيل والإيقاف button_Play.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { if (media_voice.isPlaying()) { if (media_voice != null) { media_voice.pause(); stopRhythm(); txt_Status.setText(getString(R.string.text_2)); button_Play.setImageResource(R.drawable.img_btn_play); } } else { if (media_voice != null) { media_voice.start(); startRhythm(); txt_Status.setText(getString(R.string.text_3)); button_Play.setImageResource(R.drawable.img_btn_pause); } } } }); } public void processing_actionBar() { getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getSupportActionBar().setCustomView(R.layout.custom_actionbar); TextView mTitleTextView = (TextView) findViewById(R.id.title_text); mTitleTextView.setText(getIntent().getExtras().getString("name")); } public void linking_elements() { seek_bar = (SeekBar) findViewById(R.id.seekbar); txt_Status = (TextView) findViewById(R.id.songCurrentDurationLabel); current_time = (TextView) findViewById(R.id.songCurrentDurationLabel1); sound_duration = (TextView) findViewById(R.id.songTotalDurationLabel); button_Play = (ImageButton) findViewById(R.id.btnPlay); image_Rhythm = (ImageView) findViewById(R.id.img_equilizer); image_Rhythm.setBackgroundResource(R.drawable.simple_animation); mAnimation = (AnimationDrawable) image_Rhythm.getBackground(); } public void playSong() { try { media_voice.reset(); media_voice = MediaPlayer.create(this,getIntent().getIntExtra("path",0)); txt_Status.setText(getString(R.string.text_4)); media_voice.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); startRhythm(); updateProgressBar(); button_Play.setImageResource(R.drawable.img_btn_pause); txt_Status.setText(getString(R.string.text_3)); } }); media_voice.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { txt_Status.setText(getString(R.string.text_5)); current_time.setText(""); stopRhythm(); button_Play.setImageResource(R.drawable.img_btn_play); } }); button_Play.setImageResource(R.drawable.img_btn_pause); seek_bar.setProgress(0); seek_bar.setMax(100); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } } private void startRhythm() { image_Rhythm.post(new Runnable() { public void run() { mAnimation.start(); } }); } private void stopRhythm() { image_Rhythm.post(new Runnable() { public void run() { mAnimation.stop(); } }); } public void updateProgressBar() { mHandler.postDelayed(mUpdateTimeTask, 100); } private Runnable mUpdateTimeTask = new Runnable() { public void run() { long totalDuration = media_voice.getDuration(); long currentDuration = media_voice.getCurrentPosition(); sound_duration.setText("" + utils.milliSecondsToTimer(totalDuration)); current_time.setText("" + utils.milliSecondsToTimer(currentDuration)); int progress = (int) (utils.getProgressPercentage(currentDuration, totalDuration)); seek_bar.setProgress(progress); mHandler.postDelayed(this, 100); } }; @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { mHandler.removeCallbacks(mUpdateTimeTask); } @Override public void onStopTrackingTouch(SeekBar seekBar) { mHandler.removeCallbacks(mUpdateTimeTask); int totalDuration = media_voice.getDuration(); int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration); media_voice.seekTo(currentPosition); updateProgressBar(); } @Override public void onDestroy() { super.onDestroy(); media_voice.release(); } @Override public void onBackPressed() { mHandler.removeCallbacks(mUpdateTimeTask); seek_bar.setProgress(0); finish(); super.onBackPressed(); } }
هكذا نكون قد أنتهينا من هذه التدوينة, والعملية إن شاء الله تمت بنجاح, وإذا اشكل عليك أمراً ما, لا تتردد في كتابة مشكلتك او استفساراتك في صندوق التعليقات.
راجع التدوينة السابقة في كيفية تجهيز خاصية تحميل الملف الصوتي : تحميل ملف من السيرفر لجهازك الأندرويد برمجياً , والسلام عليكم.
عند ادخال ملفات mp3 التطبيق مايشغلها .. واذا دخلت عليها يسوي كراش
عذرا الخطا من الملف الذي تم ادخاله في المشورع تبعي
اكملو ربي يفتح لكم باب التوفيق والنجاح