애플리케이션의 res/raw/ 디렉터리에 저장된 로컬 원시 리소스로 사용 가능한 오디오를 재생하는 방법
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); // no need to call prepare(); create() does that for youURI는 정보의 고유한 명칭으로 웹 주소를 나타내는 URL보다 더 상위의 개념
File 타입: file://파일패스/파일이름
file:///storage/emulated/0/Pictures/camera_image.jpg안드로이드 리소스 타입: android.resource://패키지이름/리소스폴더/리소스이름
android.resource://com.example.kwanwoo.multimediatest/raw/instrumental컨텐츠 타입: content://정보제공자/패스/아이디
content://media/external/video/media/154Uri 클래스의 주요 메소드
static Uri parse(String uriString) - Uri문자열로부터 Uri 객체 생성
Uri image_Uri = Uri.parse("file:///storage/emulated/0/Pictures/camera_image.jpg");static Uri.fromFile(File file) - file로부터 Uri 객체 생성
Uri image_Uri = Uri.fromFile(
new File(getExternalFilesDir(Environment.DIRECTORY_PICTURE).getPath()+
"/"+
"camera_image.jpg")));사용방법
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(getApplicationContext(), myUri);
// or just mediaPlayer.setDataSource(mFileName);
mMediaPlayer.prepare();
mediaPlayer.start();인터넷 접근 권한(android.permission.INTERNET) 필요
AndroidMenifest.xml 파일에 다음 권한 추가
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
</manifest>Android Platform API 28 이상의 디바이스에서는 ClearText 지원이 기본적으로 비활성화되어 있다.
이를 활성화 시키기위해서, AndroidMenifest.xml 파일의 application 태그에 다음 속성값을 설정
<application
android:usesCleartextTraffic="true"
... >사용 방법 1 (UI 스레드에서 실행)
String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();사용방법 2 (별도의 스레드에서 비동기 실행)
String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(url);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();MediaPlayer는 귀중한 시스템 리소스를 소비할 수 있습니다. 따라서 항상 특히 주의를 기울여 필요 이상으로 오래 MediaPlayer 인스턴스를 유지하지 않는지 확인해야 합니다.
액티비티의 onStop() 콜백 메소드에서 MediaPlayer 해제
protected void onStop() {
mediaPlayer.release();
mediaPlayer = null;
}| 메소드 | 설명 |
|---|---|
| void pause() | 재생 일시 중지 |
| boolean isPlaying() | 재생 중인지 검사 |
| void seekTo(int msec) | msec 시간 위치로 재생 위치 이동 |
| int getCurrentPosition() | 현재 재생 위치를 반환 |
예제
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// ...
if (mMediaPlayer != null && mSelectedPosition == position) { // 이전 선택과 동일한 항목을 선택한 경우
if (mMediaPlayer.isPlaying()) { // 미디어가 재생 중인 경우
mPlaybackPosition = mMediaPlayer.getCurrentPosition();
mMediaPlayer.pause();
Toast.makeText(getApplicationContext(), "음악 파일 재생 중지됨.", Toast.LENGTH_SHORT).show();
} else { // 미디어가 재생 중이 아닌 경우
mMediaPlayer.seekTo(mPlaybackPosition);
mMediaPlayer.start();
Toast.makeText(getApplicationContext(), "음악 파일 재생 재시작됨.", Toast.LENGTH_SHORT).show();
}
} else { // 이전 선택과 다른 항목을 선택한 경우
// 미디어 재생
playAudioByUri(uri);
// 선택된 리스뷰 뷰 항목 위치 저장
mSelectedPosition = position;
}MediaPlayer로도 비디오 재생이 가능하나, VideoView 위젯을 이용하면 매우 간단히 비디오 재생이 가능
VideoView 활용 절차
Java 코딩
[선택사항] 미디어콘트롤러 설정

재생할 동영상 URI 설정
재생 시작

필요한 권한
<manifest ... >
<uses-permission android:name="android.permission.RECORD_AUDIO" />
</manifest>오디오 녹음 절차
[주의] Android 6.0 이상부터는 앱 실행 중에 권한 검사 및 요청 필요
앱 시작시에 앱에서 필요한 권한 보유여부를 검사하고 없으면 요청한다.
requestRecordAudioPermission() 메소드는 RECORD_AUDIO권한을 요청한다.
protected void onCreate(Bundle savedInstanceState) {
//...
if (haveRecordAudioPermission())
initListView();
else
requestRecordAudioPermission();
}
private boolean haveRecordAudioPermission() {
return ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO)
== PackageManager.PERMISSION_GRANTED;
}
private void requestRecordAudioPermission() {
String[] permissions = {
Manifest.permission.RECORD_AUDIO
};
ActivityCompat.requestPermissions(
this,
permissions,
REQUEST_RECORD_AUDIO_FOR_MULTIMEDIA);
}예제 코드
private void startAudioRec() {
* mMediaRecorder = new MediaRecorder();
* mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
* mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
* mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
// currentDateFormat(): 현재 시각을 “yyyyMMdd_HH_mm_ss” 형태로 반환
recFileN = "VOICE" + currentDateFormat() + ".mp4";
// 출력 파일의 위치를 앱 전용 외부저장소의 /Music/ 위치로 설정
* mMediaRecorder.setOutputFile(
* getExternalFilesDir(Environment.DIRECTORY_MUSIC).getPath()+"/" + recFileN);
try {
* mMediaRecorder.prepare();
Toast.makeText(getApplicationContext(), "녹음을 시작하세요.", Toast.LENGTH_SHORT).show();
* mMediaRecorder.start();
} catch (Exception ex) {
Log.e("SampleAudioRecorder", "Exception : ", ex);
}
} private void stopAudioRec() {
* mMediaRecorder.stop();
* mMediaRecorder.release();
mMediaRecorder = null;
Uri uri = Uri.parse("file://" +
getExternalFilesDir(Environment.DIRECTORY_MUSIC).getPath()+
"/" +
recFileN);
// 리스트 뷰의 항목으로 녹음된 파일 이름과 URI를 추가
mAdapter.addItem(new MediaItem(MediaItem.SDCARD, recFileN,uri));
Toast.makeText(getApplicationContext(), "녹음이 중지되었습니다.", Toast.LENGTH_SHORT).show();
}특별한 Permission이 필요 없음
카메라 앱 요청
private void dispatchTakePictureIntent() {
* Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// resolveActivity(): takePictureIntent를 처리할 수 있는 (사진찍기) 액티비티 반환
startActivity(takePictureIntent);
}
}Uri 객체를 Extras를 통해 카메라 앱으로 전달
[주의] Android 7.0 이상부터는 FileProvider의 getUriForFile(Context, String, File)를 통해 해당 파일 객체의 content://URI를 획득

[사전조건] 외부 저장소에 저장하기 위해서 Permission 획득 과정 필요
*Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
If (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// 1. 카메라 앱으로 찍은 이미지를 저장할 파일 객체 생성
mPhotoFileName = "IMG"+currentDateFormat()+".jpg";
mPhotoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),
mPhotoFileName);
if (mPhotoFile !=null) {
// 2. 생성된 파일 객체에 대한 Uri 객체를 얻기
Uri imageUri = FileProvider.getUriForFile(this,
"com.example.kwanwoo.multimediatest", mPhotoFile);
// 3. Uri 객체를 Extras를 통해 카메라 앱으로 전달
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
* startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
} else
Toast.makeText(getApplicationContext(), "file null", Toast.LENGTH_SHORT).show();
}onActivityResult() 메소드에서 저장된 사진을 이미지 뷰에 출력
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
if (mPhotoFileName != null) {
mPhotoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),
mPhotoFileName);
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageURI(Uri.fromFile(mPhotoFile)); }
}
}카메라 앱으로 전달
static final int REQUEST_VIDEO_CAPTURE = 2;
private void dispatchTakeVideoIntent() {
// 1. 동영상 캡처 작업 요청을 포함한 인텐트를 생성
* Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
//2. 카메라 앱으로 찍은 동영상을 저장할 파일 객체 생성
mVideoFileName = "VIDEO"+currentDateFormat()+".mp4";
File destination = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES),
mVideoFileName);
if (destination != null) {
//3. 생성된 파일 객체에 대한 Uri 객체를 얻기
Uri videoUri = FileProvider.getUriForFile(this,
"com.example.kwanwoo.multimediatest", destination);
//4. Uri 객체를 Extras를 통해 카메라 앱으로 전달
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
}
}onActivityResult() 메소드에서 결과 코드가 RESULT_OK인 경우에, 촬영 결과를 저장한 파일 이름을 리스뷰의 항목으로 추가
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
...생략...
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {
if (mVideoFileName != null) {
mAdapter.addItem(new MediaItem(
MediaItem.SDCARD,
mVideoFileName,
MediaItem.VIDEO));
} else
Toast.makeText(getApplicationContext(), "!!! null video.", Toast.LENGTH_LONG).show();
}
}특별한 Permission이 필요 없음
Photo/Gallery 앱 요청
private void dispatchPickPictureIntent() {
Intent pickPictureIntent = new Intent(Intent.ACTION_PICK);
pickPictureIntent.setType("image/*");
if (pickPictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(pickPictureIntent,REQUEST_IMAGE_PICK);
}
}
onActivityResult() 메소드에서 선택된 사진 결과를 이미지 뷰에 출력하기
선택된 사진 결과는 콘텐츠 Uri 형식으로 인텐트 객체를 통해 전달됨
Example
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_PICK && resultCode == RESULT_OK) {
Uri imgUri = data.getData();
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageURI(imgUri);
}
콘텐츠 Uri 형식의 사진 결과를 외부 저장소 파일로 저장하기
MediaStore.Images.Media 클래스의 getBitmap()를 통해 Uri로부터 비트맵 얻기
Bitmap getBitmap (ContentResolver cr, Uri url)Bitmap 클래스의 compress 메소드를 이용하면 비트맵을 다양한 형식으로 저장할 수 있다.
compress(Bitmap.CompressFormat format, int quality, OutputStream stream) Example
private void saveToExternalFile(Uri imgUri) {
try {
Bitmap imgBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imgUri);
mPhotoFileName = "IMG"+currentDateFormat()+".jpg";
mPhotoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), mPhotoFileName);
imgBitmap.compress(Bitmap.CompressFormat.JPEG,100,
new FileOutputStream(mPhotoFile));
} catch (IOException e) {}
}