다음은 안드로이드에서 MediaRecorder와 MediaPlayer를 이용하여 소리를 녹음하고  재생하는 예시이다.

 

 

소스코드 보기 (Open)

 


 

 

setAudioSource() : 소리를 어디서부터 받아올지 설정한다.

  마이크를 녹음하거나 통화 중 목소리 녹음, 통화 중 발신자 목소리만 녹음, 통화 중 수신자 목소리만 녹음 등을 결정한다.

 

setOutputFormat() : 녹음 파일의 데이터 형식(format)을 설정한다.

 

setAudioEncoder() : 인코더(코덱)을 설정한다.

 

setOutputFile() : 녹음 파일의 경로 및 이름을 설정한다.

Posted by Kugi
TAG android

댓글을 달아 주세요




어플리케이션을 개발하다 보면 파일을 외장메모리 등에 저장해야 할 필요가 있다.

 

특정 경로를 지정해줬는데, 만약 해당 경로가 존재하지 않으면

 

error: No such file or directory

와 같은 에러를 뱉어내곤 한다.

 

해결하기 위해서는 다음과 같은 방법을 사용한다.

 

 

파일을 생성하기 전에 원하는 경로가 존재하는지 확인하고 만약 경로가 존재하지 않으면 생성한 후

 

파일을 생성할 경로를 반환해주는 메소드이다. 외장메모리의 유무도 확인한다.

 

	// Example
	public static synchronized String GetFilePath(int fileType, int fileId)
	{
		String sdcard = Environment.getExternalStorageState();
		File file = null;
		
		if ( !sdcard.equals(Environment.MEDIA_MOUNTED)) 
		{ 
			// SD카드가 마운트되어있지 않음
			file = Environment.getRootDirectory();
		}
		else
		{
			// SD카드가 마운트되어있음
			file = Environment.getExternalStorageDirectory();
		}

		
		String dir = file.getAbsolutePath() + String.format("/mytestdata/file_%02d", fileType);
		String path = file.getAbsolutePath() + String.format("/mytestdata/file_%02d/myfile%04d.mp4", fileType, fileId);

		file = new File(dir);
		if ( !file.exists() )
		{
			// 디렉토리가 존재하지 않으면 디렉토리 생성
			file.mkdirs();
		}
		
		// 파일 경로 반환
		return path;
	}

 

* 참고로 File 클래스의 멤버메소드에는 mkdirs()와 mkdir()이 있는데

 

 이름 그대로 mkdirs()는 목적지 경로까지 상위폴더를 포함하여 전체 경로를 생성하고, mkdir()은 지정한 폴더 하나만을 생성한다.

 

 둘 다 반환타입은 boolean으로, 경로 생성에 성공하면 true, 이미 존재하는 경로이거나 실패하면 false를 반환한다.

Posted by Kugi
TAG android

댓글을 달아 주세요




안드로이드의 SharedPreferences.Editor에는

비슷한 역할을 하는 apply()와 commit() 두 개의 메소드가 존재한다.

 

이 둘의 차이점을 알아보자.

 

(*아래 내용은 http://developer.android.com/reference/android/content/SharedPreferences.Editor.html 의 영어 원문 일부를 번역한 것이다.)

 

 

public abstract boolean commt()

 

해당 Editor에서 변경한 preferences 값을 이 Editor의 SharedPreferences 객체에 전달한다.

 

두 개의 Editor가 동시에 preferences를 수정 중이라면 마지막에 호출된 commit()가 적용된다.

 

만약 반환값을 필요로 하지 않는다면 apply()를 써도 좋다.

 

반환값: 변경한 값이 성공적으로 저장장치에 반영되면 true를 반환한다.

 

 

public abstract void apply()

 

해당 Editor에서 변경한 preferences 값을 이 Editor의 SharedPreferences 객체에 전달한다.

 

자동적으로, 원래 SharedPreferences 안의 내용이 무엇이었든간에 요청받은 값으로 내용을 대체한다.

 

두 개의 Editor가 동시에 preferences를 수정 중이라면 마지막에 호출된 apply()가 적용된다.

 

저장공간에 지속적인 동기를 유지하며 preferences를 작성하는 commit()과는 달리,

 

apply()는 메모리 내의 SharedPreferences를 즉시 변경하지만 디스크로의 반영은 비동기적으로 시작되며

 

작업 실패에 대한 어떠한 알림도 받을 수 없다.

 

SharedPreferences는 프로세스 내에서 싱글톤 방식의 인스턴스이기 때문에

 

만약 반환 값을 필요로 하지 않는다면 commit() 대신에 apply()를 쓰는 것이 안전하다.

 

apply()의 경우 안드로이드 컴포넌트의 라이프사이클 및 디스크 쓰기의 상호작용을 신경 쓸 필요가 없다.

 

구조적으로 apply()를 한 후에 이루어지는 in-flight 디스크의 쓰기는 상태(state) 전환이 이루어지기 전에 완료되도록 되어있다.

Posted by Kugi

댓글을 달아 주세요

  1. name 2014.12.27 17:38  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다!
    근데 SharedPreferences는 프로세스 내에서 싱글톤 방식의 인스턴스이기 때문에
    만약 반환 값을 필요로 하지 않는다면 commit() 대신에 apply()를 쓰는 것이 안전하다는 논리가 잘 이해가 안됩니다..
    좀 더 자세한 설명을 들을수 있을까요

    • Kugi 2014.12.27 21:33 신고  댓글주소  수정/삭제

      마지막 호출만 적용되는 commit()과 달리 apply()는 호출될 때마다 SharedPreferences 내용을 바꿔주기 때문입니다.

  2. 사긔 2016.10.04 16:50 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다! 노란 밑줄 뜨면서 apply로 변경하라기에 무슨 차이인가 했더니 이해하기 쉽게 설명해주셔서 도움이 되었습니다




안드로이드에서 현재 시간을 알아내기 위해서는 여러 가지 방법이 있겠지만 그 중에서 한 가지를 소개하자면

 

java.util.Calendar 오브젝트를 이용하는 것이다. java.util에 포함되어있기 때문에 물론 안드로이드 뿐만 아니라 일반 자바 프로젝트에서도 이용 가능하다.

 

다음은 사용 예시이다.

 

public static String GetCurrentTime() {
	String time = "";
	Calendar cal = Calendar.getInstance();
	time = String.format("%04d-%02d-%02d-%02d-%02d-%02d-%03d",
			cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),
			cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
		
	return time;
}

 

출력되는 포맷은 편의에 맞게 고치면 된다.

이 때 cal.get(Calendar.MONTH)는 "반환값+1"이 실제 달 수이므로 주의해야 한다.

0~12까지의 값을 반환하며 이는 각각 다음과 같이 매치된다.

  0 JANUARY
  1 FEBRUARY
  2 MARCH
  3 APRIL
  4 MAY
  5 JUNE
  6 JULY
  7 AUGUST
  8 SEPTEMBER
  9 OCTOBER
 10 NOVEMBER
 11 DECEMBER
 12 UNDECIMBER

 

시간(hour)을 얻어오는 cal.get(Calendar.HOUR_OF_DAY)는 24시 표현으로 시간 값으로 반환한다.

Posted by Kugi
TAG android, Java

댓글을 달아 주세요




안드로이드 프로그래밍을 위해 액티비티 레이아웃 xml 파일을 작업하다 보면

 

다음과 같은 Warning을 만날 수 있다.

 

[Accessibility] Missing contentDescription attribute on image

 

ImageView를 추가하고 이에 대한 contentDescrioption을 빼먹었다는 뜻이다.

 

무시해도 상관은 없지만 노란 경고 표시가 보기 싫다면

 

이 경고 메시지를 없애기 위한 3가지 방법이 있다.

 

첫번째 방법은 경고가 말하는대로 빠뜨린 contentDescription을 추가해주는 방법이다.

 

다음과 같이

 

android:contentDescription="@string/contentDescription"

 

를 추가해주면 경고가 사라진다.

 

 

 

contentDescription을 일일히 써주는게 싫다면 개별적인 경고를 무시하는 방법도 있다.

 

다음과 같이

 

tools:ignore="ContentDescription"

 

를 추가해주면 되는데, 이 때 tools를 사용하기 위해서는

 

xmlns:tools="http://schemas.android.com/tools"

 

가 추가되어있어야 하며 그렇지 않으면

 

error: Error parsing XML: unbound prefix

Attribute is missing the Android namespace prefix

 

이러한 에러가 생긴다.

 

이 방법을 적용하면 아래 이미지에서 볼 수 있듯이, ignore를 추가해준 부분에 대해서만 경고가 사라지게 된다.

 

 

 

마지막으로, 이상의 방법들이 모두 귀찮다면 아예 해당하는 모든 경고를 무시하는 방법이 있다.

 

이클립스의 메뉴중에서

 

[Windows -> Preferences -> Android -> Lint Error Checking]

 

을 찾아가서 contentDescription 항목을 warning 레벨에서 Ignore 레벨로 바꾸어주면 된다.

 

Posted by Kugi

댓글을 달아 주세요

  1. ds 2013.09.10 15:16  댓글주소  수정/삭제  댓글쓰기

    해당 자료 에러가 있네요..
    마지막 ignore 무턱대고 체크하면 전체 에러 발생합니다..

    • Kugi 2013.09.10 21:03 신고  댓글주소  수정/삭제

      전체 에러라는게 무슨 에러를 말씀하시는지요?
      다이얼로그 리스트의 ContentDescription 항목을 선택하고 Ignore로 설정하셔야 합니다.