2011년 4월 26일 화요일

Hello JSON(2) : 본격 JSON

출처 : http://springjjeon.blog.me/70096404278


본격적으로 JSON에 대해서 알아보겠습니다.
비트박스에 북치기와 박치기만 있으면 된다면, JSON에서는 []와 {}만 알고 계시면 되겠습니다.
네, 눈치가 있으신분이라면, (1)편에서 말씀드린 색인배열과 연관배열을 떠올리시겠네요. ^^
먼저 용법을 한번 보겠습니다.
[10, 20, 30, '가나다',40]


네, 위 JSON식은 []로 엮여 있기 때문에, 색인배열이 되겠습니다.
실제 스크립트에서 사용방법은
<script type='text/javascript'>
var array = eval([10, 20, 30, '가나다',40]);
alert(array[3]);
</script>


JSON 의 기본 사용방법에 대해서 설명을 드리지 않고 예제가 나와 당황스러우실 것 같네요.
JSON는 문자열 형식으로 나타내도록 되어있습니다. (script에서 데이터 전송을 목적으로 하다보니, 어쩌면 당연할수도 있겠네요 ^^)
[10, 20, 30, '가나다',40] 이 부분이 JSON이 되겠구요. javascript에서는 eval 함수를 통해서 JSON을 해석한 객체를 생성해 줍니다.
alert창의 array[3] 용법을 통해 4번째 인수를 메시지창으로 보여주는 소스입니다.
색인배열을 보셨으니, 연관배열을 보셔야겠습니다. ^^
<script type='text/javascript'>
var array = eval({"KOR": 10, "ENG":20, "MATH": 30});
alert(array['KOR']);
alert(array.KOR);
</script>


색인배열은 HashTable 처럼 키와 값이 쌍을 이루는 구조로 되어 있기 때문에, 키:값을 쌍으로 정의해주게 됩니다.
array 에는 KOR, END, MATH 의 배열키를 가지고 각각의 값을 저장하고 있습니다.
접근은 색인배열처럼 Index로 접근하는 것이 아니라, 키값을 가지고 접근하게 됩니다.
array['KOR'] 과 array.KOR 으로 두 번 호출하였는데요. Javascript는 자체 객체관리구조를 색인배열의 형태를 이용하고 있습니다.
그래서 [‘KOR’]로 하거나 .KOR로 하거나 동일한 접근으로 인식해서 사용할 수 있습니다. ( (1)에서 말씀드렸네요 ^^)
자. 이제 JSON을 마스터 하셨습니다. (응??)
응용으로 좀 섞어서 써볼까요?
<script type='text/javascript'>
var array = eval(
[
{
"NAME" : "김선기",
"NUM" : 23,
"SCORE" : {"KOR": 10, "ENG":20, "MATH": 30},
"HIS" : [2,4,5]
},
{
"NAME" : "박동휘",
"NUM" : 24,
"SCORE" : {"KOR": 30, "ENG":40, "MATH": 50},
"HIS" : [7,3,7]
},
{
"NAME" : "박종훈",
"NUM" : 25,
"SCORE" : {"KOR": 1, "ENG":2, "MATH": 1},
"HIS" : [9,9,9]
},
]
);

alert(array[1].NAME);
alert(array[1].SCORE.KOR);
alert(array[1]['HIS'][1]);

</script>


보기 편하게 좀 들여쓰기를 해 보았습니다.
Array 의 색인배열에는 각각 학생의 데이터를 관리하는 연관배열이 들어있고,
학생의 데이터의 연관배열에는 이름, 번호, 점수를 가지고 있는 연관배열을 가지고 있고, 과거석차(?)를 의미하는 HIS 색인배열을 가지고 있습니다.
array[1].NAME 는 2번째 학생의 이름을 가져온 것이고,
array[1].SCORE.KOR 는 2번째 학생의 점수 연관배열에서 국어점수를 가져온 것이고,
array[1]['HIS'][1] 는 2번째 학생의 과거석차 기록 색인배열에서 2번째 값을 가져온 것입니다.
쉽게 이해 되시죠?
이제 정말 JSON을 마스터 하셨습니다.
JSON은 비동기로 데이터를 주고 받을 때, 사용하면 특히 편리합니다.
웹서비스로 데이터를 요청하여 받아올 때, 그것을 클라이언트에서 뿌려줄 때. 특히 편리합니다.
데이터를 보내주는 쪽에서도 몇 개의 반복문만 사용하면 쉽게 만들 수 있구요. ^^
XML로 주고 받을 수 도 있지만, 스크립트 언어에서 사용하긴 매우 귀찮을 수 있죠. ^^
이상으로 매우 허접한 JSON강좌를 마치겠습니다.
감사합니다. 

Hello JSON(1) : javascript의 배열

출처 : http://springjjeon.blog.me/70079792274


JSON(JavaScript Object Notation)은 web에서 데이터를 주고받을 때 사용하는 표현 방법입니다.
약자에서도 알수 있듯이 javascript에 기반하고 있습니다.


그렇기 때문에 우선 자바스크립트의 배열구조를 간단히 알아보도록 하겠습니다.
우리가 흔히 프로그래밍 코드에서 배열을 선언 할때는 인덱스([])를 사용해서 표현합니다.
javascript또한 마찬가지 입니다.
var array = new Array();
array[0] = 10;
array[1] = 20;
var arr = [10,20];


이런 코드가 가능합니다. 이는 색인배열이라고 부릅니다.
색인배열은 Index로 접근하게되며, 자바스크립트 특성답게 길이는 별도로 선언하지 않아도 됩니다.
배열의 길이가 자동으로 늘어나고, 자동으로 줄어들게 되기 때문입니다.
또한 맨아래 코드와 같이 한번에 선언해 줄 수 있습니다.
색인배열과 다른 배열이 있습니다. 배열이라고 생각하지 못한 경우도 있을텐데요.
var array = {};
array[“kor”] = 10;
array[“eng”] = 20;
array.jpn = 30;
var arr = {kor:10, eng:20, jpn:30};


사용법을 보면, hashtable과 유사한 느낌이 들 수 있습니다.
이를 연관배열이라고 칭합니다.
위 예제에서 jpn과 eng는 용법이 다르지만, 실제로는 똑같이 동작합니다.
그리고 맨 아래와 같이 한줄로 선언 할 수도 있습니다.
array와 arr는 똑 같은 내용을 가지게 됩니다.
한가지 특이점은 자바스크립트의 모든 객체들은 연관배열을 기초로 구성되어 있습니다.
그렇기 때문에document.location 과 document[“location”] 은 똑같이 작동합니다.
배열하면 제일 먼저 생각나는 것이 반복자(반복문, loop)를 생각하시게 될 겁니다.
색인배열이야 별 무리 없겠지만, 연관배열은 생소하신 분도 있으시겠습니다.
for(var key in array)
{
alert(array[key]);
}


마치 foreach와 비슷하게 동작하는걸 볼 수 있습니다.
연관배열과 색인배열과의 가장 큰 차이점은 length의 지원 유무입니다.
연관배열은 별도로 길이를 선언하는 로직이 없는 만큽, 길이를 검사할 수 있는 로직도 없습니다,
그러나 색인 배열은 length를 지원하고 있습니다.
JSON에 대해서 쓰려했는데 js의 배열이야기만 했네요. ;;
다음 포스팅에 JSON에 대해서, 알아보도록 하겠습니다.

2011년 3월 24일 목요일

Android : AsyncTask

출처 : http://blog.naver.com/schweine7/40112690238

AsyncTask

  : 백그라운드 작업을 하는데 만드는 쓰레드, 핸들러 등을 대신 만들어주는 도우미 클래스


Params : 실행시에 전달할 인수 타입.
Progress : 매 작업 단계마다 진행 상태를 표기하기 위한 타입
Result : 작업 결과로 리턴될 타입


void onPreExecute ()
  -> 작업 시작되기 전 호출. UI 스레드에서 실행. 보통 초기화작업

Result doInBackground (Params ... params)
  -> 배경 작업을 수행. 분리된 스레드에서 실행.
       execute 메서드로 전달한 작업거리가 params 인수로 전달됨. (배열 타입으로)
       하나의 인수만 필요하면 params[0]만 사용
       작업 중에 publishProgress 메서드를 호출하여 작업 경과를 UI 스레드로 보고 가능

void onProgressUpdate (Progress ...values)
  -> doInBackground에서 publicProgress 메서드를 호출할 때 작업 경과 표시를 위해
     호출되며 UI 스레드에서 실행. 프로그래스 바에 진행 상태를 표시하는 역할

void onPostExecute (Result result)
  -> 백그라운드 작업이 끝난 후 UI 스레드에서 실행. 인수로 작업 결과 전달.
      취소되거나 예외 발생시 null 전달

void onCancelled ()
  -> cancel 메서드로 작업 취소했을 때 호출되며 UI 스레드에서 실행



작업 시작할 때는 AsyncTask 객체를 UI 스레드에서 생성한 후 다음 메서드 호출
!! 반드시 UI 스레드에서 호출 !!

AsyncTask <Params, Progress, Result> execute (Params... params)


boolean cancel (boolean mayInterruptIfRunning)
boolean isCancelled()
   -> 작업을 취소하라고 지시.
       작업 시작 전에는 취소 성공한 것으로 return 됨.

Result get([long timeout, TimeUnit unit])
  -> 작업 완료되기까지 대기하며 작업 결과를 돌려 받는다. 타임아웃값 지정 가능

AsyncTask.Status getStatus()
  -> 작업의 현재 상태 조사. 시작되지 않은 상태면 PENDING 리턴. 이미 실행중이면 RUNNING,
      완료되었다면 FINISHED가 리턴




 메인 스레드
작업 스레드 
 execute

onPrepareExecute()
 // 작업 스레드 작동



onProgressUpdate()
// 메인에서 한번 작동

onPostExecute()
// 메인에서 한번 작동

작업 완료

doInBackground(){
   while(){
     //To do
     publishProgress()

   }
   return result;



==================================  ex  ============================================
ProgressDialog mProgress;
new AccumulateTask().execute(100);

class AccumulateTask extends AsyncTask<Integer, Integer, Integer> {
   protected void onPreExecute(){
      mValue = 0;
      mProgress = new ProgressDialog(.this);
      mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
      mProgress.setTitle("updating");
      mProgress.setMessage("Wait...");
      mProgress.setCancelable(false);
      mProgress.setProgress(0);
      mProgress.setButton("Cancel", new DialogInterface.OnClickListener(){
         public void onClick(DialogInterface dialog, int whichButton){
            cancel(true);
         }
      });
      mProgress.show();
   }

   protected Integer doInBackground(Integer... arg0){
      while (isCancelled() == false){
         mValue++;
         if (mValue <= 100){
            publishProgress(mValue);
         }
         else{
            break;
         }
         try { Thread.sleep(50); } catch (InterruptedException e) { ; }
      }
      return mValue;
   }

   protected void onProgressUpdate(Integer... progress){
      mProgress.setProgress(progress[0]);
      mText.setText(Integer.toString(progress[0]));
   }
  
   protected void onPostExecute(Integer result){
      mProgress.dismiss();
   }

   protected void onCancelled(){
      mProgress.dismiss();
   }
}
=====================================================================================

2011년 3월 17일 목요일

Android : Source 상에서 Margin 값 적용하기

private MarginLayoutParams margin;
margin = new ViewGroup.MarginLayoutParams(/*this.getLayoutParams()*/new LinearLayout.LayoutParams(140, 50));
//setMargins(int left, int top, int right, int bottom)
margin.setMargins( 10, 10, 10,10 );
super.addView(view , new LinearLayout.LayoutParams(margin));

출처 : http://blog.naver.com/lowmans/100123263572

Android : Android pixcel to dpi

final float scale = getContext().getResources().getDisplayMetrics().density;

final float densityDpi = getContext().getResources().getDisplayMetrics().densityDpi;

float pxPerInch = 340; // default value - note it's a new density in API version 9.
switch(densityDpi){
     case DisplayMetrics.DENSITY_LOW:
                 pxPerInch = 120 * scale;
                 break;
     case DisplayMetrics.DENSITY_MEDIUM:
                 pxPerInch = 160 * scale;
                 break;
     case DisplayMetrics.DENSITY_HIGH:
                 pxPerInch = 240 * scale;
                 break;
}

출처 : http://blog.naver.com/lowmans/100123712145

Android : 단말기 정보 확인

TelephonyManager tpMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String alphName = tpMgr.getNetworkOperatorName();

Log.d("Telephony", "alphName:\t" + alphName); // 통신사
Log.d("", "SDK:" + android.os.Build.VERSION.RELEASE); // 버젼 sdk:2.1-update1
Log.d("", "MODEL:" + android.os.Build.MODEL); // Device Model

출처 : http://blog.naver.com/lowmans/100123923127

Android : 어플실행시키기(Package name으로 액티비티 실행)

Package name으로 액티비티 실행하는 로직.

Intent intent = this.getPackageManager().getLaunchIntentForPackage(packageName);
startActivity(intent);
 

Android : 안드로이드 마켓 License Validation Library 사용하기

[권한]
<uses-permission android:name="com.android.vending.CHECK_LICENSE />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />


[import]
import android.telephony.TelephonyManager;
import com.android.vending.licensing.AESObfuscator;
import com.android.vending.licensing.LicenseChecker;
import com.android.vending.licensing.LicenseCheckerCallback;
import com.android.vending.licensing.ServerManagedPolicy;


[class]
 private class MyLicenseCheckerCallback implements LicenseCheckerCallback { 
    @Override
    public void allow() { 
        if (isFinishing()) { 
            return; 
        } 
        // 라이선스 인증에 성공했을때 수행할 일을 여기에 추가 
    } 
    @Override
    public void applicationError(ApplicationErrorCode errorCode) { 
        // 에러 메시지 출력 등의 루틴 추가 
    } 
    @Override
    public void dontAllow() { 
        if (isFinishing()) { 
            return; 
        } 
        // 라이선스 인증에 실패했을 때 수행할 일을 여기에 추가 
    } 
}

[onCreate]
 public class MainActivity extends Activity { 
     // 2에서 확인한 public key 
     private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... ";  
     // 20개의 랜덤한 byte 
     private static final byte[] SALT = {-46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95,  
                          -45, 77, -117, -36, -113, -11, 32, -64, 89};  
   
     private LicenseCheckerCallback mLicenseCheckerCallback; 
     private LicenseChecker mChecker; 
     @Override
     public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
   
         // LicenseCheckerCallback 초기화 
         mLicenseCheckerCallback = new MyLicenseCheckerCallback(); 
   
         // 디바이스 아이디를 얻기 위한 루틴 
         TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
         String deviceId = tm.getDeviceId(); 
   
         // LicenseChecker 초기화 
         mChecker = new LicenseChecker(  
                 this,  
                 new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), 
                 BASE64_PUBLIC_KEY); 
   
         // License Validation 실행 
         mChecker.checkAccess(mLicenseCheckerCallback); 
     } 
   
     @Override
     protected void onDestroy() { 
         super.onDestroy(); 
         mChecker.onDestroy(); // 어플리케이션 종료시 메모리 반환 
     } 
}

출처 :  http://techdic.tistory.com/48

Android : 디바이스에 설치된 어플리케이션(액티비티) 목록 얻기

멋진 소스

PackageManager manager = getPackageManager();
List<PackageInfo> appInfoList = manager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
for (int j = 0, jend = appInfoList.size(); j < jend ; j++) {
   PackageInfo pi = appInfoList.get(j);
}

출처 : http://blog.naver.com/PostView.nhn?blogId=dong277&logNo=130104023606&beginTime=0&jumpingVid=&from=search&redirect=Log&widgetTypeCall=true&topReferer=http%3A%2F%2Fsearch.naver.com%2Fsearch.naver%3Fwhere%3Dnexearch%26sm%3Dies_hty%26ie%3Dutf8%26query%3DgetPackageManager%28%29

Android : 현재 실행 가능한 어플리케이션(액티비티) 목록 얻기

멋진 소스 발견.

PackageManager manager = getPackageManager();


final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = manag.queryIntentActivities(mainIntent, 0);
for (int i = 0, iend = resolveInfos.size(); i < iend; i++) {
   ResolveInfo ri = resolveInfos.get(i);
   String pkgName = ri.activityInfo.applicationInfo.packageName; //패키지 이름
   String className = ri.activityInfo.name; //클래스 이름(실행되는 액티비티 이름)
   ComponentName componentName = new ComponentName(pkgName, className); //컴포넌트 생성 코드
   CharSequence title = ri.loadLabel(manager); //어플리케이션 이름
   Drawable icon = ri.activityInfo.loadIcon(manager); //어플리케이션 아이콘 Drawable
   boolean thirdPartyFlag = false;
   if ((ri.activityInfo.applicationInfo.flags
          & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0 ) {
      // 다운로드 받은 어플리케이션
      thirdPartyFlag = true;
   } else {
      // 프리로드된 어플리케이션
   }
   boolean isExternalApp = false;
   if ((info.activityInfo.applicationInfo.flags & android.content.pm.ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
      // 외장메모리에 설치되는 어플리케이션
      isExternalApp = true;
   } else {
      // 내장메모리에 설치되는 어플리케이션
      isExternalApp = false;
   }
}

출처 : http://blog.naver.com/PostView.nhn?blogId=dong277&logNo=130104023606&beginTime=0&jumpingVid=&from=search&redirect=Log&widgetTypeCall=true&topReferer=http%3A%2F%2Fsearch.naver.com%2Fsearch.naver%3Fwhere%3Dnexearch%26sm%3Dies_hty%26ie%3Dutf8%26query%3DgetPackageManager%28%29

Android : 어플리케이션 버전 정보 얻기

어플 배포시 마다 도움말/이번 버전의 갱신 내용등을 보여 줄때 일일이 버전 정보를 수정하였었는데. 아래의 로직으로 쉽게 처리할 수 있을 거 같네요.

AdroindManifest.xml 파일에서 버전 정보를 읽는 로직.

PackageManager pm = getPackageManager();
pm.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).versionName;

출처 : http://techdic.tistory.com/49

2011년 3월 16일 수요일

Android : 네트워크 접속 전에 3G 및 Wife 접속 가능 체크하기.

아래의 로직으로 체크 가능합니다. 이때 AndoridManifest.xml에 권한을 설정하셔야 합니다.

[로직]
ConnectivityManager connec = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

   if (connec.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED
     && connec.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED) {
     //원하는 로직 추가.

    return;
   }


[권한]
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Android : Title Bar / Notification Bar 없애기

1. 테마로 Title Bar 없애기.
    AndroidManfest.xml안에 Title Bar를 없애기를 원하는 Activity를 아래와 같이 변경합니다.

   <activity android:name="ShowActivity"   android:theme="@android:style/Theme.NoTitleBar">

2. 테마로 Notification Bar 없애기.
    AndroidManfest.xml안에 Title Bar를 없애기를 원하는 Activity를 아래와 같이 변경합니다.

   <activity android:name="ShowActivity"   android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

3. 로직으로 Title Bar를 없애기.
    아래의 로직을 Activity의 onCreate 메소드 안에서 setContentView를 호출하기 전에 넣으면 됩니다.

    requestWindowFeature(Window.FEATURE_NO_TITLE);

4. 로직으로 Notification Bar를 없애기.
    아래의 로직을 Activity 의 onCreate 메소드 안에 넣는다.

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

도움말 - Wordroid2[유료]으로 데이타 옮기는 방법

1. Wordroid2 어플을 실행합니다.
2. 단어장 목록 화면에서 메뉴 > 데이타관리를 선택합니다.
3. 중간의 Wordroid 복원을 선택합니다.

일본 원전에 결사대 50명이 남았다.

어제 뉴스에서
일본 원전를  지키기 위해서 800명의 직원 중 베테랑 급 50명이 남아서 순직을 각오하고 혈투를 벌이고 있다고 들었다.
조금 더 내용을 찾아 보니 그 중 몇몇은 자발적으로 남았다고 한다. 그 기사를 읽는 순간 가슴이 먹먹해지고 온몸에 소름이 돋았다. 우리가 살고 있는 이 시대에도 자신을 기꺼이 버리고 남을 위해서 살아 가는 사람들이 있었다.
그 분들의 희생이 헛되지 않게 일본 원전 사건이 잘 마무리 되었으면 좋겠다.

도움말 -Wordroid2 Google Docs SpreadSheet로 단어장 만들기

1. 단어장 목록에서 "메뉴 > 외부 단어장 추가 > 구글 SpreadSheet"를 선택합니다.
2. 구글 로그인 창에 구글 계정 정보를 입력하고 로그인 합니다.


 3. 로그인 후 첫번째 화면은 스프레트쉬트 목록입니다.





4. SpreadSheet목록을 선택하면 두번째 화면인 Sheet 목록으로 이동합니다.
 




5. Sheet 목록을 선택하면 서번째 화면인 Data 화면으로 이동합니다.





6. Sheet의 입력 방식은 아래 그림과 같습니다. 쉬트의 첫번째 열에 제목을 입력하고 두번째 열부터 데이타를 입력하세요.

7. Sheet 목록에서 단어장으로 만들 쉬트 옆의 "가져오기"를 선택하세요. Sheet의 명이 단어장 이름으로 됩니다.

도움말 - Wordroid 단어 학습 하기

** 단어 학습 기능 **
  - '플래시 카드' 단어 학습.
  - '자동 플랫 카드' 단어 학습.

  - '단어 암기' 단어 학습.
  - '단어 테스트' 단어 학습.

  - '단어 짝 맞추기' 단어 학습.


[플래시 카드]
플래시 카드로 단어를 학습 할 수 있습니다.
1. 단어장 목록에서 각 단어장 마다 있는 "카드" 레이블을 선택하거나.
    단어 목록의 메뉴에서 "플래시 카드"를 선택한다.
2. 플래시 카드 화면 설명.
2.1 단어섞기
     단어 학습 중 단어를 섞을 싶을 경우 이 레이블을 선택한다.
     단어를 다시 섞은 후 학습을 처음부터 시작할 수 있다.
2.2 모든단어/중요단어
     단어 중 별 표시가 된 단어만 학습을 원하는 경우 "모든단어" 레이블을 선택한다.
     레이블이 "중요단어"로 변경되고 별 표시된 단어만 학습할 수 있다.
     다시 모든 단어를 원한 경우 "중요단어"레이블을 선택한다.
2.3 단어먼저 / 뜻먼저
     단어 먼저 - 단어와 뜻을 각각 보는 모드에서 단어를 먼저 보여주고 후에 뜻을 보여준다.
     뜻 먼저 - 뜻을 먼저 보여주고 단어를 보여준다.
2.4 단어/뜻
    단어 와 뜻을 한번에 보여줄지 각각 보여줄지를 선택할 수 있다.
2.5 자동학습
    단어 학습 도중 "자동 플래시 카드"로 이동할 수 있다.
2.6 단어수정
    단어 학습 도중 단어으 내용을 수정하고 싶은 경우 이 레이블을 선택한다.
    단어 수정 화면으로 이동한다.
2.7 별
    중요 단어를 표시한다. 선택하는 경우 빨간색으로 변한다.
2.8 이전단어
    이전 단어로 이동할 수 있다.
2.9 다음단어
    다음 단어로 이동할 수 있다.

[자동 플래시 카드]
1. 플래시 카드 학습 도중 화면 하단의 "자동학습" 레이블을 선택하거나
    단어 목록의 메뉴에서 "자동 플래시 카드"를 선택한다.
2. 설정하기에 따라 단어와 뜻을 주기적으로 보여준다.
3. 화면의 아래의 진행바를 통해서 학습 현재 위치를 알 수 있다.
** 자동 플래시 카드 설정
1. 단어장 목록에서 메뉴 버튼를 선택한다.
2. 메뉴 중 "환경설정"를 선택한다.
3. 설정 목록 중 "자동 플래시 카드"를 선택한다.
4. 설정 할 수 있는 내용.
4.1 단어 노출 교대
4.2 단어 노출 시간
4.3 뜻 노출 시간
4.4 모든 단어 반복 회수
4.5 중요 단어 반복 회수

[단어 암기]
1. 단어장 목록에서 각 단어장 마다 있는 "암기" 레이블을 선택하거나.
    단어 목록의 메뉴에서 "단어 암기"를 선택한다.
2. 뜻이 보여지고 단어를 입력하고 "응답" 버튼을 선택한다.
3. 응답이 맞은 경우에는 "CORRECT" , 틀린 경우에는 "INCORRECT"가 볼 수 있다.
4. 답이 전혀 생각이 나지 않는 경우 "응답포기"를 선택할 수 있고
    응답 포기 화면에서 단어를 한번 입력해 볼 수 있다.
5. 모든 단어를 맞출때까지 2~4과정이 반복된다.
6. 모든 단어를 맞추면 결과 페이지로 이동한다.
7. 각 응답 라운드마다의 사용자 응답을 볼 수 있다.

[단어 테스트]
1. 단어장 목록에서 각 단어장 마다 있는 "테스트" 레이블을 선택하거나.
    단어 목록의 메뉴에서 "단어 테스트"를 선택한다.
2. 3가지 형식으로 문제가 출제되고 응답할 수 있다.
2.1 단어 입력.
2.2 단어 4지 선택.
2.3 참/거짓 선택.
3. 응답이 모든 끝난 경우 응답 결과를 볼 수 있다.

[단어 짝 맞추기]
1. 단어 목록의 메뉴에서 "단어 짝 맞추기"를 선택한다.
2. 단어와 뜻을 올바르게 선택하면 화면에서 사라진다.
3. 모두 맞추는 경우 다음 단어들이 나타난다.
4. 화면 아래의 진행바를 통해 현재의 위치를 알 수 있다.