Facebook
From Soft Hummingbird, 5 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 241
  1. import android.content.Context;
  2. import android.content.Intent;
  3. import android.media.AudioFormat;
  4. import android.media.AudioRecord;
  5. import android.media.MediaRecorder;
  6. import android.os.Environment;
  7. import android.support.v7.app.AppCompatActivity;
  8. import android.os.Bundle;
  9. import android.view.View;
  10. import android.widget.Button;
  11. import android.widget.EditText;
  12. import android.widget.Toast;
  13. import android.widget.ToggleButton;
  14.  
  15. import java.io.DataInputStream;
  16. import java.io.DataOutputStream;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.FileNotFoundException;
  20. import java.io.FileOutputStream;
  21. import java.io.IOException;
  22. import java.nio.ByteBuffer;
  23. import java.nio.ByteOrder;
  24. import java.util.Calendar;
  25.  
  26. public class ActivityNote extends AppCompatActivity {
  27.  
  28.     private Button button1, button2, button3;
  29.     private EditText lastNameEditText, nameEditText, titelEditText, descriptionEditText;
  30.     private Thread recordingThread = null;
  31.     private AudioRecord audioRecord = null;
  32.  
  33.     private boolean isRecording = false;
  34.  
  35.     private final int SAMPLING_FREQUENCY = 44100;
  36.     private final int BYTES_PER_ELEMENTS = 2;
  37.     private final int BUFFER_ELEMENTS_TO_REC  = 1024;
  38.     private final String FILE_NAME = "RecordedAudio.pcm";
  39.  
  40.     @Override
  41.     protected void onCreate(Bundle savedInstanceState) {
  42.         super.onCreate(savedInstanceState);
  43.         setContentView(R.layout.activity_note);
  44.  
  45.         lastNameEditText = findViewById(R.id.last_name_edit_text);
  46.         nameEditText = findViewById(R.id.name_edit_text);
  47.         titelEditText = findViewById(R.id.title_edit_text);
  48.         descriptionEditText = findViewById(R.id.description_edit_text);
  49.  
  50.         final ToggleButton toggleButton = findViewById(R.id.togglebutton1);
  51.         toggleButton.setOnClickListener(new ToggleButton.OnClickListener() {
  52.             @Override
  53.             public void onClick(View view) {
  54.                 if (toggleButton.isChecked()) {
  55.                     startRecording();
  56.                 } else {
  57.                     stopRecording();
  58.                 }
  59.             }
  60.         });
  61.  
  62.         button1 = findViewById(R.id.button1);
  63.         button1.setOnClickListener(new Button.OnClickListener() {
  64.             @Override
  65.             public void onClick(View view) {
  66.                 saveNote();
  67.             }
  68.         });
  69.  
  70.         button2 = findViewById(R.id.button2);
  71.         //Prevent from saving or deleting note before being recorder
  72.         button1.setEnabled(false);
  73.         button2.setEnabled(false);
  74.         button2.setOnClickListener(new Button.OnClickListener() {
  75.             @Override
  76.             public void onClick(View view) {
  77.                 deleteNote();
  78.             }
  79.         });
  80.  
  81.         button3 = findViewById(R.id.button3);
  82.         final Intent intent1 = new Intent(this, ActivityList.class);
  83.         button3.setOnClickListener(new Button.OnClickListener() {
  84.             @Override
  85.             public void onClick(View view) {
  86.                 startActivity(intent1);
  87.             }
  88.         });
  89.     }
  90.  
  91.     private void startRecording() {
  92.         // Prevent from saving or deleting note while being recorded
  93.         button1.setEnabled(false);
  94.         button2.setEnabled(false);
  95.  
  96.         audioRecord = new AudioRecord(
  97.                 MediaRecorder.AudioSource.MIC,
  98.                 SAMPLING_FREQUENCY,
  99.                 AudioFormat.CHANNEL_IN_MONO,
  100.                 AudioFormat.ENCODING_PCM_16BIT,
  101.                 BYTES_PER_ELEMENTS * BUFFER_ELEMENTS_TO_REC
  102.         );
  103.         audioRecord.startRecording();
  104.         isRecording = true;
  105.  
  106.         recordingThread = new Thread(new Runnable() {
  107.             @Override
  108.             public void run() {
  109.                 writeAudioDataToFile();
  110.             }
  111.         }, "AudioRecorder Thread");
  112.         recordingThread.start();
  113.  
  114.         // Debug toast
  115.         Toast.makeText(this, "Start recording", Toast.LENGTH_SHORT).show();
  116.     }
  117.  
  118.     private void stopRecording() {
  119.         // Note can be saved or deleted only after being recorded
  120.         button1.setEnabled(true);
  121.         button2.setEnabled(true);
  122.  
  123.         if (audioRecord != null) {
  124.             isRecording = false;
  125.             audioRecord.stop();
  126.             audioRecord.release();
  127.             audioRecord = null;
  128.             recordingThread = null;
  129.         }
  130.         // Debug toast
  131.         Toast.makeText(this, "Stop recording", Toast.LENGTH_SHORT).show();
  132.     }
  133.  
  134.     private void saveNote() {
  135.         File source = new File(getApplicationContext().getFilesDir() + "/" + FILE_NAME);
  136.         File destiny = new File("/sdcard/note_" + Calendar.getInstance().getTime().toString() + ".wav");
  137.  
  138.         try {
  139.             rawToWave(source, destiny);
  140.         } catch (Exception e) {
  141.             e.printStackTrace();
  142.         }
  143.  
  144.         // Debug toast
  145.         Toast.makeText(this, "Save Note", Toast.LENGTH_SHORT).show();
  146.     }
  147.  
  148.     private void deleteNote() {
  149.         // Prevent saving or deleting empty note
  150.         button1.setEnabled(false);
  151.         button2.setEnabled(false);
  152.  
  153.         File source = new File(getApplicationContext().getFilesDir() + "/" + FILE_NAME);
  154.         source.delete();
  155.  
  156.         // Debug toast
  157.         Toast.makeText(this, "Delete Note", Toast.LENGTH_SHORT).show();
  158.     }
  159.  
  160.     private void writeAudioDataToFile() {
  161.         short sData[] = new short[BUFFER_ELEMENTS_TO_REC];
  162.  
  163.         FileOutputStream fileOutputStream = null;
  164.         try {
  165.             fileOutputStream = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
  166.         } catch (FileNotFoundException e) {
  167.             e.printStackTrace();
  168.         }
  169.  
  170.         while (isRecording) {
  171.             audioRecord.read(sData, 0, BUFFER_ELEMENTS_TO_REC);
  172.  
  173.             try {
  174.                 byte bData[] = short2byte(sData);
  175.                 fileOutputStream.write(bData, 0, BUFFER_ELEMENTS_TO_REC * BYTES_PER_ELEMENTS);
  176.             } catch (IOException e) {
  177.                 e.printStackTrace();
  178.             }
  179.         }
  180.  
  181.         try {
  182.             fileOutputStream.close();
  183.         } catch (IOException e) {
  184.             e.printStackTrace();
  185.         }
  186.     }
  187.  
  188.     private byte[] short2byte(short[] sData) {
  189.         int shortArraySize = sData.length;
  190.         byte[] bytes = new byte[shortArraySize * 2];
  191.  
  192.         for (int i = 0; i < shortArraySize; i++) {
  193.             bytes[i * 2] = (byte) (sData[i] & 0x00FF);
  194.             bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
  195.             sData[i] = 0;
  196.         }
  197.  
  198.         return bytes;
  199.     }
  200.  
  201.     private void rawToWave(final File rawFile, final File waveFile) throws IOException {
  202.  
  203.         byte[] rawData = new byte[(int) rawFile.length()];
  204.         DataInputStream input = null;
  205.         try {
  206.             input = new DataInputStream(new FileInputStream(rawFile));
  207.             input.read(rawData);
  208.         } finally {
  209.             if (input != null) {
  210.                 input.close();
  211.             }
  212.         }
  213.  
  214.         DataOutputStream output = null;
  215.         try {
  216.             output = new DataOutputStream(new FileOutputStream(waveFile));
  217.  
  218.             // WAVE header
  219.             writeString(output, "RIFF"); // chunk id
  220.             writeInt(output, 36 + rawData.length); // chunk size
  221.             writeString(output, "WAVE"); // format
  222.             writeString(output, "fmt "); // subchunk 1 id
  223.             writeInt(output, 16); // subchunk 1 size
  224.             writeShort(output, (short) 1); // audio format (1 = PCM)
  225.             writeShort(output, (short) 1); // number of channels
  226.             writeInt(output, 44100); // sample rate
  227.             writeInt(output, SAMPLING_FREQUENCY * 2); // byte rate
  228.             writeShort(output, (short) 2); // block align
  229.             writeShort(output, (short) 16); // bits per sample
  230.             writeString(output, "data"); // subchunk 2 id
  231.             writeInt(output, rawData.length); // subchunk 2 size
  232.             // Audio data (conversion big endian -> little endian)
  233.             short[] shorts = new short[rawData.length / 2];
  234.             ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
  235.             ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
  236.             for (short s : shorts) {
  237.                 bytes.putShort(s);
  238.             }
  239.  
  240.             output.write(fullyReadFileToBytes(rawFile));
  241.         } finally {
  242.             if (output != null) {
  243.                 output.close();
  244.             }
  245.         }
  246.     }
  247.     byte[] fullyReadFileToBytes(File f) throws IOException {
  248.         int size = (int) f.length();
  249.         byte bytes[] = new byte[size];
  250.         byte tmpBuff[] = new byte[size];
  251.         FileInputStream fis= new FileInputStream(f);
  252.         try {
  253.  
  254.             int read = fis.read(bytes, 0, size);
  255.             if (read < size) {
  256.                 int remain = size - read;
  257.                 while (remain > 0) {
  258.                     read = fis.read(tmpBuff, 0, remain);
  259.                     System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
  260.                     remain -= read;
  261.                 }
  262.             }
  263.         }  catch (IOException e){
  264.             throw e;
  265.         } finally {
  266.             fis.close();
  267.         }
  268.  
  269.         return bytes;
  270.     }
  271.     private void writeInt(final DataOutputStream output, final int value) throws IOException {
  272.         output.write(value >> 0);
  273.         output.write(value >> 8);
  274.         output.write(value >> 16);
  275.         output.write(value >> 24);
  276.     }
  277.  
  278.     private void writeShort(final DataOutputStream output, final short value) throws IOException {
  279.         output.write(value >> 0);
  280.         output.write(value >> 8);
  281.     }
  282.  
  283.     private void writeString(final DataOutputStream output, final String value) throws IOException {
  284.         for (int i = 0; i < value.length(); i++) {
  285.             output.write(value.charAt(i));
  286.         }
  287.     }
  288. }
  289.  
  290.  
  291. <?xml version="1.0" encoding="utf-8"?>
  292. <LinearLayout
  293.     xmlns:android="http://schemas.android.com/apk/res/android"
  294.     xmlns:app="http://schemas.android.com/apk/res-auto"
  295.     xmlns:tools="http://schemas.android.com/tools"
  296.     android:layout_width="match_parent"
  297.     android:layout_height="match_parent"
  298.     android:orientation="vertical"
  299.     tools:context=".ActivityNote">
  300.  
  301.     <ToggleButton
  302.         android:id="@+id/togglebutton1"
  303.         android:layout_width="match_parent"
  304.         android:layout_height="wrap_content"
  305.         android:checked="false"
  306.         android:textOn="@string/note_togglebutton1_on"
  307.         android:textOff="@string/note_togglebutton1_off"/>
  308.  
  309.     <Button
  310.         android:id="@+id/button1"
  311.         android:layout_width="match_parent"
  312.         android:layout_height="wrap_content"
  313.         android:text="@string/note_button1"/>
  314.  
  315.     <Button
  316.         android:id="@+id/button2"
  317.         android:layout_width="match_parent"
  318.         android:layout_height="wrap_content"
  319.         android:text="@string/note_button2" />
  320.  
  321.     <Button
  322.         android:id="@+id/button3"
  323.         android:layout_width="match_parent"
  324.         android:layout_height="wrap_content"
  325.         android:text="@string/note_button3"/>
  326.  
  327.     <EditText
  328.         android:id="@+id/last_name_edit_text"
  329.         android:layout_width="match_parent"
  330.         android:layout_height="wrap_content"
  331.         android:inputType="text"
  332.         android:maxLength="15"
  333.         android:hint="@string/last_name" />
  334.  
  335.     <EditText
  336.         android:id="@+id/name_edit_text"
  337.         android:layout_width="match_parent"
  338.         android:layout_height="wrap_content"
  339.         android:inputType="text"
  340.         android:maxLength="15"
  341.         android:hint="@string/name" />
  342.  
  343.     <EditText
  344.         android:id="@+id/title_edit_text"
  345.         android:layout_width="match_parent"
  346.         android:layout_height="wrap_content"
  347.         android:inputType="text"
  348.         android:maxLength="15"
  349.         android:hint="@string/note_title" />
  350.  
  351.     <EditText
  352.         android:id="@+id/description_edit_text"
  353.         android:layout_width="match_parent"
  354.         android:layout_height="wrap_content"
  355.         android:inputType="text"
  356.         android:maxLength="50"
  357.         android:hint="@string/note_description" />
  358. </LinearLayout>