녹음파일 저장, 타이머, 효과음 구현

Hwan·2023년 2월 6일
0

voicekeeper

목록 보기
4/16

구현할 내용

  • 안드로이드 최신 버전에서 외부저장소 접근 권한 얻기
  • 녹음 기능 구현
  • 파일명 지정하여 원하는 위치에 저장
  • 효과음(시간지연) 이후 녹음 시작
  • 녹음 시작시 타이머 작동

1. CallActivity.java

제작하는 앱의 구조상 버튼을 눌러 녹음하는 것이 아닌, 페이지 이동 후 6초 후에 자동으로 녹음이 시작되게 하였다.

녹음기능

  • MediaStore을 사용하여 오디오 파일을 생성 (audio/mp4 형식)
  • Environment.getExternalStorageDirectory를 이용하여 외부저장소의 위치를 얻어낸 뒤, 원하는 폴더에 경로 지정
  • .getAbsolutePath()로 절대경로 얻음

효과음

  • res 폴더 안에 raw 폴더를 만들고, 그 안에 음원을 넣어두어야 실행 가능
  • final MediaPlayer mp = MediaPlayer.create(this, R.raw.phone_calling_tone); 으로 음원 설정
  • mp.start(); 음악 시작, mp.stop(); 음악 종료

타이머

  • Chronometer를 이용하여 작동
  • xml에서의 타입도 Chronometer이다

아래는 종합 코드


public class CallActivity extends AppCompatActivity {

    private Chronometer chronometer;
    int Record = 0;

    MediaRecorder recorder;
    String filename;
    String date;
    String phoneNum;

    // 파일명 날짜
    private String dateName(long dateTaken){
        Date date = new Date(dateTaken);
        SimpleDateFormat dateFormat =
                new SimpleDateFormat("yyyy-MM-dd_HH시mm분");
        return dateFormat.format(date);
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        }
    
        
    // 녹음파일
    // 파일명은 자유롭게 지정. 날짜를 넣기 위해 date 생성함
    date = dateName(System.currentTimeMillis());
    File sdcard = Environment.getExternalStorageDirectory();
    File file = new File(sdcard, "Recordings/" + phoneNum + "_" + date + ".m4a");   // 파일명
    filename = file.getAbsolutePath();

	// 효과음 후 전화연결, 통화시간 측정 (효과음 시간 맞춰서 조절)
    final MediaPlayer mp = MediaPlayer.create(this, R.raw.phone_calling_tone);
    mp.start();
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mp.stop();
            chronometer = findViewById(R.id.stopwatch);
            chronometer.setBase(SystemClock.elapsedRealtime());
            chronometer.start();
            // 녹음시작
            startRecording();
            voicekeeper.setImageResource(R.drawable.vk_color);
            }
        }, 6000); // 6초 지연

//  통화 종료
   ImageButton endcall = findViewById(R.id.endcalling);
   endcall.setOnClickListener(new View.OnClickListener(){
       @Override
       public void onClick(View v) {
            chronometer.stop();
            long pauseOffset = SystemClock.elapsedRealtime() - chronometer.getBase();
            int time = (int) (pauseOffset / 1000);
            int min = time % (60*60) / 60;
            int sec = time % 60;

            //녹음종료
            stopRecording(phoneNum);

            Intent callintent = new Intent(CallActivity.this, RecordActivity.class);
            callintent.putExtra("phoneNum", phoneNum);
            callintent.putExtra("min", String.valueOf(min));
            callintent.putExtra("sec", String.valueOf(sec));
            callintent.putExtra("sec", String.valueOf(sec));
            callintent.putExtra("filename", String.valueOf(filename));
            
            recorder = null;
            startActivity(callintent);
            finish();
            }
        });
    }
    
	public void startRecording(){
        recorder = new MediaRecorder();

        /* MediaRecorder 설정하기 */
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);     // 마이크로 입력 받기
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);    // MPEG4 포맷으로 지정
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);   // 디폴트 인코터 사용
        recorder.setOutputFile(filename);       // 결과물 파일을 설정하는데 사용

        try{
            recorder.prepare();
            recorder.start();
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void stopRecording(String phoneNum) {
        recorder.stop();
        recorder.release(); // 리소스 해제하는 역할

        ContentValues values = new ContentValues(10);
        values.put(MediaStore.Audio.Media.DISPLAY_NAME, phoneNum + "_" + date + ".m4a");
        values.put(MediaStore.Audio.Media.IS_PENDING, 1);
        values.put(MediaStore.Audio.Media.IS_MUSIC, 0);
        values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp4");

        ContentResolver contentResolver = getContentResolver();
        Uri item = contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);

//        recorder = null;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //권한을 허용 했을 경우
        if(requestCode == 1){
            int length = permissions.length;
            for (int i = 0; i < length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    // 동의
                    Log.d("MainActivity","권한 허용 : " + permissions[i]);
                }
            }
        }
    }

0개의 댓글