Multimedia 1 v activitymain xml Linear Layout xmlns

  • Slides: 132
Download presentation
Multimedia 1

Multimedia 1

오디오 재생 v activity_main. xml 파일 수정 <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android"

오디오 재생 v activity_main. xml 파일 수정 <Linear. Layout 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" android: orientation="vertical" > <Button android: id="@+id/play. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin. Top="20 dp" android: width="180 dp" android: layout_gravity="center" android: text="재생" /> <Button android: id="@+id/pause. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin. Top="20 dp" android: width="180 dp" android: layout_gravity="center" android: text="중지" />

오디오 재생 <Button </Linear. Layout> android: id="@+id/restart. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin.

오디오 재생 <Button </Linear. Layout> android: id="@+id/restart. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin. Top="20 dp" android: width="180 dp" android: layout_gravity="center" android: text="재시작" />

오디오 재생 v Android. Manifest. xml 파일에 인터넷 사용 권한 추가 <uses-permission android: name="android.

오디오 재생 v Android. Manifest. xml 파일에 인터넷 사용 권한 추가 <uses-permission android: name="android. permission. INTERNET"/> v Android. Manifest. xml 파일의 Application 태그에 추가 android: uses. Cleartext. Traffic="true" v Main. Activity 오디오 재생 관련 프로퍼티 선언 static final String AUDIO_URL = "http: //sites. google. com/site/ubiaccessmobile/sample_audio. amr"; private Media. Player media. Player; private int playback. Position = 0;

오디오 재생 v Main. Activity 클래스에 오디오 재생 과 메모리 정리와 관련된 사용자 정의

오디오 재생 v Main. Activity 클래스에 오디오 재생 과 메모리 정리와 관련된 사용자 정의 메소드 생성 private void play. Audio(String url) throws Exception { kill. Media. Player(); //media. Player = new Media. Player(); //media. Player. set. Data. Source(url); //media. Player. prepare(); media. Player = Media. Player. create(this, R. raw. birthday); } media. Player. start(); private void kill. Media. Player() { if (media. Player != null) { try { media. Player. release(); } catch (Exception e) { e. print. Stack. Trace(); } } }

오디오 재생 v Main. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드 재정의 //액티비티가 종료

오디오 재생 v Main. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드 재정의 //액티비티가 종료 될 때 호출되는 메소드 @Override protected void on. Destroy() { super. on. Destroy(); kill. Media. Player(); }

오디오 재생 v Main. Activity 클래스의 on. Create 메소드에 버튼 클릭 이벤트 작성 Button

오디오 재생 v Main. Activity 클래스의 on. Create 메소드에 버튼 클릭 이벤트 작성 Button start. Btn = (Button) find. View. By. Id(R. id. play. Btn); Button pause. Btn = (Button) find. View. By. Id(R. id. pause. Btn); Button restart. Btn = (Button) find. View. By. Id(R. id. restart. Btn); start. Btn. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View view) { try { play. Audio(AUDIO_URL); Snackbar. make(view, "음악 파일 재생 시작됨. ", Snackbar. LENGTH_SHORT). show(); } catch (Exception e) { e. print. Stack. Trace(); } } });

오디오 재생 v Main. Activity 클래스의 on. Create 메소드에 버튼 클릭 이벤트 작성 pause.

오디오 재생 v Main. Activity 클래스의 on. Create 메소드에 버튼 클릭 이벤트 작성 pause. Btn. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View view) { if (media. Player != null) { playback. Position = media. Player. get. Current. Position(); media. Player. pause(); Snackbar. make(view, "음악 파일 재생 중지됨. ", Snackbar. LENGTH_SHORT). show(); } } }); restart. Btn. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View view) { if (media. Player != null && !media. Player. is. Playing()) { media. Player. start(); media. Player. seek. To(playback. Position); Snackbar. make(view, "음악 파일 재생 재시작됨. ", Snackbar. LENGTH_SHORT). show(); } } });

오디오 재생 v 상태의 변화 ü 각 리스너 인터페이스에는 이벤트를 받는 메서드가 정의되어 있고

오디오 재생 v 상태의 변화 ü 각 리스너 인터페이스에는 이벤트를 받는 메서드가 정의되어 있고 이벤트와 관련된 인수가 전달 l void set. On. Error. Listener (Media. Player. On. Error. Listener listener) l void set. On. Prepared. Listener (Media. Player. On. Prepared. Listener listener) l void set. On. Completion. Listener (Media. Player. On. Completion. Listener listener) l void set. On. Buffering. Update. Listener (Media. Player. On. Buffering. Update. Listener listener) l void set. On. Seek. Complete. Listener (Media. Player. On. Seek. Complete. Listener listener) ü on. Completion 콜백은 스트림을 끝까지 재생했을 때 호출되며 이 때 객체는 재생 완료(Playback Completed)상태 ü 실행 중에 미디어를 오픈하는 set. Data. Source 메서드는 Idle 상태에서만 호출 가능하므로 reset 해야 만 미디어를 교체할 수 있음 ü on. Buffering. Update 콜백은 스트리밍시에 버퍼에 새로운 데이터가 들어왔을 때 호출

오디오 재생 v 실행 가능한 Activity 생성 – Play. Audio. Activity v activity_play_audio. xml

오디오 재생 v 실행 가능한 Activity 생성 – Play. Audio. Activity v activity_play_audio. xml 파일 수정 <? xml version="1. 0" encoding="utf-8"? > <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android" android: orientation="vertical" android: layout_width="fill_parent" android: layout_height="fill_parent" > <Text. View android: id="@+id/filename" android: layout_width="wrap_content" android: layout_height="wrap_content" android: text. Size="16 sp" android: text="파일 : " android: layout_margin. Top="10 dip" android: layout_margin. Bottom="10 dip" /> <Linear. Layout android: orientation="horizontal" android: layout_width="fill_parent" android: layout_height="wrap_content" >

오디오 재생 <Button android: id="@+id/play" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m.

오디오 재생 <Button android: id="@+id/play" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m. On. Click" android: text="Play" /> <Button android: id="@+id/stop" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m. On. Click" android: text="Stop" /> <Button android: id="@+id/prev" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m. On. Click" android: text="Prev" />

오디오 재생 <Button android: id="@+id/next" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m.

오디오 재생 <Button android: id="@+id/next" android: layout_width="fill_parent" android: layout_height="wrap_content" android: layout_weight="1" android: on. Click="m. On. Click" android: text="Next" /> </Linear. Layout> <Seek. Bar android: id="@+id/progress" android: layout_width="fill_parent" android: layout_height="wrap_content" android: max="100" android: progress="0" android: padding="10 dip" /> </Linear. Layout>

오디오 재생 v Play. Audio. Activity 클래스에 노래 제목을 출력하고 재생 준비 상태를 알려주는

오디오 재생 v Play. Audio. Activity 클래스에 노래 제목을 출력하고 재생 준비 상태를 알려주는 핸들러 작성 //노래 제목 과 진행률을 표시해주는 핸들러 Handler message. Hander = new Handler(Looper. get. Main. Looper()) { public void handle. Message(Message msg) { boolean result = (Boolean) msg. obj; String result. Msg = null; if (result == true) { result. Msg = "재생 준비 완료"; file. Name. set. Text("파일 : " + list. get(msg. what)); progress. set. Max(player. get. Duration()); } else { result. Msg = "재생 준비 실패"; } Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), result. Msg, Snackbar. LENGTH_LONG). show(); if (result == false) { finish(); } } };

오디오 재생 v Play. Audio. Activity 클래스에 음원 재생과 관련된 사용자 정의 메소드 선언

오디오 재생 v Play. Audio. Activity 클래스에 음원 재생과 관련된 사용자 정의 메소드 선언 //노래 준비를 수행해주는 메소드 private boolean prepare() { try { player. prepare(); } catch (Illegal. State. Exception e) { return false; } catch (IOException e) { return false; } return true; }

오디오 재생 v Play. Audio. Activity 클래스에 음원 재생과 관련된 사용자 정의 메소드 선언

오디오 재생 v Play. Audio. Activity 클래스에 음원 재생과 관련된 사용자 정의 메소드 선언 //노래의 인덱스를 받아서 준비 상태로 만들고 그 결과를 핸들러에게 전송하는 메소드 private void load. Media(int idx) { Message message = new Message(); message. what = idx; try { player. set. Data. Source(this, Uri. parse(list. get(idx))); } catch (Exception e) { message. obj = false; } if (prepare() == false) { message. obj = false; } else { message. obj = true; } message. Hander. send. Message(message); }

오디오 재생 v Play. Audio. Activity 클래스에 진행률을 표시해주는 핸들러를 작성 // 0. 2초에

오디오 재생 v Play. Audio. Activity 클래스에 진행률을 표시해주는 핸들러를 작성 // 0. 2초에 한번꼴로 재생 위치fmf 갱신 해주는 핸들러 Handler progress. Handler = new Handler(Looper. get. Main. Looper()) { public void handle. Message(Message msg) { if (player == null) return; if (player. is. Playing()) { progress. set. Progress(player. get. Current. Position()); } progress. Handler. send. Empty. Message. Delayed(0, 200); } };

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 //파일이름을 출력할 뷰 찾아오기 file. Name = (Text. View) find. View. By. Id(R. id. filename); list = new Array. List<String>();

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 //노래 목록을 가져오는 스레드 new Thread() { public void run() { try { String addr = "http: //cyberadam. cafe 24. com/song/"; java. net. URL url = new URL(addr + "song. txt"); Http. URLConnection con = (Http. URLConnection) url. open. Connection(); Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(con. get. Input. Stream())); String. Builder sb = new String. Builder(); while (true) { String line = br. read. Line(); if (line == null) { break; } sb. append(line + "n"); } String str = sb. to. String(); String[] song. List = str. split(", "); for (String song : song. List) { list. add(addr + song + ". mp 3"); } Log. e("목록 준비 완료", list. to. String());

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 player = new Media. Player(); idx = 0; load. Media(idx); // 완료 리스너, 시크바 변경 리스너 등록 progress = (Seek. Bar) find. View. By. Id(R. id. progress); // 재생 완료되면 다음곡으로 player. set. On. Completion. Listener(new Media. Player. On. Completion. Listener() { @Override public void on. Completion(Media. Player mp) { idx = (idx == list. size() - 1 ? 0 : idx + 1); player. reset(); load. Media(idx); player. start(); } });

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 // 에러 발생시 메시지 출력 player. set. On. Error. Listener(new Media. Player. On. Error. Listener() { @Override public boolean on. Error(Media. Player mp, int what, int extra) { String err = "On. Error occured. what = " + what + " , extra = " + extra; Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), err, Snackbar. LENGTH_LONG). show(); return false; } }); // 위치 이동 완료 처리 player. set. On. Seek. Complete. Listener(new Media. Player. On. Seek. Complete. Listener() { @Override public void on. Seek. Complete(Media. Player mp) { if (was. Playing) { player. start(); } } });

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 // 재생 위치 이동 progress. set. On. Seek. Bar. Change. Listener(new Seek. Bar. On. Seek. Bar. Change. Listener() { public void on. Progress. Changed(Seek. Bar seek. Bar, int progress, boolean from. User) { if (from. User) { player. seek. To(progress); } } public void on. Start. Tracking. Touch(Seek. Bar seek. Bar) { was. Playing = player. is. Playing(); if (was. Playing) { player. pause(); } } public void on. Stop. Tracking. Touch(Seek. Bar seek. Bar) { } }); progress. Handler. send. Empty. Message. Delayed(0, 200); } catch (Exception e) { Log. e("목록 다운로드 예외", e. get. Message()); e. print. Stack. Trace(); } } }. start();

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 play. Btn = (Button) find. View. By. Id(R. id. play); play. Btn. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { if (player. is. Playing() == false) { player. start(); play. Btn. set. Text("Pause"); } else { player. pause(); play. Btn. set. Text("Play"); } } }); stop. Btn = (Button) find. View. By. Id(R. id. stop); stop. Btn. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { player. stop(); play. Btn. set. Text("Play"); progress. set. Progress(0); prepare(); } });

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 prev. Btn = (Button) find. View. By. Id(R. id. prev); prev. Btn. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { boolean was. Playing = player. is. Playing(); idx = (idx == 0 ? list. size() - 1 : idx - 1); player. reset(); load. Media(idx); } // 이전에 재생중이었으면 다음 곡 바로 재생 if (was. Playing) { player. start(); play. Btn. set. Text("Pause"); }

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성

오디오 재생 v Play. Audio. Activity 클래스의 on. Create 메소드에 초기화를 위한 코드를 작성 next. Btn = (Button) find. View. By. Id(R. id. next); next. Btn. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { boolean was. Playing = player. is. Playing(); idx = (idx == list. size() - 1 ? 0 : idx + 1); player. reset(); load. Media(idx); } // 이전에 재생중이었으면 다음 곡 바로 재생 if (was. Playing) { player. start(); play. Btn. set. Text("Pause"); }

오디오 재생 v Play. Audio. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드를 재정의 //

오디오 재생 v Play. Audio. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드를 재정의 // 액티비티 종료시 재생 강제 종료 public void on. Destroy() { super. on. Destroy(); if (player != null) { player. release(); player = null; } }

실로폰 v 8개의 사운드 파일을 res/raw 디렉토리에 복사 v 실행 가능한 Activity 생성(Xylophone. Activity)

실로폰 v 8개의 사운드 파일을 res/raw 디렉토리에 복사 v 실행 가능한 Activity 생성(Xylophone. Activity) v Xylophone. Activity. kt 파일의 on. Create 파일의 내용을 수정해서 가로 모드로 고정 override fun on. Create(saved. Instance. State: Bundle? ) { this. requested. Orientation = Activity. Info. SCREEN_ORIENTATION_LANDSCAPE super. on. Create(saved. Instance. State) set. Content. View(R. layout. activity_xylophone) }

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <? xml version="1. 0" encoding="utf-8"?

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <? xml version="1. 0" encoding="utf-8"? > <androidx. constraintlayout. widget. Constraint. Layout xmlns: android="http: //schemas. android. com/apk/res/android" xmlns: app="http: //schemas. android. com/apk/res-auto" xmlns: tools="http: //schemas. android. com/tools" android: layout_width="match_parent" android: layout_height="match_parent" tools: context=". Xylophone. Activity">

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/do 1"

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/do 1" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="16 dp" android: layout_margin. Bottom="16 dp" android: background="@android: color/holo_red_dark" android: gravity="center" android: text="도" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/re" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Horizontal_chain. Style="spread" app: layout_constraint. Start_to. Start. Of="parent" app: layout_constraint. Top_to. Top. Of="parent" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/re" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/re" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="24 dp" android: layout_margin. Bottom="24 dp" android: background="@android: color/holo_orange_dark" android: gravity="center" android: text="레" android: text. Alignment="center" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/mi" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/do 1" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/mi" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/mi" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="32 dp" android: layout_margin. Bottom="32 dp" android: background="@android: color/holo_orange_light" android: gravity="center" android: text="미" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/fa" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/re" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/fa" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/fa" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="40 dp" android: layout_margin. Bottom="40 dp" android: background="@android: color/holo_green_light" android: gravity="center" android: text="파" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/sol" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/mi" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/sol" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/sol" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="48 dp" android: layout_margin. Bottom="48 dp" android: background="@android: color/holo_blue_light" android: gravity="center" android: text="솔" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/la" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/fa" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/la" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/la" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="56 dp" android: layout_margin. Bottom="56 dp" android: background="@android: color/holo_blue_dark" android: gravity="center" android: text="라" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/si" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/sol" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/si" android:

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/si" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="64 dp" android: layout_margin. Bottom="64 dp" android: background="@android: color/holo_purple" android: gravity="center" android: text="시" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. Start. Of="@+id/do 2" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/la" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" />

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/do 2"

실로폰 v activity_xlyophone. xml 파일을 수정해서 실로폰 모양 만들기 <Text. View android: id="@+id/do 2" android: layout_width="50 dp" android: layout_height="0 dp" android: layout_margin. Top="72 dp" android: layout_margin. Bottom="72 dp" android: background="@android: color/holo_red_dark" android: gravity="center" android: text="도" android: text. Appearance="@style/Text. Appearance. App. Compat. Large" android: text. Color="@android: color/white" app: layout_constraint. Bottom_to. Bottom. Of="parent" app: layout_constraint. End_to. End. Of="parent" app: layout_constraint. Horizontal_bias="0. 5" app: layout_constraint. Start_to. End. Of="@+id/si" app: layout_constraint. Top_to. Top. Of="parent" app: layout_constraint. Vertical_bias="0. 0" /> </androidx. constraintlayout. widget. Constraint. Layout>

실로폰 v Xlyophone. Activity 클래스에 실로폰을 위한 프로퍼티 선언 //텍스트 뷰와 사운드 파일이름을 쌍으로

실로폰 v Xlyophone. Activity 클래스에 실로폰을 위한 프로퍼티 선언 //텍스트 뷰와 사운드 파일이름을 쌍으로 저장하기 만들기 private Array. List<Pair> sounds; //사운드 풀 private Sound. Pool sound. Pool; //노래를 가져오고 텍스트 뷰의 클릭 이벤트 처리를 위한 함수 private void tune(Pair<Integer, Integer> pitch ) { int sound. Id = sound. Pool. load(this, pitch. second, 1); find. View. By. Id(pitch. first). set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { sound. Pool. play(sound. Id, 1. 0 f, 0, 0, 1. 0 f); } }); }

실로폰 v Xlyophone. Activity 클래스의 on. Create 메소드에 초기화 코드 추가 //운영체제 버전에 따라

실로폰 v Xlyophone. Activity 클래스의 on. Create 메소드에 초기화 코드 추가 //운영체제 버전에 따라 사운드 풀 생성 if (Build. VERSION. SDK_INT >= Build. VERSION_CODES. LOLLIPOP) { sound. Pool = new Sound. Pool. Builder(). set. Max. Streams(8). build(); } else { sound. Pool = new Sound. Pool(8, Audio. Manager. STREAM_MUSIC, 0); } //텍스트 뷰의 아이디 와 사운드를 쌍으로 저장 Pair [] pairs = { new Pair(R. id. do 1, R. raw. do 1), new Pair(R. id. re, R. raw. re), new Pair(R. id. mi, R. raw. mi), new Pair(R. id. fa, R. raw. fa), new Pair(R. id. sol, R. raw. sol), new Pair(R. id. la, R. raw. la), new Pair(R. id. si, R. raw. si), new Pair(R. id. do 2, R. raw. do 2)}; sounds = new Array. List(Arrays. as. List(pairs)); //텍스트 뷰에 이벤트 연결 for(Pair<Integer, Integer> pair : sounds){ tune(pair); }

실로폰 v Xlyophone. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드 재정의 @Override protected void

실로폰 v Xlyophone. Activity 클래스에 Activity가 소멸될 때 호출되는 메소드 재정의 @Override protected void on. Destroy() { super. on. Destroy(); sound. Pool. release(); }

비디오 재생 v 실행 가능한 Activity 생성(Video. Play. Activity) v res/raw 디렉토리에 trailer. mp

비디오 재생 v 실행 가능한 Activity 생성(Video. Play. Activity) v res/raw 디렉토리에 trailer. mp 4 파일을 복사

비디오 재생 v activity_play_video. xml 파일 수정 <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android"

비디오 재생 v activity_play_video. xml 파일 수정 <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android" android: layout_width="match_parent" android: layout_height="match_parent" android: orientation="vertical" > <Button android: id="@+id/start. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin. Top="20 dp" android: width="180 dp" android: layout_gravity="center" android: text="재생"/> <Button android: id="@+id/volume. Btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_margin. Top="20 dp" android: width="180 dp" android: layout_gravity="center" android: text="볼륨조절: 최대로"/>

비디오 재생 v activity_play_video. xml 파일 수정 <Video. View android: id="@+id/video. View" android: layout_width="match_parent"

비디오 재생 v activity_play_video. xml 파일 수정 <Video. View android: id="@+id/video. View" android: layout_width="match_parent" android: layout_height="match_parent" android: layout_margin. Top="20 dp"/> </Linear. Layout>

비디오 재생 v Play. Video. Activity 클래스에 프로퍼티 선언 //비디오 URL static final String

비디오 재생 v Play. Video. Activity 클래스에 프로퍼티 선언 //비디오 URL static final String VIDEO_URL = "http: //sites. google. com/site/ubiaccessmobile/sample_video. mp 4"; //비디오 재생 뷰 private Video. View video. View;

비디오 재생 v Play. Video. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button

비디오 재생 v Play. Video. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button start. Btn = (Button)find. View. By. Id(R. id. start. Btn); Button volume. Btn = (Button)find. View. By. Id(R. id. volume. Btn); //비디오 재생 start. Btn. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View view) { video. View. seek. To(0); video. View. start(); } }); //볼륨을 최대로 설정 volume. Btn. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View view) { Audio. Manager m. Audio. Manager = (Audio. Manager) get. System. Service(AUDIO_SERVICE); int max. Volume = m. Audio. Manager. get. Stream. Max. Volume(Audio. Manager. STREAM_MUSIC); m. Audio. Manager. set. Stream. Volume(Audio. Manager. STREAM_MUSIC, max. Volume, Audio. Manager. FLAG_SHOW_UI); } });

비디오 재생 v Play. Video. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 video.

비디오 재생 v Play. Video. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 video. View = (Video. View) find. View. By. Id(R. id. video. View); Media. Controller mc = new Media. Controller(this); video. View. set. Media. Controller(mc); video. View. set. Video. URI(Uri. parse(VIDEO_URL)); //raw 디렉토리 경로 설정 //String path = "android. resource: //" + get. Package. Name() + "/" + R. raw. trailer; //video. View. set. Video. URI(Uri. parse(path)); video. View. request. Focus(); video. View. set. On. Prepared. Listener(new Media. Player. On. Prepared. Listener() { public void on. Prepared(Media. Player player) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "동영상이 준비되었습니다. n'재생' 버튼을 누르세요. ", Snackbar. LENGTH_LONG). show(); } }); video. View. set. On. Completion. Listener(new Media. Player. On. Completion. Listener() { public void on. Completion(Media. Player player) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "동영상 재생이 완료되었습 니다. ", Snackbar. LENGTH_LONG). show(); } });

오디오 녹음 v 오디오 녹음 ü 객체를 리셋하거나 해제 void release () void reset

오디오 녹음 v 오디오 녹음 ü 객체를 리셋하거나 해제 void release () void reset () ü 프로파일은 하드웨어의 능력치를 조사하는 읽기 전용의 클래스인데 응용 프로그램이 하드웨어의 모 든 능력을 십분 활용할 수 있다. void set. Audio. Encoding. Bit. Rate (int bit. Rate) void set. Audio. Sampling. Rate (int sampling. Rate) void set. Video. Encoding. Bit. Rate (int bit. Rate) void set. Profile (Camcorder. Profile profile) ü 녹음을 하려면 다음 두 개의 퍼미션이 필요 RECORD_AUDIO WRITE_EXTERNAL_STORAGE

오디오 녹음 v Android. Manifest. xml 파일에 필요한 권한 부여 <uses-permission android: name="android. permission.

오디오 녹음 v Android. Manifest. xml 파일에 필요한 권한 부여 <uses-permission android: name="android. permission. RECORD_AUDIO" /> <uses-permission android: name="android. permission. WRITE_EXTERNAL_STORAGE" /> <uses-permission android: name="android. permission. READ_EXTERNAL_STORAGE" /> v 권한 확인 라이브러리의 의존성을 설정 – 프로젝트 수준의 build. gradle 파일에 추가 allprojects { repositories { google() jcenter() maven { url 'https: //jitpack. io' } } }

오디오 녹음 v 권한 확인 라이브러리의 의존성을 설정 – 모듈 수준의 build. gradle 파일에

오디오 녹음 v 권한 확인 라이브러리의 의존성을 설정 – 모듈 수준의 build. gradle 파일에 추가 dependencies { implementation 'com. github. pedro. SG 94: Auto. Permissions: 1. 0. 3' implementation file. Tree(dir: 'libs', include: ['*. jar']) implementation 'androidx. appcompat: 1. 1. 0' implementation 'androidx. constraintlayout: 1. 1. 3' test. Implementation 'junit: 4. 12' android. Test. Implementation 'androidx. test. ext: junit: 1. 1. 1' android. Test. Implementation 'androidx. test. espresso: espresso-core: 3. 2. 0' }

오디오 녹음 v 실행 가능한 Activity 추가(Audio. Record. Activity) v activity_audio_record. xml 파일 수정

오디오 녹음 v 실행 가능한 Activity 추가(Audio. Record. Activity) v activity_audio_record. xml 파일 수정 <? xml version="1. 0" encoding="utf-8"? > <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android" xmlns: app="http: //schemas. android. com/apk/res-auto" xmlns: tools="http: //schemas. android. com/tools" android: layout_width="match_parent" android: layout_height="match_parent" android: orientation="vertical" tools: context=". Main. Activity"> <Button android: id="@+id/button" android: layout_width="match_parent" android: layout_height="wrap_content" android: text="녹음시작" /> <Button android: id="@+id/button 2" android: layout_width="match_parent" android: layout_height="wrap_content" android: text="녹음중지" />

오디오 녹음 <Button android: id="@+id/button 3" android: layout_width="match_parent" android: layout_height="wrap_content" android: text="재생시작" /> <Button

오디오 녹음 <Button android: id="@+id/button 3" android: layout_width="match_parent" android: layout_height="wrap_content" android: text="재생시작" /> <Button android: id="@+id/button 4" android: layout_width="match_parent" android: layout_height="wrap_content" android: text="재생중지" /> </Linear. Layout>

오디오 녹음 v Audio. Record. Activity 클래스 선언부 변경 public class Audio. Record. Activity

오디오 녹음 v Audio. Record. Activity 클래스 선언부 변경 public class Audio. Record. Activity extends App. Compat. Activity implements Auto. Permissions. Listener { v Audio. Record. Activity 클래스에 프로퍼티 추가 Media. Recorder recorder; Media. Player player; String filename;

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생 중지를 위한 사 용자 정의 메소드 선언 public void start. Recording() { if (recorder == null) { recorder = new Media. Recorder(); } recorder. set. Audio. Source(Media. Recorder. Audio. Source. MIC); recorder. set. Output. Format(Media. Recorder. Output. Format. MPEG_4); recorder. set. Audio. Encoder(Media. Recorder. Audio. Encoder. DEFAULT); recorder. set. Output. File(filename); } try { recorder. prepare(); recorder. start(); } catch (Exception e) { Log. e("Sample. Audio. Recorder", e. get. Localized. Message()); e. print. Stack. Trace(); }

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생 중지를 위한 사 용자 정의 메소드 선언 public void stop. Recording() { try { if (recorder == null) { return; } recorder. stop(); recorder. release(); recorder = null; Content. Values values = new Content. Values(10); values. put(Media. Store. Media. Columns. TITLE, "Recorded"); values. put(Media. Store. Audio. Media. ALBUM, "Audio Album"); values. put(Media. Store. Audio. Media. ARTIST, "Mike"); values. put(Media. Store. Audio. Media. DISPLAY_NAME, "Recorded Audio"); values. put(Media. Store. Audio. Media. IS_RINGTONE, 1); values. put(Media. Store. Audio. Media. IS_MUSIC, 1); values. put(Media. Store. Media. Columns. DATE_ADDED, System. current. Time. Millis() / 1000); values. put(Media. Store. Media. Columns. MIME_TYPE, "audio/mp 4"); values. put(Media. Store. Audio. Media. DATA, filename);

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생 중지를 위한 사 용자 정의 메소드 선언 Uri audio. Uri = get. Content. Resolver(). insert(Media. Store. Audio. Media. EXTERNAL_CONTENT_URI, values); if (audio. Uri == null) { Log. e("Sample. Audio. Recorder", "Audio insert failed. "); return; } }catch (Exception e){ Log. e("Sample. Audio. Recorder", e. get. Localized. Message()); } }

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생 중지를 위한 사 용자 정의 메소드 선언 public void start. Play() { kill. Media. Player(); } try { player = new Media. Player(); player. set. Data. Source("file: //" + filename); player. prepare(); player. start(); } catch(Exception e) { e. print. Stack. Trace(); } public void stop. Play() { if (player != null) { player. stop(); } }

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생

오디오 녹음 v Audio. Record. Activity 클래스에 오디오 녹음 시작, 녹음 중지, 오디오 재생 중지를 위한 사 용자 정의 메소드 선언 private void kill. Media. Player() { if (player != null) { try { player. release(); } catch (Exception e) { e. print. Stack. Trace(); } } }

오디오 녹음 v Audio. Record. Activity 클래스에 권한 설정 관련 메소드를 재정의 //권한을 요청하는

오디오 녹음 v Audio. Record. Activity 클래스에 권한 설정 관련 메소드를 재정의 //권한을 요청하는 메소드 @Override public void on. Request. Permissions. Result(int request. Code, String permissions[], int[] grant. Results) { super. on. Request. Permissions. Result(request. Code, permissions, grant. Results); Auto. Permissions. Companion. parse. Permissions(this, request. Code, permissions, this); } //거부한 권한에 대한 정보를 알려주는 메소드 @Override public void on. Denied(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions denied : " + permissions. length, Snackbar. LENGTH_LONG). show(); } @Override //허용한 권한에 대한 정보를 알려주는 메소드 public void on. Granted(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions granted : " + permissions. length, Snackbar. LENGTH_LONG). show(); }

오디오 녹음 v Audio. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button

오디오 녹음 v Audio. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button button = find. View. By. Id(R. id. button); button. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { start. Recording(); } }); Button button 2 = find. View. By. Id(R. id. button 2); button 2. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { stop. Recording(); } }); Button button 3 = find. View. By. Id(R. id. button 3); button 3. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { start. Play(); } });

오디오 녹음 v Audio. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button

오디오 녹음 v Audio. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button button 4 = find. View. By. Id(R. id. button 4); button 4. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { stop. Play(); } }); String file. Dir = get. Files. Dir(). get. Absolute. Path(); filename = file. Dir + File. separator + "recorded. mp 4"; Auto. Permissions. Companion. load. All. Permissions(this, 101);

비디오 녹화 v Android. Manifest. xml 파일에 필요한 권한 설정 <uses-permission android: name="android. permission.

비디오 녹화 v Android. Manifest. xml 파일에 필요한 권한 설정 <uses-permission android: name="android. permission. WRITE_EXTERNAL_STORAGE" /> <uses-permission android: name="android. permission. READ_EXTERNAL_STORAGE" /> <uses-permission android: name="android. permission. CAMERA" /> <uses-feature android: name="android. hardware. camera" android: required="true" />

비디오 녹화 v 실행 가능한 Activity 추가(Video. Record. Activity) v activity_video_record. xml 파일 수정

비디오 녹화 v 실행 가능한 Activity 추가(Video. Record. Activity) v activity_video_record. xml 파일 수정 <Linear. Layout xmlns: android="http: //schemas. android. com/apk/res/android" android: layout_width="match_parent" android: layout_height="match_parent" android: orientation="vertical" > <Button android: id="@+id/button" android: layout_width="wrap_content" android: layout_height="wrap_content" android: width="180 dp" android: layout_gravity="center" android: text="녹화시작" /> <Button android: id="@+id/button 2" android: layout_width="wrap_content" android: layout_height="wrap_content" android: width="180 dp" android: layout_gravity="center" android: text="녹화중지" />

비디오 녹화 v activity_video_record. xml 파일 수정 <Button android: id="@+id/button 3" android: layout_width="wrap_content" android:

비디오 녹화 v activity_video_record. xml 파일 수정 <Button android: id="@+id/button 3" android: layout_width="wrap_content" android: layout_height="wrap_content" android: width="180 dp" android: layout_gravity="center" android: text="재생시작" /> <Button android: id="@+id/button 4" android: layout_width="wrap_content" android: layout_height="wrap_content" android: width="180 dp" android: layout_gravity="center" android: text="재생중지" /> <Frame. Layout android: layout_width="match_parent" android: layout_height="match_parent" android: id="@+id/container" /> </Linear. Layout>

비디오 녹화 v Video. Record. Activity 클래스의 선언부 수정 public class Video. Record. Activity

비디오 녹화 v Video. Record. Activity 클래스의 선언부 수정 public class Video. Record. Activity extends App. Compat. Activity implements Auto. Permissions. Listener { v Video. Record. Activity 클래스에 프로퍼티 수정 Media. Player player; Media. Recorder recorder; String filename; Surface. Holder holder;

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void start. Recording()

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void start. Recording() { if (recorder == null) { recorder = new Media. Recorder(); } recorder. set. Audio. Source(Media. Recorder. Audio. Source. MIC); recorder. set. Video. Source(Media. Recorder. Video. Source. CAMERA); recorder. set. Output. Format(Media. Recorder. Output. Format. MPEG_4); recorder. set. Audio. Encoder(Media. Recorder. Audio. Encoder. DEFAULT); recorder. set. Video. Encoder(Media. Recorder. Video. Encoder. DEFAULT); recorder. set. Output. File(filename); recorder. set. Preview. Display(holder. get. Surface());

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 try { recorder. prepare();

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 try { recorder. prepare(); recorder. start(); } catch (Exception e) { e. print. Stack. Trace(); recorder. release(); recorder = null; } }

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void stop. Recording()

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void stop. Recording() { if (recorder == null) { return; } recorder. stop(); recorder. reset(); recorder. release(); recorder = null; Content. Values values = new Content. Values(10); values. put(Media. Columns. TITLE, "Recorded. Video"); values. put(Audio. Media. ALBUM, "Video Album"); values. put(Audio. Media. ARTIST, "Mike"); values. put(Audio. Media. DISPLAY_NAME, "Recorded Video"); values. put(Media. Columns. DATE_ADDED, System. current. Time. Millis() / 1000); values. put(Media. Columns. MIME_TYPE, "video/mp 4"); values. put(Audio. Media. DATA, filename);

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 Uri video. Uri =

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 Uri video. Uri = get. Content. Resolver(). insert(Video. Media. EXTERNAL_CONTENT_URI, values); if (video. Uri == null) { Log. d("Sample. Video. Recorder", "Video insert failed. "); return; } send. Broadcast(new Intent(Intent. ACTION_MEDIA_SCANNER_SCAN_FILE, video. Uri)); }

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void start. Play()

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void start. Play() { if (player == null) { player = new Media. Player(); } try { player. set. Data. Source(filename); player. set. Display(holder); player. prepare(); player. start(); } catch (Exception e) { e. print. Stack. Trace(); } }

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void stop. Play()

비디오 녹화 v Video. Record. Activity 클래스에 사용자 정의 메소드 public void stop. Play() { if (player == null) { return; } player. stop(); player. release(); player = null; }

비디오 녹화 v Video. Record. Activity 클래스에 권한 요청을 위한 메소드를 재정의 //권한을 요청하는

비디오 녹화 v Video. Record. Activity 클래스에 권한 요청을 위한 메소드를 재정의 //권한을 요청하는 메소드 @Override public void on. Request. Permissions. Result(int request. Code, String permissions[], int[] grant. Results) { super. on. Request. Permissions. Result(request. Code, permissions, grant. Results); Auto. Permissions. Companion. parse. Permissions(this, request. Code, permissions, this); } //거부한 권한에 대한 정보를 알려주는 메소드 @Override public void on. Denied(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions denied : " + permissions. length, Snackbar. LENGTH_LONG). show(); }

비디오 녹화 v Video. Record. Activity 클래스에 권한 요청을 위한 메소드를 재정의 @Override //허용한

비디오 녹화 v Video. Record. Activity 클래스에 권한 요청을 위한 메소드를 재정의 @Override //허용한 권한에 대한 정보를 알려주는 메소드 public void on. Granted(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions granted : " + permissions. length, Snackbar. LENGTH_LONG). show(); }

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Surface.

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Surface. View surface = new Surface. View(this); holder = surface. get. Holder(); //holder. set. Type(Surface. Holder. SURFACE_TYPE_PUSH_BUFFERS); Frame. Layout frame = find. View. By. Id(R. id. container); frame. add. View(surface); Button button = find. View. By. Id(R. id. button); button. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { start. Recording(); } });

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button button 2 = find. View. By. Id(R. id. button 2); button 2. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { stop. Recording(); } }); Button button 3 = find. View. By. Id(R. id. button 3); button 3. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { start. Play(); } });

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button

비디오 녹화 v Video. Record. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 Button button 4 = find. View. By. Id(R. id. button 4); button 4. set. On. Click. Listener(new View. On. Click. Listener() { @Override public void on. Click(View v) { stop. Play(); } }); String file. Dir = get. Files. Dir(). get. Absolute. Path(); filename = file. Dir + File. separator + "video. mp 4"; Auto. Permissions. Companion. load. All. Permissions(this, 101);

카메라 사용 v 3개의 권한 필요 <uses-permission android: name="android. permission. CAMERA" /> <uses-feature android:

카메라 사용 v 3개의 권한 필요 <uses-permission android: name="android. permission. CAMERA" /> <uses-feature android: name="android. hardware. camera. autofocus" /> v 동적으로 권한을 확인해야 함 v 카메라 인텐트 생성 Intent intent = new Intent(Media. Store. ACTION_IMAGE_CAPTURE); v 촬영한 내용은 data라는 이름으로 결과를 이전 Activity에 전송됨

카메라 사용 v Camera 2 Util. java 파일을 프로젝트의 java 패키지 안에 추가 v

카메라 사용 v Camera 2 Util. java 파일을 프로젝트의 java 패키지 안에 추가 v 2개의 이미지 파일을 추가 – ic_normal. png, ic_pressed. png v Drawable 디렉토리에 xml 파일을 추가 <? xml version="1. 0" encoding="utf-8"? > <selector xmlns: android="http: //schemas. android. com/apk/res/android"> <item android: drawable="@drawable/ic_pressed" android: state_pressed="true"/> <item android: drawable="@drawable/ic_normal"/> </selector> v Android. Manifest. xml 파일에 권한 추가 <uses-permission android: name="android. permission. CAMERA" /> <uses-permission android: name="android. permission. WRITE_EXTERNAL_STORAGE" /> <uses-permission android: name="android. permission. READ_EXTERNAL_STORAGE" /> <uses-feature android: name="android. hardware. camera" android: required="true" />

카메라 사용 v 실행 가능한 Activity 추가(Image. Capture. Activity) v activity_image_capture. xml 파일 수정

카메라 사용 v 실행 가능한 Activity 추가(Image. Capture. Activity) v activity_image_capture. xml 파일 수정 <Linear. Layout 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" android: orientation="vertical" > <Surface. View android: id="@+id/surface" android: layout_width="match_parent" android: layout_height="0 dp" android: layout_weight="1" />

카메라 사용 v activity_image_capture. xml 파일 수정 <Image. View android: id="@+id/btn" android: layout_width="wrap_content" android:

카메라 사용 v activity_image_capture. xml 파일 수정 <Image. View android: id="@+id/btn" android: layout_width="wrap_content" android: layout_height="wrap_content" android: src="@drawable/ic_camera" android: max. Width="100 dp" android: max. Height="100 dp" android: adjust. View. Bounds="true" android: clickable="true" android: layout_gravity="center" /> </Linear. Layout>

카메라 사용 v Image. Capture. Activity 클래스 선언부 수정 public class Image. Capture. Activity

카메라 사용 v Image. Capture. Activity 클래스 선언부 수정 public class Image. Capture. Activity extends App. Compat. Activity implements Auto. Permissions. Listener, Surface. Holder. Callback, View. On. Click. Listener { v Image. Capture. Activity 클래스에 프로퍼티 선언 Surface. Holder holder; Handler. Thread thread; Handler handler; Surface. View surface. View; Image. View image. View; Camera. Manager manager; Camera. Device camera; //surface에서 사진데이터 추출 Image. Reader reader; //surface 화면을 preview 로 찍거나 사진추출 기능 제공. . Camera. Capture. Session session; //카메라 정보 Camera. Characteristics characteristics;

카메라 사용 v Image. Capture. Activity 클래스에 권한 관련 메소드 재정의 @Override public void

카메라 사용 v Image. Capture. Activity 클래스에 권한 관련 메소드 재정의 @Override public void on. Request. Permissions. Result(int request. Code, String permissions[], int[] grant. Results) { super. on. Request. Permissions. Result(request. Code, permissions, grant. Results); if (request. Code == 200 && grant. Results. length > 0) { if (grant. Results[0] == Package. Manager. PERMISSION_GRANTED && grant. Results[1] == Package. Manager. PERMISSION_GRANTED) { holder = surface. View. get. Holder(); holder. add. Callback(this); thread = new Handler. Thread("background"); thread. start(); handler = new Handler(thread. get. Looper()); } } manager = (Camera. Manager) get. System. Service(CAMERA_SERVICE); } Auto. Permissions. Companion. parse. Permissions(this, request. Code, permissions, this);

카메라 사용 v Image. Capture. Activity 클래스에 권한 관련 메소드 재정의 @Override public void

카메라 사용 v Image. Capture. Activity 클래스에 권한 관련 메소드 재정의 @Override public void on. Denied(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions denied : " + permissions. length, Snackbar. LENGTH_LONG). show(); } @Override public void on. Granted(int request. Code, String[] permissions) { Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "permissions granted : " + permissions. length, Snackbar. LENGTH_LONG). show(); }

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 @Override public void

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 @Override public void on. Click(View v) { if (session != null) { try { //add~~~~~~~~~~ Capture. Request. Builder requester = camera. create. Capture. Request(camera. TEMPLATE_STILL_CAPTURE); requester. add. Target(reader. get. Surface()); int rotation = get. Window. Manager(). get. Default. Display(). get. Rotation(); requester. set(Capture. Request. JPEG_ORIENTATION, Camera 2 Util. get. Orientation(rotation, characteristics)); session. capture(requester. build(), null); } } catch (Exception ex) { } } else { }

카메라 사용 v Image. Capture. Activity 클래스에 Surface View 관련 메소드 재정의 @Override public

카메라 사용 v Image. Capture. Activity 클래스에 Surface View 관련 메소드 재정의 @Override public void surface. Created(Surface. Holder holder) { } @Override public void surface. Changed(Surface. Holder holder, int format, int width, int height) { if (camera == null) { try { for (String camera. Id : manager. get. Camera. Id. List()) { characteristics = manager. get. Camera. Characteristics(camera. Id); if (characteristics. get(characteristics. LENS_FACING) == Camera. Characteristics. LENS_FACING_BACK) { Size largest. Size = Camera 2 Util. get. Largest. Image. Size(characteristics); reader = Image. Reader. new. Instance(largest. Size. get. Width(), largest. Size. get. Height(), Image. Format. JPEG, 2); reader. set. On. Image. Available. Listener(capture. Listener, handler); height); Size optimal. Size = Camera 2 Util. choose. Optimal. Size(this, characteristics, width, holder. set. Fixed. Size(optimal. Size. get. Width(), optimal. Size. get. Height());

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 if (Context. Compat.

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 if (Context. Compat. check. Self. Permission(this, Manifest. permission. CAMERA) == Package. Manager. PERMISSION_GRANTED) { manager. open. Camera(camera. Id, state. Callback, handler); } return; } } } catch (Exception ex) { } } }

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 @Override public void

카메라 사용 v Image. Capture. Activity 클래스에 버튼의 클릭 메소드 생성 @Override public void surface. Destroyed(Surface. Holder holder) { holder. remove. Callback(this); try { // 초기화 holder. set. Fixed. Size(/*width*/0, /*height*/0); if (session != null) { session. close(); session = null; } } finally { if (camera != null) { camera. close(); camera = null; } } if (reader != null) reader. close(); }

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 Camera.

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 Camera. Device. State. Callback state. Callback = new Camera. Device. State. Callback() { @Override public void on. Opened(Camera. Device camera) { Image. Capture. Activity. this. camera = camera; try { //add~~~~~~~ List<Surface> outputs = Arrays. as. List(holder. get. Surface(), reader. get. Surface()); camera. create. Capture. Session(outputs, session. Listener, handler); } catch (Exception ex) { } } @Override public void on. Disconnected(Camera. Device camera) { } }; @Override public void on. Error(Camera. Device camera, int error) { }

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 Camera.

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 Camera. Capture. Session. State. Callback session. Listener = new Camera. Capture. Session. State. Callback() { @Override public void on. Configured(Camera. Capture. Session session) { Image. Capture. Activity. this. session = session; if (holder != null) { try { Capture. Request. Builder request. Builder = camera. create. Capture. Request(camera. TEMPLATE_PREVIEW); request. Builder. add. Target(holder. get. Surface()); Capture. Request preview. Request = request. Builder. build(); try { session. set. Repeating. Request(preview. Request, null); } catch (Camera. Access. Exception e) { } } catch (Camera. Access. Exception ex) { } } else { } }

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 @Override

카메라 사용 v Image. Capture. Activity 클래스에 카메라 관련 이벤트 처리 객체를 생성 @Override public void on. Closed(Camera. Capture. Session session) { session = null; } }; @Override public void on. Configure. Failed(Camera. Capture. Session session) { }

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장을 위한 이벤트 객체를 생성 Image.

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장을 위한 이벤트 객체를 생성 Image. Reader. On. Image. Available. Listener capture. Listener = new Image. Reader. On. Image. Available. Listener() { @Override public void on. Image. Available(Image. Reader reader) { handler. post(new Captured. Image. Saver(reader. acquire. Next. Image())); } };

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장 스레드 관련 객체를 생성 class

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장 스레드 관련 객체를 생성 class Captured. Image. Saver implements Runnable { private Image m. Capture; public Captured. Image. Saver(Image capture) { m. Capture = capture; }

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장 스레드 관련 객체를 생성 @Override

카메라 사용 v Image. Capture. Activity 클래스에 이미지 저장 스레드 관련 객체를 생성 @Override public void run() { File file = null; try { File dir = new File(Environment. get. External. Storage. Directory(). get. Absolute. Path() + "/my. App"); if (!dir. exists()) { dir. mkdir(); } file = File. create. Temp. File("IMG", ". jpg", dir); File. Output. Stream ostream = new File. Output. Stream(file); Byte. Buffer buffer = m. Capture. get. Planes()[0]. get. Buffer(); byte[] jpeg = new byte[buffer. remaining()]; buffer. get(jpeg); ostream. write(jpeg); ostream. flush(); Snackbar. make(get. Window(). get. Decor. View(). get. Root. View(), "file write ok : " + file. get. Absolute. Path(), Snackbar. LENGTH_SHORT). show(); } catch (Exception ex) { } finally { m. Capture. close(); } } }

카메라 사용 v Image. Capture. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 surface.

카메라 사용 v Image. Capture. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 surface. View = (Surface. View) find. View. By. Id(R. id. surface); image. View = (Image. View) find. View. By. Id(R. id. btn); image. View. set. On. Click. Listener(this); holder = surface. View. get. Holder(); holder. add. Callback(this); thread = new Handler. Thread("background"); thread. start(); handler = new Handler(thread. get. Looper()); manager = (Camera. Manager) get. System. Service(CAMERA_SERVICE); Auto. Permissions. Companion. load. All. Permissions(this, 101);

카메라 사용 v 실행 가능한 Activity 추가 – Camera. Coupon. Activity v 프로젝트의 java

카메라 사용 v 실행 가능한 Activity 추가 – Camera. Coupon. Activity v 프로젝트의 java 디렉토리에 Camera. Surface. View. java 파일을 추가 v drawable 디렉토리에 이미지 파일을 추가(coupon) v Android. Manifest. xml 파일에 권한 추가 <uses-permission android: name="android. permission. FLASHLIGHT"/>

카메라 사용 v 레이아웃 수정 <Relative. Layout xmlns: android="http: //schemas. android. com/apk/res/android" android: layout_width="match_parent"

카메라 사용 v 레이아웃 수정 <Relative. Layout xmlns: android="http: //schemas. android. com/apk/res/android" android: layout_width="match_parent" android: layout_height="match_parent" android: background="#ffff"> <Relative. Layout android: id="@+id/title. Layout" android: layout_width="match_parent" android: layout_height="wrap_content" android: layout_align. Parent. Top="true" android: layout_margin="8 dp"> <Text. View android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent. Left="true" android: text="쿠폰" android: text. Color="#ff 000000" android: text. Size="16 dp" /> </Relative. Layout>

카메라 사용 v 레이아웃 수정 <Frame. Layout android: id="@+id/preview. Frame" android: layout_width="match_parent" android: layout_height="match_parent"

카메라 사용 v 레이아웃 수정 <Frame. Layout android: id="@+id/preview. Frame" android: layout_width="match_parent" android: layout_height="match_parent" android: layout_above="@+id/button. Layout" android: layout_below="@+id/title. Layout"> <itstudy. kakao. multimedia. Camera. Surface. View android: id="@+id/camera. View" android: layout_width="match_parent" android: layout_height="match_parent" /> <Relative. Layout android: id="@+id/icon. Layout" android: layout_width="match_parent" android: layout_height="match_parent" android: background="#0000" android: visibility="visible">

카메라 사용 v 레이아웃 수정 <Linear. Layout android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent.

카메라 사용 v 레이아웃 수정 <Linear. Layout android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent. Top="true" android: layout_margin. Left="80 dp" android: layout_margin. Top="200 dp" android: orientation="vertical"> <Image. View android: id="@+id/icon 01 Image" android: layout_width="50 dp" android: layout_height="50 dp" android: scale. Type="center. Inside" android: src="@drawable/coupon" /> <Text. View android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_gravity="center_horizontal" android: text="VIPS" android: text. Color="#ffff" android: text. Size="18 dp" /> </Linear. Layout>

카메라 사용 v 레이아웃 수정 <Linear. Layout android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent.

카메라 사용 v 레이아웃 수정 <Linear. Layout android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent. Top="true" android: layout_margin. Left="200 dp" android: layout_margin. Top="180 dp" android: orientation="vertical"> <Image. View android: id="@+id/icon 02 Image" android: layout_width="50 dp" android: layout_height="50 dp" android: scale. Type="center. Inside" android: src="@drawable/coupon" />

카메라 사용 v 레이아웃 수정 <Text. View android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_gravity="center_horizontal" android:

카메라 사용 v 레이아웃 수정 <Text. View android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_gravity="center_horizontal" android: text="스타벅스" android: text. Color="#ffff" android: text. Size="18 dp" android: text. Style="bold" /> </Linear. Layout> </Relative. Layout> </Frame. Layout>

카메라 사용 v 레이아웃 수정 <Linear. Layout android: id="@+id/button. Layout" android: layout_width="wrap_content" android: layout_height="wrap_content"

카메라 사용 v 레이아웃 수정 <Linear. Layout android: id="@+id/button. Layout" android: layout_width="wrap_content" android: layout_height="wrap_content" android: layout_align. Parent. Bottom="true" android: layout_center. Horizontal="true" android: layout_margin="8 dp" android: orientation="horizontal"> <Button android: id="@+id/show. Button" android: layout_width="120 dp" android: layout_height="wrap_content" android: text="쿠폰보이기" android: text. Size="16 dp" android: text. Style="bold" />

카메라 사용 v 레이아웃 수정 <Button android: id="@+id/hide. Button" android: layout_width="120 dp" android: layout_height="wrap_content"

카메라 사용 v 레이아웃 수정 <Button android: id="@+id/hide. Button" android: layout_width="120 dp" android: layout_height="wrap_content" android: layout_margin. Left="10 dp" android: text="쿠폰감추기" android: text. Size="16 dp" android: text. Style="bold" /> </Linear. Layout> </Relative. Layout>

카메라 사용 v Image. Coupon. Activity 클래스에 프로퍼티 선언 Frame. Layout preview. Frame; Camera.

카메라 사용 v Image. Coupon. Activity 클래스에 프로퍼티 선언 Frame. Layout preview. Frame; Camera. Surface. View camera. View; Relative. Layout icon. Layout; Image. View icon 01 Image; Image. View icon 02 Image;

카메라 사용 v Image. Coupon. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 preview.

카메라 사용 v Image. Coupon. Activity 클래스의 on. Create 메소드에 초기화 코드 작성 preview. Frame = (Frame. Layout) find. View. By. Id(R. id. preview. Frame); camera. View = (Camera. Surface. View) find. View. By. Id(R. id. camera. View); icon. Layout = (Relative. Layout) find. View. By. Id(R. id. icon. Layout); icon 01 Image = (Image. View) find. View. By. Id(R. id. icon 01 Image); icon 02 Image = (Image. View) find. View. By. Id(R. id. icon 02 Image); Button show. Button = (Button) find. View. By. Id(R. id. show. Button); show. Button. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View v) { icon. Layout. set. Visibility(View. VISIBLE); } }); Button hide. Button = (Button) find. View. By. Id(R. id. hide. Button); hide. Button. set. On. Click. Listener(new View. On. Click. Listener() { public void on. Click(View v) { icon. Layout. set. Visibility(View. INVISIBLE); } });