إنشاء جهاز تسجيل صوتي خاص بنظام Android باستخدام Kotlin

إنشاء جهاز تسجيل صوتي خاص بنظام Android باستخدام Kotlin


يدعم إطار الوسائط المتعددة لنظام 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


بعد ذلك ، نحتاج إلى تحديد المسار لحفظ الصوت وتكوين 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 .

Source: https://habr.com/ru/post/ar444616/


All Articles