다...다른 방법을 검색해서 구했습니다-_-;
하지만, 이건 한글은 이제 잘 읽는 것 같은데......한자를 못 읽습니다-_-; 원래 안되는건가....-_-;

우선 ID3Parser 링크입니다. 매우 빠른 속도로 ID3데이터를 가져옵니다.
http://blog.ashier.com/2007/11/08/id3-parser/

여기서 한글을 읽을 수 있게 수정하는 부분이......
보면 ID3데이터를 추출해오는 부분이 있습니다.
거기서 한글로 추출할 수 있게 변경합니다.

[code]
private function parseFrames():void {
    var id:String = "";
    var size:uint = 0;
    if(fs.position <length) {
        try {
            id = fs.readUTFBytes(frameIdSize);
            size = fs.readUnsignedInt();
            if (version>= 3) {
                fs.readByte();
                fs.readByte();
            }
            if(id.match(regEx)) {
                var obj:Object = new Object();
                obj.encoding = fs.readByte();
                obj.text = fs.readUTFBytes(size - 1);
                frames[id] = obj;
            }
            parseFrames();
        }catch(e:Error) {}
    }
}
[/code]
이 부분이 있는데요. 한글을 읽어오는 readUTFBytes 부분을 바꿔줍니다.
[code]
//obj.text = fs.readUTFBytes(size - 1);
if (obj.encoding == "1")
{
    obj.text = StringUtil.trim(fs.readMultiByte(size - 1, "unicode"));
}
else
{
    obj.text = StringUtil.trim(fs.readMultiByte(size - 1, "EUC-KR"));
}
[/code]
보니까 obj.encoding이 1인 값은 unicode로 인코딩 된 것 같아요. obj.encoding이 0인 값은 EUC-KR로...
이렇게 하니까 잘 되네요....가끔 공백을 추출해오고 그래서 trim처리했습니다.

아래글은 ID3v1방식 추출 방법 및 ID3v2의 다른 추출 방식 입니다^^ 참고하세요~
http://mudchobo.tomeii.com/tt/356
 
Posted by 머드초보
,
 
그......sound객체를 이용해서 하는 것이라니라 직접 바이트로 읽어서-_-; 하는 법이 있더라구요.
우선 ID3v1태그는 음악내용 맨 뒤에 있습니다. 그래서 추출하기는 쉽습니다.

http://cafe.naver.com/flexcomponent.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=10087
flexcomponent에서 혀니님께서 작성하신 글입니다.

그 다음 ID3v2태그는 맨 앞에 있습니다. 또한 이것을 추출하는 방법이 만만치 않습니다-_-;
왜냐하면 이건 뭐 길이도 가변적이고, 태그가 복잡합니다-_-;
그래서 태그를 공부하는 것보다 누가 만들어 놓은 것을 찾는 게 더 빠를 듯하여.....-_-;
구글신님께 부탁드리니 잘 찾아주셨습니다 ^^

http://blog.benstucki.net/?id=3

이것을 그대로 사용하시면 한글이 깨집니다.
사용자 삽입 이미지

저 위에 소스를 다운 받아서 첫번째 ID3v1에서 사용한 방법을 사용합니다.
ID3Reader.as파일에 readTextFrame이라는 함수가 있는데요.
이게 텍스트를 읽어올 때 사용하는 함수인 것 같습니다.
[code]
//obj.text = bytes.readUTFBytes(size-1);
obj.text = bytes.readMultiByte(size-1, "EUC-KR");
[/code]
요렇게 바꿔줍니다-_-;
그런 다음에 실행하면 한글이 잘 나옵니다.
사용자 삽입 이미지
하지만........-_-;
기존에 Actionscript에서 제공하는 Sound클래스에서 추출하는 ID3에서 잘나오는 한글(즉 UTF-8로 인코딩 된 것)은 여기서 읽으면 잘 안나옵니다-_-; 이거 추출하는 프로그램 만드신 분이 잘못 만든건지 잘 모르겠는데요. 확인해봐야할 것 같네요 ㅠ

사용자 삽입 이미지
헉...-_-; 인코딩을 unicode로 바꾸니까 잘 나오네요. 기존에 Actionscript에서 잘 나오는 것은 unicode로 되어있어서 그런거였나요? ㅠ 더 확인해봐야겠습니다 ㅠ
이거 말고, 요아래 것으로 하면 잘 되네요.

ID3v2추출하는 다른 방법입니다.
http://mudchobo.tomeii.com/tt/357
 
Posted by 머드초보
,
 
Microsoft Outlook 2007에서 최소화버튼을 누르면, 창이 사라지면서 작업표시줄에서도 같이 사라지고, 트레이아이콘으로만 남게 됩니다.
그것을 AIR에서도 구현할 수 있습니다.

AIR에서는 윈도우의 DisplayState를 캐치할 수 있는데요. 즉, 최소화, 최대화 이런 이벤트가 발생하는 것을 잡을 수 있습니다. 그래서 만약 위와 같은 기능을 구현하고자 한다면 이렇게 하면 됩니다.

최소화이벤트를 잡은 뒤, 창의 visible을 false로 바꾸고, trayicon의 icon이미지를 넣어주면 됩니다.
또, 창을 다시 원래 대로 돌리려면, trayicon에 이벤트를 걸어서 클릭 시, 창의 visible을 true로 바꿔주고, trayicon의 icon이미지를 삭제하면 됩니다.

http://help.adobe.com/en_US/AIR/1.1/devappsflex/WS5b3ccc516d4fbf351e63e3d118666ade46-7dcb.html

음....저는 찾는데 하루를 소비했습니다만-_-;(머리가 딸려서-_-) 찾은 문서는 Adobe AIR에 있는 "Developing Adobe AIR 1.1 Applications with Flex"문서군요 ㅠ

아래는 제가 구현해봤습니다.
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="creationCompleteHandler()">
    <mx:Script>
        <![CDATA[

            private var icons:Loader = new Loader();
                   
            private function creationCompleteHandler():void
            {
                makeTrayIcon();
                icons.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);
               
                nativeWindow.addEventListener(
                        NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, onChange);
            }
           
            private function onChange(event:NativeWindowDisplayStateEvent):void
            {
                if (event.afterDisplayState == NativeWindowDisplayState.MINIMIZED)
                {
                    event.preventDefault();
                    nativeWindow.visible = false;
                   
                    icons.load(new URLRequest("icons/icon_16.png"));
                }
            }
           
            private function makeTrayIcon():void
            {
                var iconMenu:NativeMenu = new NativeMenu();
                var visibleCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem("Visible"));
                visibleCommand.addEventListener(Event.SELECT, function(event:Event):void {
                    nativeWindow.visible = true;
                    NativeApplication.nativeApplication.icon.bitmaps = [];
                });
               
                var exitCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem("Exit"));
                exitCommand.addEventListener(Event.SELECT, function(event:Event):void {
                    NativeApplication.nativeApplication.icon.bitmaps = [];
                    NativeApplication.nativeApplication.exit();
                });
               
                var systray:SystemTrayIcon =
                NativeApplication.nativeApplication.icon as SystemTrayIcon;
                systray.menu = iconMenu;
            }
        
            private function iconLoadComplete(event:Event):void
            {
                NativeApplication.nativeApplication.icon.bitmaps =
                    [event.target.content.bitmapData];
            }

        ]]>
    </mx:Script>
</mx:WindowedApplication>
[/code]
핵심은
[code]
nativeWindow.addEventListener(
                        NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, onChange);

private function onChange(event:NativeWindowDisplayStateEvent):void{
    if(event.afterDisplayState == NativeWindowDisplayState.MINIMIZED){
        event.preventDefault();
        event.target.visible = false;
    }
}
[/code]
우선 윈도우에 NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING 이벤트를 겁니다. 이것은 윈도우의 상태가 변경되었을 때 발생합니다.
최소화버튼을 누르거나 작업표시줄에서 버튼을 클릭하여 최소화 할 때 이벤트가 발생합니다.
event.preventDefault()를 호출하게 되면 디폴트동작을 취소하게 됩니다. 그리고 창만 숨기는거죠. 창을 숨기면 작업표시줄에도 사라집니다. 그리고, trayicon을 만들면 됩니다.

후.....달이차오르니 가야겠습니다.

 
Posted by 머드초보
,
 
플렉스로 만들기는 했지만, 뭐 모든 클라이언트 플랫폼에서 쉽게 만들 수 있습니다.

요아래에 있는 RESTful Web Service를 구축하셨다면 그것을 이용한 클라이언트가 필요할 것입니다.

게시판용 RESTful WebService만들기
http://mudchobo.tomeii.com/tt/345
http://mudchobo.tomeii.com/tt/346

그래서 구현해봤습니다.
우선 5가지 요청을 합니다.

1. 게시물 리스트를 받아오는 것(GET)
2. 게시물 1개의 데이터를 받아오는 것(GET)
3. 게시물 쓰기(POST)
4. 게시물 삭제(DELETE)
5. 게시물 수정(PUT)

핵심은 RESTful요청이 가능한 라이브러리입니다. 요아래를 참고하세요~

[Flex/AIR] RESTful WebService를 위한 Flex RestService Library!


이 라이브러리를 통해 RESTService요청을 합니다. (기존 Flex에 있는 HTTPService는 DELETE와 PUT이 안됩니다.)
[code]
<rest:RESTService id="boardService" method="GET"
        rootURL="http://localhost/BoardWS/resources/wsboards/" port="9080"
        result="resultBoardHandler(event)" fault="faultHandler(event)"/>
[/code]
이런식으로 요청하면 되겠죠? ^^

아래는 구현체 소스입니다.
허접해서 도움이 될지는 모르겠지만....-_-; 어쨌든 저의 삽질의 결정체니....-_-;

저 위에서 구현한 WebService를 띄워놓고, 이 클라이언트로 접속하면 잘 될겁니다.

사용자 삽입 이미지

 
Posted by 머드초보
,
 
우선 RESTFul로 구현된 WebService를 Flex에서 호출하기 위해서는 클라이언트에서 method방식이 GET, POST, DELETE, PUT을 지원을 해야합니다. 근데, 제가 RESTful WebService를 만들었는데요. 만들어놓고, 자체 GlassFish에서 제공하는 RESTful WebService Test로는 무쟈게 잘 돌아갔습니다.
근데, Flex에서 제공하는 HTTPService를 이용해서 method는 DELETE로 놓은다음에 http요청을 해봤습니다. 이게 왠걸......POST로 요청이 되는 듯해서 데이터를 가져오고 있습니다-_-; 지워야하는데!

그래서 검색을 해보니.......
http://verveguy.blogspot.com/2008/07/truth-about-flex-httpservice.html
저의 짧은 영어실력으로 보니.......
4/ All HTTP PUT and HTTP DELETE requests are turned into POST requests. This appears to be a browser limitation that the Flash player is stuck with.
라고 되어있군요. PUT과 DELETE는 POST로 요청이 된다고 하는 것 같습니다. 플래쉬플레이어가 브라우저 제한에 뭐 걸린 것으로 보인다고 말하는데요. 해석이 잘 안되네요-_-;

그래서! 검색해본 결과 REST요청을 위한 라이브러리를 누가 만들었더군요. 대단합니다 ^^ 어차피 HTTP요청도 해당 포트로 뭐 데이터를 주고 받는 것이다 보니, 이것을 소켓으로 구현을 했더군요.

http://lab.arc90.com/2008/03/restservice.php

기존 HTTPService랑 틀린 것이...얘는 소켓을 통해서 쏘기 때문에 포트를 지정해줘야합니다. 그리고 arc90에서 만든 ResultEvent랑 FaultEvent를 사용해야합니다.

서버측 코드를 보면
[code]
@DELETE
    public Response delete() {
        PersistenceService persistenceSvc = PersistenceService.getInstance();
        try {
            Wsboard entity = getEntity();
            if (entity.getPwd().equals(pwd))
            {
                persistenceSvc.beginTx();
                persistenceSvc.removeEntity(entity);
                persistenceSvc.commitTx();
               
                return Response.ok("success").build();
            }
        } finally {
            persistenceSvc.close();
        }
        return Response.ok("fail").build();
    }
[/code]
그냥 단순히 비밀번호가 같으면 지워서 응답을 success로 주고, 틀리면 fail로 줍니다.

이제 플렉스에서 봅시다.
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    creationComplete="init()" xmlns:rest="com.arc90.rpc.rest.*">
   
    <mx:Script>
        <![CDATA[
            import com.arc90.rpc.events.FaultEvent;
            import com.arc90.rpc.events.ResultEvent;
            import mx.controls.Alert;
           
            private function init():void
            {       
                service.send();               
            }

            private function result(event:ResultEvent):void
            {
                Alert.show(event.result.toString());
            }   
           
            private function fault(event:FaultEvent):void
            {
                Alert.show(event.fault.toString());
            }       
        ]]>
    </mx:Script>
    <rest:RESTService id="service"
        port="9080" url="http://localhost/BoardWS/resources/wsboards/22/1"
        result="result(event)" fault="fault(event)" method="DELETE">
    </rest:RESTService>
   
</mx:WindowedApplication>
[/code]
포트를 port라고 해서 따로 지정해줍니다.
저 웹서비스가 {idx}/{pwd} 형식의 url을 요청합니다. DB에는 22번의 idx를 가지고 pwd가 1인 데이터가 있습니다. 저렇게 요청하면 지워집니다.

사용자 삽입 이미지
ps. 정말 적절하지 못한 웹서비스군-_-;
 
Posted by 머드초보
,