안드로이드애플리케이션과통합하는데는자바가편하므로대표적인두가지라이브러리를비교해보자. 자바 ID3 태그라이브러리 jaudiotagger ID3v1, ID3v1.1, Lyrics3v1, Mp3, Mp4 (Mp4 오디오, M4a 지원범위 Lyrics3v2, ID3v2.2, ID

Similar documents
어댑터뷰

2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android=" 2 xmlns:tools="

안드로이드기본 11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 -

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

03장

01장

2 Application Name: Day10_yhg <LinearLayout android:layout_weight="3" > /> an

( )부록

이것은리스트뷰의 setadapter 메소드에잘표현되어있습니다. setadapter 는리스트뷰에사용할데이터객체를넘겨주는메소드입니다. 일반적으로생각한다면 ArrayAdapter 객체를생성하여사용할데이터를저장할것이고데이터가저장된 ArrayAdapter 객체를 setadapt

13ÀåÃß°¡ºÐ

[ 그림 7-1] 프로젝트 res 폴더 이미지뷰 [ 예제 7-1] 이미지뷰 1 <LinearLayout 2 ~~~~ 중간생략 ~~~~ 3 android:orientation="vertical" > 4 <ImageView

학습목표 선언하여디자인을하는방법을이해하고, 실행할수있다. 시작화면을만드는방법과대체리소스를사용하는방법을이해하고실행할수있다. About 과같은상자를구현하고, 테마를적용하는법을이해하고실행할수있다.

Microsoft PowerPoint - 11주차_Android_GoogleMap.ppt [호환 모드]

9 차시고급위젯다루기 1 학습목표 날짜 / 시간과관련된위젯을배운다. 웹뷰를사용하여간단한웹브라우저기능을구현한다. 매니패스트파일의설정법을배운다. 2 확인해볼까? 3 날짜 / 시간위젯 1) 활동하기 활동개요

헬로, 안드로이드 13 주차 SQL 활용하기 (2) 강대기동서대학교컴퓨터정보공학부

학습목표 메뉴를추가하는방법을이해하고실습할수있다. 프로그램의기본설정 (settings) 을정의하는방법을알고실습할수있다. 대화상자를여는방법을알고실습할수있다. 로그메시지로디버깅하는방법을이해한다. 디버거로디버깅하는방법을이해한다.

PowerPoint 프레젠테이션

슬라이드 1

슬라이드 1

슬라이드 1

Spring Data JPA Many To Many 양방향 관계 예제

50_1953.pdf

리니어레이아웃 - 2 -

Microsoft PowerPoint App Fundamentals[Part1](1.0h).pptx

PowerPoint Presentation

SQLite v 소개 ü SQLite 라이브러리를통해완전한관계형데이터베이스 (RDBMS) 기능제공 ü 오픈소스 ü 표준준수 ü 경량 ü 단일계층 2

rmi_박준용_final.PDF

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

Cluster management software

Microsoft PowerPoint - Java7.pptx

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

위젯과레이아웃위젯은 View 클래스를상속해화면디스플레이와이벤트처리를할수있도록구현된스크린구성의최소단위를말한다. android.widget 패키지에는여러유형의위젯들이포함되어있다. TextView, ImageView, Button, ImageButton 등은가장간단한위젯들이

TipssoftAppActivity.java // 기본소스파일 main.xml // 배치와구성에관련된리소스파일 string.xml // 프로그램에서사용할문자열에관련된리소스파일 컴파일을하고나면 r.java 라는소스파일이하나추가되는데이파일은리소스파일을소스파일에서이용할수있도

파일로입출력하기II - 파일출력클래스중에는데이터를일정한형태로출력하는기능을가지고있다. - PrintWriter와 PrintStream을사용해서원하는형태로출력할수있다. - PrintStream은구버전으로가능하면 PrintWriter 클래스를사용한다. PrintWriter

Microsoft Word - src.doc

PowerPoint Presentation

보가태그다. 태그정보를뮤직플레이어에서활용해곡명과가수정보를출력하는것이다. 안드로이드뮤직플레이어도태그정보를활용한다. 태그정보는문자열로, 글자깨짐현상은글자의인코딩과디코딩의문제로보인다. 따라서원인은다음과같이 2가지로분석할수있다. MP3 파일에서인코딩설정이잘못됨. 안드로이드플랫

안드로이드2_14

Microsoft PowerPoint - 04-UDP Programming.ppt

PowerPoint 프레젠테이션

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

12Àå PDF

Secure Programming Lecture1 : Introduction

PowerPoint 프레젠테이션

Microsoft PowerPoint App Fundamentals[Part1].pptx

쉽게 풀어쓴 C 프로그래밊

JUNIT 실습및발표

PowerPoint Presentation

PowerPoint 프레젠테이션

12-file.key

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

PowerPoint Presentation

Microsoft PowerPoint - CSharp-10-예외처리

슬라이드 1

PowerPoint Presentation

슬라이드 1

Spring Boot/JDBC JdbcTemplate/CRUD 예제

신림프로그래머_클린코드.key

Spring Boot

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

<4D F736F F F696E74202D20C1A63234C0E520C0D4C3E2B7C228B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

C# Programming Guide - Types

class Sale void makelineitem(productspecification* spec, int qty) SalesLineItem* sl = new SalesLineItem(spec, qty); ; 2. 아래의액티비티다이어그램을보고 Java 또는 C ++,

mytalk

PowerPoint Presentation

rosaec_workshop_talk

F120L(JB)_UG_V1.0_ indd

4장.문장

(Microsoft PowerPoint - \301\24613\260\255 - oFusion \276\300 \261\270\274\272)

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

제8장 자바 GUI 프로그래밍 II

Microsoft PowerPoint - 02처음으로만드는(Ver 1.0)

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

JAVA PROGRAMMING 실습 09. 예외처리

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

Android Master Key Vulnerability

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

Microsoft PowerPoint - 06-Chapter09-Event.ppt

PowerPoint 프레젠테이션

OpenCV와 함께하는 컴퓨터 비전 프로그래밍 캠프

OOP 소개

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

JDK이클립스

02 C h a p t e r Java

교육자료

// 화면을터치하였을때해야할작업구현 case MotionEvent.ACTION_MOVE: // 화면을드래그하였때 // 화면을드래그하였을때해야할작업구현 case MotionEvent.ACTION_UP: // 화면에서터치가사라질때 // 화면에서터치가사라질때해야할자업구현 c

슬라이드 1

슬라이드 1

(Microsoft PowerPoint - Ch06.ppt [\310\243\310\257 \270\360\265\345])

기술문서 작성 XXE Attacks 작성자 : 인천대학교 OneScore 김영성 I. 소개 2 II. 본문 2 가. XML external entities 2 나. XXE Attack 3 다. 점검방법 3 라.

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

Microsoft PowerPoint - 03-TCP Programming.ppt

서현수

Daum 카페

Design Issues

혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 <html> 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 <html> 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가

PowerPoint 프레젠테이션

Transcription:

2 안드로이드뮤직플레이어 Intent 를활용한 ID3 태그에디터구현안드로이드용 ID3 태그에디터개발 스마트폰에서뮤직플레이어를사용하면서노래제목과가수이름의글이깨져서보인경험이있는가? 필자는 MP3 의메타정보인 ID3 태그를편집할수있는에디터를만들어사용자의불편을개선하는애플리케이션을만들어배포하고있다. 이번호에서는 ID3 태그에디터를만들어보면서안드로이드에서음악정보를수정할수있는방법을알아보자. 연재순서 1 회 2011. 1 안드로이드뮤직플레이어분석 2 회 2011. 2 안드로이드용 ID3 태그에디터개발 진성주 moleskine7@gmail.com, http://softwaregeeks.org 호기심왕성하고생활속자동화를실천하려는개발자다. 검색엔진, 대용량분산처리, 성능튜닝에관심이많다. 현재는삼성소프트웨어멤버십 20기, SW 마에스트로 1기회원으로활동하고있다. 일상생활에서 MP3 파일을많이접한다. 음악을재생하려고윈도우탐색기를열면쉽게음악정보를확인할수있다. 윈도우탐색기에표시되는제목, 참여음악가, 앨범등의정보를음악태그라고한다. ID3 태그의이해 ID3 를위키피디아에서찾아보면 MP3 파일에서사용하는메타데이터포맷으로, 음악의제목, 음악가이름등의음악파일에관련된정보를담는다 고정의돼있다. < 화면 1> 윈도우탐색기에서음악정보 많은애플리케이션이음악정보들을활용한다. 안드로이드뮤직플레이어에서음악이재생되는동안나타나는제목과앨범이미지가대표적이다. 이러한음악정보들은어디에있는것일까? 파일내부에기록돼있다. 즉, MP3 파일내부에가수명, 앨범명, 앨범이미지가존재하는것이다. ID3라고것은음악파일내부에 어떤정보가들어있으며어느위치에존재하는지를정의해놓은것이다. ID3v1은 1996년에고안됐으며사용자의요구사항에맞춰 ID3v1, ID3v1.1, ID3v2.2, ID3v2.3, ID3v2.4 형태로발전돼왔다. ID3의각버전마다지원하는정보의양과처리방법이다르다. 우리가기억해야할것은음악정보가파일에기록돼있고 ID3 각버전마다기록방법이조금씩다르다는것이다. ID3의상세한내용을알고싶다면 http://www.id3.org를방문하면도움이될것이다. ID3 태그라이브러리 ID3 태그정보는파일에기록돼있고버전마다기록되는방식이조금씩다르다. 다양한파일의음악정보를수정하려면모든버전에대해음악정보기록방식을이해해야한다. 이프로젝트의목표는태그라이브러리를만드는것이아닌사용자에게유용한애플리케이션을제공하는것이므로라이브러리를찾는것이현명하다. 수많은 ID3 태그라이브러리가존재하는데, 이프로젝트에서선택할라이브러리의기준을정해보자. 1) ID3 버전지원범위는어떻게되는가? 2) 안드로이드애플리케이션과통합하는데유용한언어인가? ( 자바또는 C/C++) 3) 라이브러리가배포된일자는언제인가? 206 m a s o

안드로이드애플리케이션과통합하는데는자바가편하므로대표적인두가지라이브러리를비교해보자. 자바 ID3 태그라이브러리 jaudiotagger ID3v1, ID3v1.1, Lyrics3v1, Mp3, Mp4 (Mp4 오디오, M4a 지원범위 Lyrics3v2, ID3v2.2, ID3v2.3, and M4p 오디오 ) Ogg, wma and ID3v2.4 tags 개발언어 자바 자바 최근버전 2006. 3. 12 2010. 12. 14 < 표 1> 라이브러리비교 안드로이드에서테스트하기위한환경구축이클립스의퍼스펙티브바에서 DDMS를선택하면오른쪽상단에 File Browser를볼수있다. 오른쪽상단에서휴대폰모양의아이콘을선택하면 Push a file onto the device 라는메뉴를볼수있는데, 비활성화되어있다면에뮬레이터가구동돼있는지확인하자. 라이브러리를선택할때최근활동을파악해계속적인지원을받을수있는지확인해야한다. Jaudiotagger 쪽이계속적으로활동하고있고다양한형식을지원하므로라이브러리를 jaudiotagger로선택하자. Jaudiotagger는자바로만들어진 ID3 태그라이브러리다. Mp3, Mp4(Mp4 오디오, M4a and M4p 오디오 ), Ogg, wma까지지원되며, 라이선스는 LGPL(The GNU Lesser General Public License) 이다. 간단한 API를사용해음악파일의정보변경이가능하다. 배포사이트인 www.jthink.net/jaudiotagger에방문하면더많은정보를확인할수있다. 사용될라이브러리를다운받아몇가지예제를만들어보며라이브러리의사용법을익히자. < 화면 3> DDMS 해당아이콘을클릭한후원하는파일을선택하면파일이옮겨지는것을볼수있다. 여기에서는 /sdcard/slowmotion.mp3 파일로복사했다. < 화면 4> DDMS FileBrowser 파일을옮기면 < 화면 4> 와같은화면을볼수있다. 이로써에뮬레이터에서테스트하기위한환경이구축됐다. < 화면 2> jaudiotagger 배포사이트 프로젝트생성안드로이드프로젝트를생성하자. < 화면 5> 는이해를돕기위해정보를기입한화면이다. 1) 사이트접속 http://www.jthink.net/jaudiotagger/ 2) Downloads Releases 선택 3) 2.0.4-SNAPSHOT 폴더이동 4) jaudiotagger-2.0.4-snapshot.jar 파일다운로드 Documentation Code Examples Read Metadata 메뉴를참고해 MP3 파일의음악정보를읽고쓰는예제를작성해보자. 실제안드로이드용단말기에서테스트하면좋겠지만단말기가없는사람들을위해에뮬레이터에서테스트를진행할것이다. 먼저테스트할 MP3 파일을에뮬레이터에옮겨야테스트할수있다. < 화면 5> 프로젝트생성 jaudiotagger 라이브러리사용해음악정보읽기앞서다운로드한 jaudiotagger-2.0.4-snapshot.jar 파일을 classpath로지정한다음예제를실행한다. m a s o 207

실전강의실 안드로이드용 ID3 태그에디터개발 < 리스트 1> jaudiotagger 라이브러리사용해음악정보읽기 (1) src/org/softwaregeeks/tagreadactivity.java import java.io.*; import org.jaudiotagger.audio.*; import org.jaudiotagger.audio.exceptions.*; import org.jaudiotagger.tag.*; import android.app.activity; import android.os.bundle; import android.util.log; import android.widget.textview; public class TagReadActivity extends Activity private static final String TAG = "TagEditor"; private TextView titletextview; private TextView artisttextview; private TextView albumtextview; public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentview(r.layout.tag_read); titletextview = (TextView) findviewbyid(r.id.titletextview); artisttextview = (TextView) findviewbyid(r.id.artisttextview); albumtextview = (TextView) findviewbyid(r.id.albumtextview); String path = "/sdcard/slowmotion.mp3"; read(path); public void read(string path) try Filefile=newFile(path); AudioFile audiofile = AudioFileIO.read(file); Tag tag = audiofile.gettag(); catch (TagException e) catch (ReadOnlyFileException e) catch (InvalidAudioFrameException e) < 리스트 2> jaudiotagger 라이브러리사용해음악정보읽기 (2) res/layout/tag_read.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com /apk/res/android" android:orientation="vertical" android:layout_width= "fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/titletextview" <TextView android:id="@+id/artisttextview" <TextView android:id="@+id/albumtextview" </LinearLayout> < 리스트 1> 은간단하게 TextView 3개를배치해음악정보를출력하는액티비티다. 여기에서는곡명, 가수, 앨범명을출력해봤다. 핵심코드는굵게표시된부분인데, AudioFileIO.read 메소드를사용해간단히음악정보를가져온후원하는정보만사용할수있다. 액티비티를실행하면음악정보가출력된것을확인할수있다. String title = tag.getfirst(fieldkey.title); String artist = tag.getfirst(fieldkey.artist); String album = tag.getfirst(fieldkey.album); titletextview.settext(title); artisttextview.settext(artist); albumtextview.settext(album); Log.i(TAG,"title : " + title); Log.i(TAG,"artist : " + artist); Log.i(TAG,"album : " + album); catch (CannotReadException e) catch (IOException e) < 화면 6> 실행화면 208 m a s o

jaudiotagger 라이브러리사용해음악정보쓰기 < 리스트 3> jaudiotagger 라이브러리사용해음악정보쓰기 (1) src/org/softwaregeeks/tagwriteactivity.java import java.io.*; import org.jaudiotagger.audio.*; import org.jaudiotagger.audio.exceptions.*; import org.jaudiotagger.tag.*; import android.app.activity; import android.os.bundle; import android.widget.textview; public class TagWriteActivity extends Activity private TextView beforetitletextview; private TextView beforeartisttextview; private TextView beforealbumtextview; private TextView aftertitletextview; private TextView afterartisttextview; private TextView afteralbumtextview; public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentview(r.layout.tag_write); beforetitletextview = (TextView) findviewbyid(r.id.beforetitletextview); beforeartisttextview = (TextView) findviewbyid(r.id.beforeartisttextview); beforealbumtextview = (TextView) findviewbyid(r.id.beforealbumtextview); aftertitletextview = (TextView) findviewbyid(r.id.aftertitletextview); afterartisttextview = (TextView) findviewbyid(r.id.afterartisttextview); afteralbumtextview = (TextView) findviewbyid(r.id.afteralbumtextview); String path = "/sdcard/slowmotion.mp3"; write(path); public void write(string path) try File file = new File(path); AudioFile audiofile = AudioFileIO.read(file); Tag tag = audiofile.gettag(); String title = tag.getfirst(fieldkey.title); String artist = tag.getfirst(fieldkey.artist); String album = tag.getfirst(fieldkey.album); beforetitletextview.settext(title); beforeartisttextview.settext(artist); beforealbumtextview.settext(album); tag.setfield(fieldkey.album,"album"); AudioFileIO.write(audioFile); album = tag.getfirst(fieldkey.album); aftertitletextview.settext(title); afterartisttextview.settext(artist); afteralbumtextview.settext(album); catch (CannotReadException e) catch (IOException e) catch (TagException e) catch (ReadOnlyFileException e) catch (InvalidAudioFrameException e) catch (CannotWriteException e) < 리스트 4> jaudiotagger 라이브러리사용해음악정보쓰기 (2) res/layout/tag_write.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com /apk/res/android" android:orientation="vertical" android:layout_width= "fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/beforetitletextview" <TextView android:id="@+id/beforeartisttextview" <TextView android:id="@+id/beforealbumtextview" <TextView android:id="@+id/aftertitletextview" <TextView android:id="@+id/afterartisttextview" <TextView android:id="@+id/afteralbumtextview" </LinearLayout> TagReadActivity에음악정보를수정하는코드만추가했다. 수정전후의정보를보며확인할수있는 TextView를추가했다. 이예제에서는외부저장장치 (sdcard) 에접근해파일을사용하 m a s o 209

실전강의실 안드로이드용 ID3 태그에디터개발 는데, 안드로이드에서는권한을설정해야정상적으로동작한다는것에유의하자. < 리스트 5> 외부저장장치권한설정 AndroidManifest.xml 중략 <uses-permission android:name="android.permission. WRITE_EXTERNAL_STORAGE"></uses-permission> 중략 Tip 간단한태그의읽기와수정은해당코드를사용하면안드로이드애플리케이션에도정상적으로동작한다. 하지만 Logcat 창을살펴보면오류가난것을볼수있다. 태그정보에간단히정보를설정한후 AudioFileIO.write 메소드를사용하면의도한대로음악정보가변경된다. 실행해실제로변경되는지확인해보자. < 화면 8> Logcat 오류화면 Jaudiotagger에서는음악정보중앨범아트를처리하기위해자바 Swing 패키지와 Awt 패키지를사용했는데안드로이드에는두패키지가없으므로오류메시지가출력된다. Jaudiotagger를사용해앨범아트를변경하고싶다면직접라이브러리의소스코드를받아두패키지의의존성을제거해야한다. 예를들어 org.jaudiotagger.tag.asf.abstractasftagimagefield.java를살펴보면 BufferedImage를 Bitmap 으로변경하는작업이필요하다. 원본 public BufferedImage getimage() throws IOException return ImageIO.read(new ByteArrayInputStream (getrawimagedata())); < 화면 7> 실행화면 지금까지 MP3 파일의음악정보를읽고쓰는간단한예제를살펴봤다. jaudiotagger 라이브러리를사용하면정말쉽게음악파일의정보를수정할수있다. ContentProvider 이해콘텐트프로바이더는특정애플리케이션에상관없이사용하는공통의데이터 ( 연락처, 사진, 음악, 동영상, 북마크목록, 통화목록등 ) 를안드로이드플랫폼에서조회 입력 수정 삭제할수있게만든것이다. 실제단말장치에는수백, 수천곡까지있을수있고사용자들은많은곡중원하는곡을선택해정보를수정해야한다. 수천곡의정보를불러온후리스트로나열하는경우를생각해보자. 앞서살펴본 jaudiotagger 라이브러리를사용하면정상적으로동작하겠지만너무느려사용자들이불평을할것이다. 콘텐트프로바이더는내외장저장장치의미디어파일에서미리정보를읽어공용데이터베이스에기록한다. 많은곡을한번에조회하려면콘텐트프로바이더를이용하는것이파일을개별로읽어서처리하는것보다훨씬빠르다. 콘텐트프로바이더를이용해음악목록을리스트로출력해보자. 수정 public Bitmap getimage() throws IOException ByteArrayInputStream in = new ByteArrayInputStream (getrawimagedata()); Bitmap bitmap = BitmapFactory.decodeStream(in); return bitmap; 꽤많은소스변경이필요하기때문에미리변경해둔 http://co de.google.com/p/needletagger/ 소스를참고하면도움이될것이다. 음악정보를담을데이터객체만들기 < 리스트 6> 음악정보를담을데이터객체 src/org/softwaregeeks/music.java public class Music private Long id; private Long albumid; private String album; private String track; 210 m a s o

private String artist; public void setartist(string artist) this.artist = artist; public String getartist() return artist; public void settrack(string track) this.track = track; public String gettrack() return track; public void setalbum(string album) this.album = album; public String getalbum() return album; public void setid(long id) this.id = id; public Long getid() return id; public void setalbumid(long albumid) this.albumid = albumid; public Long getalbumid() return albumid; 콘텐트프로바이더를사용해음악의정보를가져온후저장할데이터객체를만들어보자. 콘텐트프로바이더는 RDB인 sqlite 를사용해데이터를관리하는데내부적으로데이터 ID 컬럼을만들어관리한다. 그값을위한 id, 앨범 ID, 앨범명, 곡명, 가수명을저장하고있다. 리스트액티비티만들기 < 리스트 7> 리스트액티비티 src/org/softwaregeeks/musiclistactivity.java import java.util.arraylist; import android.app.activity; import android.content.contentresolver; import android.content.context; import android.database.cursor; import android.net.uri; import android.os.bundle; import android.provider.mediastore; import android.widget.listview; public class MusicListActivity extends Activity private ArrayList<Music> musiclist; private MusicListAdapter listadapter; private ListView listview; static String[] columns = new String[] "audio._id AS _id", MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.ALBUM_ID ; public void oncreate(bundle savedinstancestate) super.oncreate(savedinstancestate); setcontentview(r.layout.list); musiclist = getall(this,"");...(1) listview = (ListView) findviewbyid(r.id.listview); listadapter = new MusicListAdapter(this,R.layout. list_row, musiclist); listview.setadapter(listadapter); public static ArrayList<Music> getall(context context,string where) ArrayList<Music> list = new ArrayList<Music>(); Cursor c = query(context, MediaStore.Audio. Media.EXTERNAL_CONTENT_URI, columns, where, null, null); try if (c == null c.getcount() == 0) return list; c.movetofirst(); for (int i = 0; i < c.getcount(); i++) Music music = new Music(); music.setid(c.getlong(0)); music.setartist(c.getstring(1)); music.setalbum(c.getstring(2)); music.settrack(c.getstring(3)); music.setalbumid(c.getlong(6)); list.add(music); c.movetonext(); finally if (c!= null) c.close(); m a s o 211

실전강의실 안드로이드용 ID3 태그에디터개발 return list; public static Cursor query(context context,uri uri,string[] projection, String selection, String[] selectionargs, String sortorder, int limit) try ContentResolver resolver = context.getcontentresolver(); if (resolver == null) return null; if (limit > 0) uri = uri.buildupon().appendqueryparameter ("limit", "" + limit).build(); return resolver.query(uri, projection, selection, selectionargs, sortorder); catch (UnsupportedOperationException ex) return null; public static Cursor query(context context, Uri uri, String[] projection, String selection, String[] selectionargs, String sortorder) return query(context, uri, projection, selection, selectionargs, sortorder, 0); 소스가복잡하게보일수도있다. 콘텐트프로바이더에서원하는데이터를가져와리스트뷰로출력하는소스다. 핵심코드는굵게표시했는데 ContentResolver의 query 메소드를사용해원하는컬럼과조건을파라미터로넘겨데이터를가져온다. (1) 의코드를실행하면서부터이러한과정이진행된다. 리스트어댑터만들기 < 리스트 8> 리스트어댑터 src/org/softwaregeeks/musiclistadapter.java import java.util.arraylist; import android.content.context; import android.graphics.typeface; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.imageview; import android.widget.textview; public class MusicListAdapter extends BaseAdapter Typeface typeface; ArrayList<Music> list; LayoutInflater inflater; Context context; int layout; public MusicListAdapter(Context context, int layout, ArrayList<Music> items) this.context = context; this.inflater = (LayoutInflater)context.getSystemService(Context. LAYOUT_INFLATER_SERVICE); this.list = items; this.layout = layout; public int getcount() return list.size(); public Object getitem(int position) return list.get(position).getid(); public long getitemid(int position) return position; static class ViewHolder ImageView nowplayimageview; TextView tracktextview; TextView artisttextview; public View getview(int position, View convertview, ViewGroup parent) View v = convertview; ViewHolder holder; if(convertview == null) holder = new ViewHolder(); v = inflater.inflate(layout, parent, false); holder.tracktextview = (TextView) 212 m a s o

v.findviewbyid(r.id.track); holder.artisttextview = (TextView) v.findviewbyid(r.id.artist); v.settag(holder); else holder = (ViewHolder)v.getTag(); Musicmusic=list.get(position); holder.tracktextview.settext(music.gettrack()); holder.artisttextview.settext(music.getartist()); return v; intent 를배포하는것이다. < 리스트 9> MediaSanner 실행 context.sendbroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorage Directory()))); 정보를수정한후 < 리스트 9> 를추가하면콘텐트프로바이더도동일하게변경될것이다. NeedleTagger 오픈소스프로젝트소개 1. 자동으로태그정보를가져옴. 2. 재생중쉽게이동 리스트뷰에어떻게배치하고출력할지를결정하는리스트어댑터다. < 리스트 8> 을바탕으로에뮬레이터를동작하면음악정보가출력되는것을확인할수있다. 두가지사항으로사용자편의성을높일것이라고했다. 연재의 1회와 2회를통해 intent를활용한태그에디터구현의기초를알아봤다. 기초만알아봤기때문에사용자가쓸만한애플리케이션을개발하려면많은노력이필요하다. 여기서이미마켓에서배포되고있는 NeedleTagger 오픈소스프로젝트를소개하고자한다. < 화면 9> 콘텐트프로바이더를사용해음악정보를리스트뷰로출력한화면 ContentProvider 정보갱신을위한 MediaSanner 작성앞서살펴본내용으로콘텐트프로바이더에서음악의리스트를보여주고사용자가선택해음악정보를수정할수있다. 하지만태그라이브러리로수정한정보는 MP3 파일에만반영될뿐콘텐트프로바이더정보에는반영되지않는다. 콘텐트프로바이더정보를수정하기위해서는다음과같은두가지방법이있다. 1. 데이터에직접접근해업데이트 2. MediaSanner를작동해변경된내역을찾게함. 여기에서는두번째방법을사용해파일의변경내역을자동으로찾도록하자. 방법은간단하다. 미디어가마운트됨을알리는 < 화면 10> NeedleTagger 1. 태그자동찾기 : 태그의정보를자동으로설정 2. 앨범이미지찾기 : 태그의제목과가수를바탕으로앨범커버검색 3. 음악재생중자동링크 : HTC 디자이어, 넥서스원의기본음악플레이어사용시상태바로바로가기세가지기능을구현한프로젝트다. http://code.google.com /p/needletagger/ 에서소스코드를볼수있으니관심있는분은방문하면도움이될것이다. 2회의짧은연재로안드로이드에서 intent를활용해다양한확장이가능하다는것과안드로이드오픈소스를활용해흥미로운애플리케이션을만들수있음을알았다. 독자들에게도움이됐길바란다. 이달의디스켓 : ID3 태그에디터-2.zip m a s o 213