2016년 10월 21일 금요일

[월간 AJ TED 제 13호] 다목적 멀티 타이머 및 스탑워치 앱을 개발하였습니다.

2016년 10월 월간 AJ TED 제 13호를 발행합니다.
앱을 개발한 동기는 여러가지 상황에 맞는 타이머, 기록이 보존되는 스탑워치를 만들어보자고해서 시작하였습니다.

* 이번에 개발한 앱(App)의 제목은 무엇인가요?

모두의 타이머(Everybody's Timer) 입니다.


*어디서 다운로드 받을 수 있나요?

*모두의 타이머는 어떤 기능이 있나요?

평소 타이머를 사용 목적에 따라 여러 개를 미리 설정해놓고 계속 사용했으면 하는 마음이 들 때가 가끔 있죠? 
스탑워치로 기록을 잴 때 기록이 계속 누적되거나 이전 기록을 별도로 보관하여 보고 싶은 경우가 가끔 있죠?
이런 분들을 위해 제가 거금의 시간을 들여 만들어 보왔습니다.


사용자가 자유롭게 생성하여 사용하는 멀티 타이머와 멀티 스탑워치입니다.
사용한 기록이 그대로 보관되고, 연속하여 사용할 수 있습니다.

1. 자유롭게 생성/편집/삭제 가능한 멀티 타이머 기능이 있습니다.

2. 여러개의 타이머 동시 실행 가능합니다.


3. 시간 간격에 따라 타이머 반복 횟수 무제한 지정 가능합니다.

4. 자유롭게 생성/편집/삭제 가능한 멀티 스탑워치 기능이 있습니다.

5. 여러개의 스탑워치 동시 실행 가능, 스탑워치별 기록 보관할 수 있습니다.

7. 사용한 기록 데이타베이스에 항상 유지됩니다.

 *모두의 타이머는 어떻게 사용하나요? 

사용방법 안내 동영상: https://www.youtube.com/watch?v=gqAx3961XNY

2016년 8월 8일 월요일

[안드로이드 앱 개발] 데이타베이스를 통한 날짜,시간 저장 및 변환에 관한 생각

안드로이드 앱 개발을 하면서 

시간 값을 어떻게 저장하고 

필요할 때 꺼내어 변환하여

쓸지에 대해 조사 및 구현한 결과를

조금 정리해 놓으려고 합니다.

* SQLite => DateTime 형으로 생성
(가장 경제적임)
"setting_total_datetime DATETIME DEFAULT CURRENT_TIMESTAMP,"


* 구현할 내용의 Item => String 형
(특별한 변환없이 데이타베이스와 입출력)
데이타베이스에서 꺼낸 값을 String형으로 저장 보관


* 시간 변환 방법 => String -> Datetime 
(필요한 경우에)
1. SimpleDateFormat 이용
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

2. 예외처리구문에서 Date형으로 변환
try{
Date date = (Date) formatter.parse(aItem.getSetUpTime());
}catch (Exception ex){    }
3. Calendar을 이용하여 년도,월,일,요일,시,분,초 얻기
Date date = new Date(time);Calendar cal = Calendar.getInstance();cal.setTime(date);
hour=cal.get(Calendar.HOUR);minute=cal.get(Calendar.MINUTE);second = cal.get(Calendar.SECOND);

*데이타베이스에 저장할 때
(가장 많은 정보를 저장할 수 있는 형태)
4. Calendar을 이용하여 시간 값으로 자장
cal.getTime();

5. 시간값 비교할 때는 TimeStamp형태로 비교

2016년 7월 13일 수요일

[월간 AJ TED 제 12호] 아이들을 위한 Baby Pang Pang 게임을 업데이트하였습니다.(Updated 'Baby Pang Pang' game for your baby)

아이들을 위한 Baby Pang Pang  게임을


게임 설명

1.  풍선이 나타나는 빈도와 속도가
    레벨에 따라 달라집니다.

2. 풍선이 터질때마다 동물이 랜덤 생성되고,
그 동물에 맞는 재미있는 소리가 같이 나옵니다.

3. 풍선이 터질때 레벨에 따라 점수를
획득할 수 있습니다.

4. 점수는 금,은,동(3위)까지 저장됩니다.

5. 다양한 배경과 아이템들이 준비되어 있습니다.









2016년 7월 10일 일요일

[안드로이드 앱 개발] 리스트뷰 안에 있는 EditText 입력 및 포커스 처리하는 방법입니다. (How to resolve some problems of listview in android)

리스트뷰 안에 있는 EditText 처리에 관해

잘 정리되어 있는 글이 있어 링크합니다.

안드로이드에서는 리스트뷰 사용이 참 어렵습니다.

1. 리스트뷰안에 EditText가 스크롤시 기존의 값이 사라지는 문제

2. 리스트뷰에서 스크롤시 EditText의 값이 9줄(화면에 보이는 개수)마다
 중복되어 나타나는 문제

3. 리스트뷰의 EditText 첫 클릭시 포커스를 잃어버리는 문제

등등이 있어 생각되로 구현이 되지 않는 경우가 있습니다.

저 또한 아래의 문제로 긴 시간동안

고생하였습니다.

이리 저리 고쳐보다가 대화상자로 처리할까하다 막판에

찾은 소중한 자료입니다.

이대로 적용하니 정말 깔끔하게 작동합니다.

다음과 같은 문제를 한 방에 해결할 수 있습니다.



2016년 7월 8일 금요일

[월간 AJ TED 제 11호] 아이들을 위한 베이비 팡팡 게임을 업데이트하였습니다.

예전에 만들었던 베이비 팡팡게임을

업데이트하였습니다.


계속해서 게임을 할 수 있도록 

여러가지 재미와 변화를 주었습니다.

1. 여러가지 테마가 있습니다.

2. 테마별로 다양한 아이템들이 등장합니다.

3. 화면을 클릭하면 재미있는 불꽃놀이가 펼쳐집니다.

4. 아이템을 클릭하시면 점수를 획득하실 수 있습니다.

5. 시간안에 많은 점수를 모으세요.












2016년 6월 22일 수요일

[월간 AJ TED 제 10호] 노래방 고민을 한방에 해결한 노래방 18번 앱을 업데이트하였습니다.

노래방 고민을 한방에 해결한

노래방 18번 앱을 업데이트하였습니다.


1. 세대별(나이별) 노래 목록 보기 기능

2. 분위기별로 노래 목록 보기 기능

3. 남/여별로 노래 목록 보기 기능

4. 나의 18번으로 등록하여 나의 노래만 보기 기능

5. 새로운 노래 등록하기 기능

6. 노래가사/가수명/노래제목 보기 기능

7. 선택 노래 미리 들어보기 기능

8. 최신 노래 목록 업데이트 기능










2016년 6월 20일 월요일

[안드로이드 개발] ListView의 항목이 중복해서 보일 때 해결방법


ListView의 경우 가려져 있다가 보이는 경우

기존 뷰를 재사용해서 표시한다고 한다.

else 부분의 루틴을

vh = (ViewHolder) convertView.getTag(); 
와 같이 처리했을 경우
동일한 내용이 반복해서 보일 수 있다.

노란색 음영으로 되어 있는 저 부분이

핵심이다.

결론적으로 재사용된 뷰의 표시내용을 변경해주면

해결된다.



@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder vh;
    if(convertView==null){
        vh = new ViewHolder();
        convertView =(LinearLayout) inflater.inflate(R.layout.list_menu, null);

        vh.mText=(TextView) convertView.findViewById(R.id.Name);
        vh.mImage=(ImageView) convertView.findViewById(R.id.Icon);
        vh.mCheckBox=(CheckBox) convertView.findViewById(R.id.mCheckbox);

        convertView.setTag(vh); 
    } else { 
        vh = (ViewHolder) convertView.getTag(); 
    } 

    vh.mText.setText(mName.get(position));
    vh.mImage.setImageDrawable(mIcon.get(position));
    vh.mCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton check, boolean isChecked) {
            if(check.isChecked()){
                Toast.makeText(mContext, "..."+mName.get(position)+"..."+position, Toast.LENGTH_SHORT).show();
            }
        }
    });
    return convertView;
}

[안드로이드 개발] 미리 만들어 놓은 Database를 불러와서사용하기

미리 만들어 놓은 sqlite 데이타베이스를 

불러와서 사용하는 방법에 대해 알아보자.

특히 사전 등과 같이 많은 데이타가 앱인 경우 

앱에 포함시켜 배포하고 최초 실행시 복사하여

사용한다.

---------------------[작업 순서]------------------------

1. assets/db 폴더를 생성한다.

- 안드로이드 app/src/main/ 아래 직접 생성한다.

- db폴더안에 database파일을 복사하여 둔다.


2. App 최초실행시 내부로 복사한다.

- onCreate 함수에서 기존의 테이블 생성하는 코드를 모두 삭제하고 

사용자 데이타베이스 유무를 체크하여

없을 경우 복사하여 사용한다.

// Checking whether file is or not
public boolean isCheckDatabase(){
String filePath = PACKAGE_DIRECTORY + "/databases/" + DATABASE_NAME;
File file = new File(filePath);
if (file.exists()) {
return true;
}
return false;
}
// Copying inside app storage from "/db/xxxx.s3db" in assetspublic void copyDataBase(){
    Log.d("Working", "copyDatabase");    AssetManager manager = mContext.getAssets();    String folderPath = PACKAGE_DIRECTORY + "/databases";    String filePath = PACKAGE_DIRECTORY + "/databases/" + DATABASE_NAME;    File folder = new File(folderPath);    File file = new File(filePath);
    FileOutputStream fileOut = null;    BufferedOutputStream bufferOut = null;    try {
        InputStream inputStr = manager.open("db/" + DATABASE_NAME);        BufferedInputStream bufferStr = new BufferedInputStream(inputStr);
        if (folder.exists()) {
        }else{
            folder.mkdirs();        }


        if (file.exists()) {
            file.delete();            file.createNewFile();        }

        fileOut = new FileOutputStream(file);        bufferOut = new BufferedOutputStream(fileOut);        int read = -1;        byte[] buffer = new byte[1024];        while ((read = bufferStr.read(buffer, 0, 1024)) != -1) {
            bufferOut.write(buffer, 0, read);        }

        bufferOut.flush();
        bufferOut.close();        fileOut.close();        bufferStr.close();        inputStr.close();    } catch (IOException e) {
        Log.e("Error : ", e.getMessage());    }
}

public void onCreate(SQLiteDatabase db) {
    boolean bResult = isCheckDatabase();    // DB가 있는지?    Log.d("Workign", "DataBase Check="+bResult);    if(!bResult){  // DB가 없으면 복사        copyDataBase();    }
}