안드로이드 개발하다 보면 별 문제는 없어보일지 모르지만 안드로이드가 네트워크 인터페이스를 여러개 가지기 때문에 발생하는 문제가 있습니다. 갤럭시 s3 의 경우에는 LTE, 3GS, WI-FI 등 세개의 인터페이스가 있습니다. 그런데 이런 인터페이스들이 사용을 안하면 비활성화 되어 있으면 사용하기 편할텐데 사용 안하더라도 활성화가 되어 있는 데다가 잘못된 (구동하지 않는) IP 주소를 가지고 있어서 문제가 됩니다.

무슨 문제가 있겠어? 라고 하지만 순수 자바 (Pure Java) 로 네트워크 레이어를 구현할 때, 만들어진 라이브러리를 안드로이드로 포팅시 발생하는 문제입니다. 이를 해결하기 위한 방법입니다.

인터넷에 연결이 되어 있고 (LTE,3GS,WI-FI 상관하지 않고) 접속되어 있는 상태에서의 가지고 있는 IP 주소를 가져오는 방법입니다.

Socket socket = new Socket("www.google.com", 80);
String localAddr = socket.getLocalAddress().getHostAddress();
Log.d(TAG, "local address is : " + localAddr);

생각보다 자주 부딛히는 문제라서 정리합니다.





기존 계정에서 실행하는 것은 문제가 없는데 , 네트워크 상에서 (즉 WorkGroup 으로 묶인 계정으로) 로그인 해서 사용할려고 실행할 때 발생하는 에러를 해결하는 방법 입니다.

   
  Debugger entered--Lisp error: (error "The directory ~/.emacs.d/server is unsafe")
     signal(error ("The directory ~/.emacs.d/server is unsafe"))
     error("The directory %s is unsafe" "~/.emacs.d/server")
     server-ensure-safe-dir("~\\.emacs.d\\server\\")
     server-start(nil)
     call-interactively(server-start t nil)
     execute-extended-command(nil)
     call-interactively(execute-extended-command nil nil)


대충 이런 식으로 에러가 발생합니다. 붉은색 으로 표시된 디렉토리 이름은 상황에 따라 다르게 나옵니다. 제 경우에는 위와는 살짝 다르게 "C:\Users\sdssss\AppData\Roaming\.emacs.d\server" 이런식으로 표시 됐습니다.

이유는 간단합니다. 붉은색 으로 표시되는 디렉토리의 소유자 (Owner)가 다르기 때문입니다. 소유자를 바꿔주던가 하는 식으로 해결하는 방법도 있지만 저는

.emacs 파일을 열어서 맨 아래쪽에 다음과 같이 추가해 줍니다.

  
(require 'server)
   (when (and (= emacs-major-version 23)
           (= emacs-minor-version 1)
           (equal window-system 'w32))
   (defun server-ensure-safe-dir (dir) "Noop" t))
   (server-start)


간단하게 설명하자면 server-ensure-safe-dir 이라는 함수가 안전한지 여부를 확인하는 함수인데 소유자 건으로 이 함수에서 에러를 뱉어 내는 것입니다. 이 함수를 무조건 t 만 리턴하는 거수기 함수로 바꿔버리면 모든 것은 간단하게 끝이 납니다.

그리고 추가로 "C:\Users\sdssss\AppData\Roaming\.emacs.d\server"  이 디렉토리 의 마지막 즉 server 디렉토리를 $HOME/.emacs.d 안으로 복사해줍니다. 이건 또 왜 해주냐면, server-ensure-safe-dir 함수가 거수기가 되 버려서 , $HOME 밑에서 server 의 존재를 찾습니다. 따라서 복사해주면 모든 것이 OK 입니다.





"웹상에서 보이는 모습"




플래시 사진 갤러리를 만들었으면 실제로 웹 사이트에 적용해 보기로 합니다. 제일 먼저 생각해야 할 것은 네트워 크상에 올리는 방안에 관해서 입니다. 시나리오는 다음과 같습니다. 

1. 기존 이미지 파일들이 나열된 XML 파일을 네트워크상에서 읽어온다. 
2. XML 파일을 읽어서 사진이 저장된 사진의 URL을 가져온다. 
3. 기존과 동일하게 플래시에 적용 시킨다. 

더 간단하게 이야기 하자면 'XML 파일을 네트워크상에서 읽어오게 하는 일'입니다. 

기존 FLA 파일에서 ActionScript 부분만 수정해 주면 됩니다. 

var urlXML:String = "http://192.168.10.16:8080/pub/imagelist.xml";
//var hardcodedXML:String="<photos><image title='2or0'>2or0.jpg</image><image title='conan'>conan.jpg</image><image title='Girls_gene'>Girls_gene.jpg</image><image title='Mystery'>mystery.jpg</image></photos>";
var loader:URLLoader = new URLLoader();

urlXML 변수는 XML 파일이 저장된 위치를 지정해주는 변수입니다. 
hardcodedXML 은 외부 파일로 저장하기로 했기 때문에 comment 처리 해줬습니다. 기존의 쓰여진 내용은 urlXML 에 지정된 XML 파일에 저장되어 있습니다. 
외우에 있는 XML 파일을 로딩하기 위해서 loader 를 선언해 줍니다. 


loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
loader.load(new URLRequest(urlXML));

loader 에서 load 가 끝났을 때 실행되는 이벤트 핸들러를 지정해 줍니다. (필수)
urlXML 이 지정하고 있는 XML 파일을 읽어오게 loader.load 로 수행해줍니다. 

// CODE FOR HARDCODED XML =====
// imageList = XML(hardcodedXML);
// fl_parseImageXML(imageList);
// END CODE FOR HARDCODED XML

기존 XML 에서 이미지리스트를 얻어오는 부분은 Comment 처리 해줍니다. 

function loadCompleteHandler (evt:Event) :void {
var hardcodedXML:String = loader.data;

imageList = XML(hardcodedXML);
fl_parseImageXML(imageList);

}

XML 로딩이 끝났을 때 불려지는 이벤트 핸들러 함수 입니다. 로딩이 끝나면 loader.data 에 읽어온 XML 내용이 들어 있습니다. 이것을 기존에 쓰던 hardcodedXML 에 저장하고 기존 이미지리스트 분리하는 함수를 로딩해 줍니다. 

이렇게만 바꿔주고 imagelist.xml 파일과 플래시에서 불러오는 image 들을 적절한 위치에 복사해주면 됩니다. (저는 http://192.168.10.16:8080/pub 밑에 몰아 넣습니다)

Flash CS4 용 소스로 변환해 뒀습니다.  
imagelist.xml 예시 입니다. 

[관련포스트]

+ Recent posts