[2015 / 팀 프로젝트]

기업연계 프로젝트 - 말벗




프로젝트 기간: 2014.11.01 ~ 2015.10.31

프로젝트 참여 기간: 2015.03.25 ~ 2016.01.19


과제명: 마이크로 웹페이지 기반 현장중심형 SNS


목표: 1. 마이크로웹페이지 기술 기반 현장중심형 SNS 스마트앱 S/W 개발

       2. 마이크로웹페이지 태그 구성 기술 개발

       3. 마이크로웹페이지 저작도구 및 SNS 확장 서버 개발


역할: 안드로이드 개발





2015년 2월에 졸업하고 연구실 생활을 하다가 교수님의 추천으로 한남대와 대전의 IT기업과 함께 프로젝트를 진행하게 되었다.

프로젝트 경험도 쌓고, 실제 기업에서는 어떻게 개발을 하는지 배울겸 해서 시작하게 되었는데

프로젝트가 진행되면서 기업의 참여도가 점점 낮아져서 조금 아쉬웠던 프로젝트이다.



개발한 기능 요약


처음 우리 연구실이 프로젝트에 참여 당시에는 안드로이드 개발만을 담당하였다. 하지만 한달마다 대전 - 부산을 번갈아가며 회의를 하면서

네이티브로 했다가 웹앱으로 바뀌고, UI도 이랬다가 저랬다가 바뀌는 등 프로젝트의 방향이 확실하게 정해지지 않았다.

이때부터 조금 불안했지만...그래도 프로젝트 처음이니 그러려니 했다.(하지만 프로젝트 시작 후 반년이 지났다는 사실을 들은건 한참 뒤..)

그럴 때마다 우리는 결과물을 갈아엎고 다시 만들어야 했지만 딱히 문제가 되진 않았다.

결국 반년이 지나고 10월즘에 네이티브쪽으로 기울었으나, 원래 기업에서 맡기로 했던 서버 부분이 우리가 하는 것으로 바뀌었다.


그래서 나를 포함한 3명 중 A라는 후배가 서버를 맡기로 하였고, B라는 후배와 내가 안드로이드 개발을 맡게 되면서

지옥으로 가는 프로젝트가 시작되었다


프로젝트를 하면서 좋았던 점부터 말하자면


1. 새로운 기술(나에게)인 QR코드에 대해서 알게 되었다.


QR코드 데이터 구성 요약


한남대에서 만든 QR코드는 먼저 구분자를 이용해서 4개의 데이터로 분류된다.

첫 번째는 한남대에서 만든 어플리케이션의 URL

두 번째는 웹 페이지의 HTML 소스가 들어가있다(이로 인해 QR코드의 크기가 커지고 인식률이 낮아졌다).

세 번째에는 웹 페이지 템플릿이 올라가 있는 URL(예: 구글 드라이브)이 들어있고

네 번째에는 앞선 두 번째의 HTML에 들어갈 데이터들이 다른 구분자로 구분되어 들어가있다.


결국 미리 QR코드에 HTML과 데이터를 넣어놓고 파싱하여 페이지를 보여주는 것이다.

이 데이터들이 암호화되고 압축 되어서 QR코드의 크기가 작아지고, 특히 HTML의 디자인과 기능이 강력해진다면 더 좋았을 것 같다.


QR코드를 이용해서 개발하는 것은 정말 재미있었다. 처음에는 스캐너를 자체적으로 만들려고 했지만 교수님의 의사결정으로 Zxing이라는 라이브러리를 이용해서 개발하게 되었다. Zxing은 QR코드뿐만 아니라 바코드까지 인식할 수 있는데 한남대에서 보내준 테스트용 QR코드는 크기가 너무 커서 QR코드로 인식되는게 아니라 바코드로 인식되는 문제가 있었다. 이는 QR코드 스캐너를 실행할 때 QR코드만을 스캔하도록 설정하여 해결하였으나, 크기가 워낙 커서 스캔하는데 시간이 많이 걸리게 되었다. 이후에 조금 크기가 줄어들어 인식률 자체는 많이 상승됐다.



2. HTTP통신

사실 이전에 한이음 프로젝트를 하면서 간접적으로 해보았는데, 그 때는 Bassio에서 제공해주는 함수를 사용했었다. 팀원이 만든 웹서버를 직접적으로 HTTP로 통신한 것이 이번이 처음이었다.


먼저 List<BasicNameValuePair>에 HTTP로 보낼 파라미터 이름(웹 서버와 맞춰야함)과 값을 넣어준 다음

HttpPost 객체에 Entity로 설정해주고 DefaultHttpClient 객체를 이용해서 통신할 수 있다. 

서버의 리턴값을 받으려면 HttpResponse에 실행한 객체를 넣어주고 HttpEntity 객체로 getEntity() 메소드를 이용해 받을 수 있다.

HTTPS로 보낼려면 SSLSocketFactory를 이용해서 SSL인증을 해주면 된다. (모든건 AsyncTask내에서 이루어졌다)


엄청 간단하게 HTTP 통신을 할 수 있었는데(더 간단하게는 HttpURLConnection으로..) 그때는 통신을 한다는 것 자체가 신기해서 서버 담당인 팀원과 이것저것 많이 테스트 해보면서 놀았다.

그러다 파일도 업로드해보았는데 일정 크기 이상의 파일(확인해보니 4MB)을 업로드하니 제대로 전송이 되지 않았다. 이는 php.ini에서 기본으로 설정된 파일 크기가 4mb였기 때문에 이를 더 크게 늘려주면서 해결할 수 있었다.


개발 자체는 정말 재밌게 했었다. 사실 시간에 쫓기는 상황이 조금 있었지만 밤을 새면서 개발하는 것이 재밌었고 기능이 완성될 때마다 성취감이 마구 생겼다. 문제는 처음에 시간이 갈수록 프로젝트의 방향이 이상하게 흘러갔고, 프로젝트 초기부터 QR코드의 구성을 알려달라고 했지만..묵묵부답에 일단 개발을 먼저 해라고 하여.. 진행이 잘 되지 않았다. 그러다 6개월이 지나고서야 QR코드를 받을 수 있었고 데이터 파싱은 String으로 받아와 split하여 어렵지 않게 할 수 있었다.


이 프로젝트를 수행하면서 정말 힘들었던 것은 회의를 할 때마다 바뀌는 프로젝트의 방향과 UI, 그리고 팀들(기업과 한남대)간의 소통이 잘 이루어지지 않았던 것이다. 회의를 할 때마다 네이티브앱에서 웹으로 바뀌었다가 다시 네이티브앱으로 왔다가 하이브리드로 갔다가 계속 바뀌다가 결국 네이티브 앱으로 확정이 됐다. 그러다보니 당연히 UI도 계속해서 변경되었고 회의를 준비하기 위해 프로토타입을 다시 만들어야 했는데, 막상 만들어서 가면 다른 팀은 준비가 안되어서 우리팀에 대한 회의만 진행하였다(그때는 같이 진행하고 있는줄 알았지만 시간이 지나고보니 부랴부랴 만들고 있다는걸 알게 되었다).

그렇게 회의를 진행하고 돌아와서 개발을 하여 다음 회의가 되면 그전 회의 때 결정한 사항들이 틀린 것이 되고 잘못된 것이 돼버린다.....맥빠지는 상황이 많이 나와서 심적으로 조금 힘들었다...그래서 구글 그룹스를 만들어서 개발 중 발생한 이슈나 의사 결정이 필요한 것들을 공유하여 다른 팀들과 소통하려고 노력했다. 노력 결과 서로가 보는 시선이 조금씩 같아지는 것을 느낄 때 쯤(정말 몇 개월 남지 않았을 때...) 의견이 모아져서 마음 놓고 개발을 할 수 있어서 다행이었다.


프로젝트를 진행하면서 역시나 팀원들간의 소통과 협력이 얼마나 중요한지 뼈저리게 느낄 수 있었다. 그리고 서로가 다른 그림을 보고 있다면 얼마나 피곤해지는지도 알 수 있어서 회의록 작성과 문서화의 중요성도 알게 해준 고마운 경험이다. 앞으로는 정말 협업이 원활하게 이루어지도록 노력하고 또 노력해야겠다.

'프로젝트 > 팀 프로젝트' 카테고리의 다른 글

한이음 프로젝트 - LifePoint  (0) 2018.01.11



[2012 / 개인과제]

객체지향 프로그래밍 과제 - 백과사전



2012년 9월부터 12월까지 객체지향 프로그래밍 강의를 들으면서 한달동안 네이버 오픈API를 이용해 간단한 백과사전 프로그램을 만들었다.

당시 오픈API와 XML파싱이란걸 처음 해보았는데 재밌어서 이후에도 트위터 검색 결과를 파싱해보면서 놀았던 기억이 있다..


이때는 XML파서를 몰라서 파싱을 손수 다 받아와서 태그로 자르고 분류해서 파싱하였다..



public void search(String s)
{
String ggg="";
try {
String a=String.format(defaultUrl + "?key=%s&query=%s&target=encyc&start=1&display=10",
mykeycode,URLEncoder.encode(s, "UTF-8"));
URL u=new URL(a);
BufferedInputStream b=new BufferedInputStream(u.openStream());
while(true)
{
int d=b.read();
if(d==-1) break;
ggg+=(char)d;
}
b.close();
DefaultTableModel tm = (DefaultTableModel) jt_o.getModel();
tm.setRowCount(0);
String ss[] = ggg.split("[<>]");
String title = "", des = "", link = "";
for (int i = 0; i < ss.length; i++)
{
if (ss[i].equals("title"))
{
title = kordecode(ss[i + 1].replaceAll("&lt;b&gt;", "").replaceAll("&lt;/b&gt;", "").replace("&amp;amp;", ""));
}
if (ss[i].equals("link"))
{
link = kordecode(ss[i + 1]);
}
if (ss[i].equals("description"))
{
des = kordecode(ss[i + 1].replaceAll("&lt;b&gt;", "").replaceAll("&lt;/b&gt;", "").replaceAll("&amp;quot;", "").replace("&amp;amp;", "").replace("&amp;gt;", "").replace("&amp;lt;", ""));
}
if (ss[i].equals("/description"))
{
if (!title.startsWith("Naver"))
{
tm.addRow(new Object[] { link, title, des });
}
}
}
record.Rec(jtf_s.getText(), "data.txt");
} catch (Exception e) {
e.printStackTrace();
}

}


이렇게 사용자가 입력한 검색어를 받아와 검색API에 넣어주고 그 결과를 문자 하나하나 받아와(...) String으로 저장하였다. 그리고 태그로 잘라서 내가 원하는 태그가 나왔을 경우

해당 값을 DefaultTableModel에 추가하여 결과 리스트를 만들었다.

여기서 결과는 한글로 잘 나오는데 자바 프로그램에서는 한글이 깨지는 문제가 발생하여 URLEncode, Decode 등.. 여러가지를 해보다가 


public static String kordecode(String kor) {
try {
if (kor != null)
kor = new String(kor.getBytes("8859_1"), "UTF-8");
return kor;
} catch (Exception ex) {
}
return kor;
}


웹에서 기본적으로 쓰는 ISO8859-1을 UTF-8로 변환시켜 한글깨짐 현상을 해결하였다.

그리고 실시간 급상승 키워드도 보여주도록 하여 그 키워드로 바로 검색할 수 있도록 하였다.


여기까지 개발을 하고 JFrame의 UI를 만지고 있다가 아주 중요한 사실을 알았다.

검색 결과로는 백과사전의 내용 모두가 오는 것이 아니라 일부만 오고 대신 전체 내용이 담긴 URL이 같이 온다는 사실! 일부 내용만 보여준다면 백과사전이라고 할 수 없다. URL의 내용을 표시해주던지 그 페이지로 이동을 시켜주어야만 했다. 해당 내용을 다시 파싱해도 됐지만 똑같은 일의 반복이기 때문에 하이퍼링크를 걸어보기로 했다.


public static void executeCmd(String[] cmd) {
Process process = null;
try {
process = new ProcessBuilder(cmd).start();
SequenceInputStream seqIn = new SequenceInputStream(process.getInputStream(), process.getErrorStream());
Scanner s = new Scanner(seqIn);

while (s.hasNextLine() == true) {
System.out.println(s.nextLine());
}

} catch (IOException e) {
e.printStackTrace();
}
}
public static String[] getUrlCmd(String url) throws Exception {

String[] cmd = null;
if (System.getProperty("os.name").indexOf("Windows") > -1) {
cmd = new String[] { "rundll32", "url.dll", "FileProtocolHandler",url };
} else {
String[] browsers = { "firefox", "mozilla", "konqueror","eqiphany", "netscape" };
String browser = "";
try {
for (int i = 0; i < browsers.length && "".equals(browser); i++) {
if (new ProcessBuilder(
new String[] { "which", browsers[i] }).start().waitFor() == 0) {
browser = browsers[i];
}
}
if ("".equals(browser)) {
throw new Exception("Could not find web browser");
} else {
cmd = new String[] { browser, url };
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return cmd;
}


먼저 설치된 브라우저를 찾고 해당 URL을 이용해서 프로세스 객체를 이용하면 브라우저가 실행되면서 URL로 이동한다.

당시에는 이해를 잘 못하고 사용하였지만 정확한 동작 원리를 다시 찾아봐야겠다.


그외에는 파일 I/O로 검색 기록과 메모 기능을 만들었다. 주요 기능은 아니어서 소스만 첨부한다.


Memo.java

Record.java

Search.java

UpKeyword.java




처음으로 목적을 가진 프로그램을 만들어보아서 의미가 나름대로 컸고 API사용법과 파싱이라는 재밌는 개념을 알게 해준 과제로 생각을 넓게 해준 경험이었다.

그때 이런 것들을 많이 만들어보고 경험했다면 하는 아쉬움이 남고 API나 외부소스를 사용할 때 정확한 이해를 바탕으로 사용한다면 더 좋은 코딩을 할 수 있었을 텐데 그러지 못한게 아쉽다. 지금부터라도 실천을 해야겠다.



[2014 / 팀 프로젝트]

한이음 프로젝트 - LifePoint



기간: 2014.04.10 ~ 2014.12.09


주제: 위치기반 SNS를 이용한 정보 제공 서비스 개발


개요: 일반 시중 지도 서비스는 업데이트가 늦기 때문에 정확한 정보를 얻기에는 불편함이 있다그러한 점을 보완하기 위해 정보의 집합소인 SNS를 연동하여 사람들끼리 정보를 공유하게 되면그 정보자체가 지도의 핀이 되어 하나의 위치정보가 완성된다이러한 정보가 카테고리 별로  하나 둘 모아져 사람들에게 제공하는 서비스가 바로 라이프 포인트(LIFE POINT) 이다


역할: 안드로이드 개발 - 지도관련 기능





2014년  연구실 인원들과 한이음을 통해 프로젝트를 수행하였다. 처음엔 인원이 7명이었지만 아이디어를 내는 과정에서

2개의 팀으로 나뉘어졌고 나를 포함한 4명이 한 팀으로 수행하였다.

개발하는 과정에서 그때 서비스 중이던 Baas.IO로 서버를 구축해보자고 하여 사용해보았다. 지금은 서비스가 종료되어 정확한 정보를 알 수 없는게 아쉽다.



제작목표

위치기반 서비스를 활용한 SNS서비스 어플리케이션 제작

작품개요

일반 시중 지도 서비스는 업데이트가 늦기 때문에 정확한 정보를 얻기에는 불편함이 있다그러한 점을 보완하기 위해 정보의 집합소인 SNS를 연동하여 사람들끼리 정보를 공유하게 되면그 정보자체가 지도의 핀이 되어 하나의 위치정보가 완성된다이러한 정보가 카테고리 별로 하나 둘 모아져 사람들에게 제공하는 서비스가 바로 라이프 포인트(LIFE POINT) 이다

작품의 차별성

현재 보통 생활정보를 알려주는 어플리케이션은 운영자가 직접관리 하는 정보들로한정된 정보만을 얻을 수 있다하지만 LIFE POINT는 SNS의 특징을 살려 사용자들의 실용적인 정보를 실시간으로 공유하여 더 포괄적이고 정확한 정보를 획득하기에 유용하다또한 위치 기반으로 지도를 이용해 더욱 직관적이고 쉽게 정보를 탐색할 수 있다.

주요기능

  •  SNS의 한 종류인 페이스북 계정을 연동하여 로그인이 가능하다.

- GPS를 이용하여 자신의 위치에 가까운 생활정보를 검색 및 조회 할 수 있고그 정보에 대한 간단한 코멘트를 달 수 있다.

  • 자신이 방문한 장소에 대한 새로운 정보를 별점사진과 글로 등록할 수 있다.

사용자는 잘못된 장소정보에 대한 수정 요청과 불법게시물을 신고 할 수 있다.

기대효과

가맹점주와의 제휴로 가맹점주는 매출상승효과를 소비자는 할인을 받을 수 있다그로 인한 수수료를 수익으로 창출 가능하다.


요약본



이 프로젝트의 주요 기능인 '지도에서 장소 검색' 기능은 네이버의 검색API를 이용하였다. GPS 신호를 이용해서 이용자가 어떤 장소에 있는지 파악하고, 이용자의 검색 키워드와 붙여서 검색API에 날린 뒤 결과들을 파싱하여 지도에 나타나도록 하였다.


여기서 지도에 뿌려줄 때 문제가 발생 했었는데 검색API의 결과로 오는 위치값은 KTM 좌표계의 값으로 보내주었지만 안드로이드용 지도에서는 WGS84 좌표계의 값이 필요했었다. 처음에는 이상한 위치에 계속 핀들이 박혀서 검색을 잘못한 줄 알았지만 웹에서는 제대로 나오는 것을 보고 좌표계를 알아본 뒤 다음의 좌표계 변환으로 문제를 해결하였다.


이후에는 별다른 문제없이 개발하였지만 그럼에도 내가 이 글을 남기는 이유는 2가지가 있다.



1. 지식이 늘었다.

위에서 말한 '지도에서 장소 검색' 기능에 결과를 지도에 뿌려주고 정보표시용 말풍선을 달았더니 결과값이 밀집된 곳에는 상당히 지저분해 보였다. 그래서 말풍선은 삭제하는 대신 핀을 선택하면 하단에 새로운 뷰가 올라와 정보를 보여줄려고 했다. 그렇게 PopupWindow와 LayoutInflater에 대해서 조금 알게되었다.


@Override
public void onFocusChanged(NMapPOIdataOverlay arg0, NMapPOIitem arg1) {
PopupWindow popup = new PopupWindow(addsearch.this);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//팝업으로 띄울 커스텀뷰를 설정하고
View view = inflater.inflate(R.layout.pininfo, null);
popup.setContentView(view);
//팝업의 크기 설정
popup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//팝업 뷰 터치 되도록
popup.setTouchable(true);
//팝업 뷰 이외에도 터치되게 (터치시 팝업 닫기 위한 코드)
popup.setOutsideTouchable(true);

먼저 PopupWindow를 생성하고 미리 만들어놓은 뷰를 이용하여



LayoutInflater로 View객체를 만든다음 PopupWindow의 컨텐트뷰로 설정해준다.

그런 뒤에 데이터를 입력하고


popup.showAsDropDown(resultmap);


를 해주게 되면 인자로 넘어온 뷰의 바로 밑에 PopupWindow가 나타나게 된다.

뷰가 가장 밑에 있을 경우 자동으로 위쪽에 표시되게 된다.

그리고 애니메이션도 설정할 수 있는데 이것저것 해보다가 그냥 기본으로 설정했다.

실행시키면 




이렇게 나오게 된다. 상당히 재밌었고 내가 원하는 모양의 뷰를 원하는 동작으로 나타나게할 수 있어서 좋았다.



2. 팀워크란 무엇인가?

이때는 거의 모든게 처음이었다. 팀 프로젝트가 처음이었으니 당연히 역할을 분담하는 것도 처음이었고, 스케쥴 관리, 버전관리 등 거기에 내가 팀장까지 하게 되었으니....

당시에는 나를 포함한 4명이 모두 개발을 그렇게 잘하진 않았다. 그리고 개발에 조금 관심이 없던 인원도 1명(이하 A).

프로젝트 시작 후 몇 달간은 자기 역할에 따라 각자 개발하고 테스트하고 회의하고 나름대로 열심히 했었다. 문제는 중간즈음에 멘토님과 점검을 해보면서 남은 일정과 현재까지 완료된 부분 등 이것저것 체크해보니 조금 촉박하다는 것을 알았다. 그리고 A가 맡은 부분(글쓰기, 사진올리기 등)이 완성이 되지 않았다는 것.

그후로 A가 맡은 부분을 나도 같이 보았고 baas.io의 문서를 보면서 고민하고 서로 힘든 날을 보낸 결과!!

어느정도 완성이 되었고 나머지부분은 A가 마무리할 수 있도록 도와주었다. 그런 뒤 남은 기간은 팀원들과 같이 디자인을 적용해보고 수정하는 작업, 페이스북 연동, 갤러리에서 사진 가져오는 등 밤샘도 하면서 개발에 박차를 가했다. 결국 당초에 생각했던 기능들을 모두 개발하진 못했지만 주요 기능들로 꼽았던 것들은 모두 개발하여서 한이음에서 성공판정을 받을 수 있었다.


나는 사실 프로젝트가 끝난 뒤에 불만이 많이 있었다. 개인과제만 해왔던 탓인지 혼자서만 개발을 했다. 데이터베이스 설계라던지 서버 통신할 때의 키워드나 사소한 것까지 내가 생각하거나 개발한 것에 맞출려고 했고 회의를 할 때에는 이러한 것들을 피드백하거나 맞출려고 노력하지 않았다. 이러다 보니 팀원이 자기 역할에 맞게 개발을 해서 나에게 주면 나는 그것을 보고 또 다시 내가 개발한 것에 맞도록, 내가 생각한 것에 맞도록 다시 코딩하면서 시간은 2배로 들게 되었다. 이러한 일들이 지속 되다 보니 팀원은 어느새 의욕을 잃게 되었고 나는 혼자서 개발을 한다고 화내고 있었던 것이다.


그리고 시간이 지나고 팀원이었던 친구가 그때 자신의 고충을 얘기해주면서 팀워크란 무엇인가 많이 생각하게 되었다. 앞선 A의 경우처럼 프로젝트 진행을 따라오지 못하는 팀원을 도와주고 이끌어 주는 것도 팀워크라고 생각한다. 그리고 더 중요한 것은 평소에 사소한 문제라도 공유하고 함께 해결하려는 자세, 팀원들을 믿는 마음이라고 생각한다.


비록 원하는 만큼의 결과물은 아니었을 지라도 이런 깨달음을 얻게 해준 프로젝트라 아직까지도 생각하고, 기억하고, 추억하는 경험이다.

'프로젝트 > 팀 프로젝트' 카테고리의 다른 글

기업연계 프로젝트 - 말벗  (0) 2018.01.15

+ Recent posts