
يدعم إطار الوسائط المتعددة لنظام Android تسجيل الصوت وتشغيله. في هذه المقالة ، سأوضح كيفية تطوير تطبيق تسجيل بسيط لتسجيل الصوت وتخزينه في التخزين المحلي لجهاز Android باستخدام MediaRecorder
من Android SDK.
سوف تتعلم أيضًا كيفية طلب الأذونات من مستخدم ما في الوقت الفعلي وكيفية التعامل مع التخزين المحلي لجهاز Android.
إنشاء واجهة المستخدم
نحتاج أولاً إلى إنشاء واجهة لتسجيل الصوت. هذا تخطيط بسيط مكون من ثلاثة أزرار سيتم استخدامه لبدء التسجيل وإيقافه مؤقتًا وإيقافه.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textview_sound_recorder_heading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sound Recorder" android:layout_centerHorizontal="true" android:textSize="32dp" android:textStyle="bold" android:textColor="#000" android:layout_marginTop="32dp"/> <Button android:id="@+id/button_start_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start" android:layout_alignParentBottom="true" android:layout_marginLeft="32dp" android:layout_marginBottom="32dp" android:layout_centerVertical="true"/> <Button android:id="@+id/button_pause_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Pause" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp"/> <Button android:id="@+id/button_stop_recording" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="32dp" android:layout_marginRight="32dp"/> </RelativeLayout>
طلب أذونات مطلوبة
بعد إنشاء واجهة المستخدم ، يمكننا البدء في استخدام MediaRecorder
لتنفيذ الوظيفة الأساسية MediaRecorder
. لكن أولاً ، نحتاج إلى طلب الأذونات اللازمة لتسجيل الصوت والوصول إلى التخزين المحلي. سنفعل ذلك ببضع سطور بسيطة من التعليمات البرمجية في ملف AndroidManifest.xml
:
<uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
تحتاج أيضًا إلى التحقق مما إذا كان المستخدم قد وافق على الأذونات قبل أن نتمكن من استخدام MediaRecorder
لدينا. دعونا نفعل ذلك في النشاط MainActivity.kt
:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE) ActivityCompat.requestPermissions(this, permissions,0) }
ملاحظة: سيتم نقل سطور التعليمات البرمجية هذه لاحقًا إلى OnClickListener
زر بدء تسجيل الصوت حتى نتمكن من التأكد من عدم MediaRecorder
بدون الأذونات اللازمة.
تسجيل وحفظ الصوت
مضيفا OnClickListeners
أضف مستمعين إلى الأزرار حتى يستجيبوا لأحداث المستخدم. كما ذكرت سابقًا ، ستتم إضافة التحقق من الأذونات اللازمة إلى OnClickListener لزر البدء في التسجيل الصوتي:
button_start_recording.setOnClickListener { if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE) ActivityCompat.requestPermissions(this, permissions,0) } else { startRecording() } } button_stop_recording.setOnClickListener{ stopRecording() } button_pause_recording.setOnClickListener { pauseRecording() }
بعد ذلك ، نحتاج إلى تحديد المسار لحفظ الصوت وتكوين MediaRecorder.
private var output: String? = null private var mediaRecorder: MediaRecorder? = null private var state: Boolean = false private var recordingStopped: Boolean = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) output = Environment.getExternalStorageDirectory().absolutePath + "/recording.mp3" mediaRecorder = MediaRecorder() mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC) mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC) mediaRecorder?.setOutputFile(output) }
نأخذ الطريق إلى جذر التخزين الخارجي الخاص بنا ونضيف اسم سجلنا ونوع الملف إليه. بعد ذلك ، نقوم بإنشاء كائن MediaRecorder
ونحدد مصدر الصوت MediaRecorder
الصوت والتنسيق والملف للتسجيل.
تسجيل وحفظ الصوت
يتم تعريف الكود المستخدم لبدء تشغيل OnClickListener
في OnClickListener
زر بدء تسجيل الصوت:
private fun startRecording() { try { mediaRecorder?.prepare() mediaRecorder?.start() state = true Toast.makeText(this, "Recording started!", Toast.LENGTH_SHORT).show() } catch (e: IllegalStateException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } }
كما ترون ، نحتاج إلى استدعاء وظيفة prepare
قبل أن نتمكن من بدء التسجيل. نقوم أيضًا بتضمين المكالمة في كتلة try-catch حتى لا ينقطع التطبيق عند فشل وظيفة prepare
.
OnClickListeners
إيقاف التسجيل إلى حد كبير الرمز أعلاه.
private fun stopRecording() { if (state) { mediaRecorder?.stop() mediaRecorder?.release() state = false } else { Toast.makeText(this, "You are not recording right now!", Toast.LENGTH_SHORT).show() } }
هنا نتحقق مما إذا كان MediaRecorder
حاليًا قبل أن نتوقف عن التسجيل لأن تطبيقنا سينقطع إذا تم استدعاء طريقة stop
بينما لن يتم MediaRecorder
. بعد ذلك ، نقوم بتغيير متغير الحالة إلى false
بحيث لا يمكن للمستخدم الضغط على زر التوقف مرة أخرى.
يبقى لنا تحديد OnClickListener
الإيقاف المؤقت / الاستئناف.
@SuppressLint("RestrictedApi", "SetTextI18n") @TargetApi(Build.VERSION_CODES.N) private fun pauseRecording() { if (state) { if (!recordingStopped) { Toast.makeText(this,"Stopped!", Toast.LENGTH_SHORT).show() mediaRecorder?.pause() recordingStopped = true button_pause_recording.text = "Resume" } else { resumeRecording() } } } @SuppressLint("RestrictedApi", "SetTextI18n") @TargetApi(Build.VERSION_CODES.N) private fun resumeRecording() { Toast.makeText(this,"Resume!", Toast.LENGTH_SHORT).show() mediaRecorder?.resume() button_pause_recording.text = "Pause" recordingStopped = false }
في هاتين الطريقتين ، نتحقق مما إذا كان MediaRecorder
. إذا نجحت ، فسنوقف التسجيل ونغير نص الزر لاستئنافه. الضغط عليه مرة أخرى سيستأنف التسجيل.
أخيرًا ، يمكننا تسجيل الصوت والاستماع إليه من خلال فتح ملف recording.mp3
، والذي سيتم حفظه في مخزننا المحلي. مجرد فتح مستكشف الملفات وإجراء بحث على recording.mp3
اسم الملف. recording.mp3
.
شفرة المصدر
هنا هو شفرة المصدر الكامل لتطبيقنا:
package com.example.android.soundrecorder import android.Manifest import android.annotation.SuppressLint import android.annotation.TargetApi import android.content.pm.PackageManager import android.media.MediaRecorder import android.os.Build import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.os.Environment import android.support.v4.app.ActivityCompat import android.support.v4.content.ContextCompat import android.widget.Toast import kotlinx.android.synthetic.main.activity_main.* import java.io.IOException class MainActivity : AppCompatActivity() { private var output: String? = null private var mediaRecorder: MediaRecorder? = null private var state: Boolean = false private var recordingStopped: Boolean = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mediaRecorder = MediaRecorder() output = Environment.getExternalStorageDirectory().absolutePath + "/recording.mp3" mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC) mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC) mediaRecorder?.setOutputFile(output) button_start_recording.setOnClickListener { if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { val permissions = arrayOf(android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE) ActivityCompat.requestPermissions(this, permissions,0) } else { startRecording() } } button_stop_recording.setOnClickListener{ stopRecording() } button_pause_recording.setOnClickListener { pauseRecording() } } private fun startRecording() { try { mediaRecorder?.prepare() mediaRecorder?.start() state = true Toast.makeText(this, "Recording started!", Toast.LENGTH_SHORT).show() } catch (e: IllegalStateException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } } @SuppressLint("RestrictedApi", "SetTextI18n") @TargetApi(Build.VERSION_CODES.N) private fun pauseRecording() { if (state) { if (!recordingStopped) { Toast.makeText(this,"Stopped!", Toast.LENGTH_SHORT).show() mediaRecorder?.pause() recordingStopped = true button_pause_recording.text = "Resume" } else { resumeRecording() } } } @SuppressLint("RestrictedApi", "SetTextI18n") @TargetApi(Build.VERSION_CODES.N) private fun resumeRecording() { Toast.makeText(this,"Resume!", Toast.LENGTH_SHORT).show() mediaRecorder?.resume() button_pause_recording.text = "Pause" recordingStopped = false } private fun stopRecording(){ if (state) { mediaRecorder?.stop() mediaRecorder?.release() state = false } else { Toast.makeText(this, "You are not recording right now!", Toast.LENGTH_SHORT).show() } } }
استنتاج
أنت تعرف الآن كيفية عمل MediaRecorder
، وكيفية طلب أذونات في الوقت الفعلي ، ولماذا من المهم القيام بذلك. لقد تعرفت أيضًا على التخزين المحلي لجهاز Android الخاص بك وكيفية تخزين البيانات فيه.
يتوفر إصدار أكثر تعقيدًا من هذا التطبيق ، والذي يحتوي على بعض الميزات الإضافية ، مثل تشغيل التسجيلات الخاصة بك باستخدام MediaPlayer
، على Github .