안드로이드 앱 개발(한자교육)
- 참조 파일들
- File – New – New Project 메뉴 순으로 클릭한다.
- … 나오는 대화상자에 맞춰 내용을 작성한다.
- 프로젝트가 생성되면 다음 4개의 파일을 순서대로 열어 놓는다.
- app/manifests/AndroidManifest.xml
- app/res/values/strings.xml
- app/res/layout/activity_main.xml
- app/java/kr.ac.jj.hanjaapp/MainActivity
- app/res/values/strings.xml 파일을 다음과 같이 작성한다.
- 문자열 1개 추가 예 : <string name=”영어이름“>문자열</string>
- strings.xml 전체 소스 코드
12345678910111213141516171819<resources><string name="app_name">한자학습</string><string name="hello_world">Hello world!</string><string name="action_settings">Settings</string><string name="btn01">한자학습</string><string name="btn02">문제풀기</string><string name="grade_prompt">해당 급수를 선택하세요</string><string-array name="grades_array"><item>교육8급(50자)</item><item>교육7급(100자)</item></string-array><string name="type_prompt">학습형태를 선택하세요</string><string-array name="types_array"><item>漢字글자읽기</item><item>漢字단어읽기</item></string-array></resources>
- app/res/layout/activity_main.xml 파일에 다음과 같은 내용을 추가한다.
- Button 2개를 추가한 후 activity_main.xml 전체 소스 코드
123456789101112131415161718192021222324252627<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="kr.co.moak.hanjaedu2016.MainActivity"><Buttonandroid:text="@string/btn01"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_alignParentStart="true"android:id="@+id/btn01" /><Buttonandroid:text="@string/btn02"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/btn01"android:layout_alignParentEnd="true"android:id="@+id/btn02" /></RelativeLayout>
- Button 2개를 추가한 후 activity_main.xml 전체 소스 코드
- app/java/패키지이름/MainActivity.java 파일의 onCreate() 함수에 다음 내용을 추가한다.
- MainActivity.java 파일의 onCreate()함수에 btn01버튼이 눌렸을 경우 처리할 소스 코드
12345678910111213141516171819202122protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn01 = (Button)this.findViewById(R.id.btn01);btn01.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, EduActivity.class);startActivity(intent);}});Button btn02 = (Button)this.findViewById(R.id.btn02);btn02.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, ExamActivity.class);startActivity(intent);}});}
- MainActivity.java 파일의 onCreate()함수에 btn01버튼이 눌렸을 경우 처리할 소스 코드
- app/res/layout/activity_edu.xml 파일 추가
12345678910111213141516171819<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:text="TextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/txt01"android:textAppearance="@style/TextAppearance.AppCompat.Large" /><TextViewandroid:text="TextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/txt02"android:textAppearance="@style/TextAppearance.AppCompat.Medium" /></LinearLayout>
- app/java/패키지이름/EduActivity.java 파일 추가
1234567public class EduActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_edu);}}
- app/res/layout/activity_exml.xml 파일 추가
- app/java/패키지이름/ExamActivity.java 파일 추가
1public class MainActivity extends Activity{
- 프로젝트 탐색기를 Project Files 형태로 변경한 뒤 app/app/src/main/ 폴더에 assets폴더를 추가한다.
- hanja.db 파일을 다운로드 받아 복사한 뒤 asstes폴더에 붙여넣기 한다.
- app/java/패키지이름/MainActivity.java 파일에 다음 setDB() 함수를 추가한다.
12345678910111213141516171819202122232425262728293031private void setDB() { //Asset 내의 DB용량이 1MB가 넘으면 복사 안됨 //확장자를 mp3로 만들어 저장한 후 복사하면서 파일명을 바꾸면 해결 가능String pkgName = "kr.co.moak.hanjaedu2016";File dir = new File("/data/data/" + pkgName + "/databases/");File outfile = new File("/data/data/" + pkgName + "/databases/hanja.db");AssetManager assetManager = getResources().getAssets();InputStream is = null;FileOutputStream fo = null;long filesize = 0;try {is = assetManager.open("hanja.db", AssetManager.ACCESS_BUFFER);filesize = is.available();Log.v("MY_TAG", "size : " + filesize + ", outfile : " + outfile.length() + ", " + outfile.lastModified());// 패키지 폴더에 설치된 DB파일이 포함된 DB파일 보다 크기가 같지않을 경우 DB파일을 덮어 쓴다.if(outfile.length() != filesize){byte[] tempdata = new byte[(int) filesize];is.read(tempdata);is.close();if(!dir.exists()) dir.mkdir(); //폴더가 없이 파일을 생성하면 오류 발생하므로 폴더를 꼭 먼저 만들어야 함outfile.createNewFile();fo = new FileOutputStream(outfile);fo.write(tempdata);fo.close();}} catch (IOException e) {e.printStackTrace();}}
- onCreate() 함수의 끝부분에서 setDB()함수를 호출한다.
- Tools – Android – Android Device Monitor 메뉴를 선택하여 Android Device Monitor를 띄운다.
- app/java/패키지이름/DBHelper.java 파일 추가
123456789101112131415161718192021package kr.co.moak.hanjaedu2016;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper {public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
- app/java/패키지이름/EduActivity.java 파일 수정
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566public class EduActivity extends AppCompatActivity {private DBHelper mHelper;private SQLiteDatabase db;private ArrayList<String> ar_chinese;private ArrayList<String> ar_meaning;private int pos = 0;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_edu);ar_chinese = new ArrayList<String>();ar_meaning = new ArrayList<String>();mHelper = new DBHelper(this, "hanja.db", null, 2);db = mHelper.getReadableDatabase();//.getWritableDatabase();String sql = "SELECT * FROM whanchar WHERE grade = 80 ORDER BY random() LIMIT 20";Cursor cursor = db.rawQuery(sql, null);cursor.moveToFirst();for(int i=0; i<cursor.getCount(); i++){ar_chinese.add(cursor.getString(cursor.getColumnIndexOrThrow("chinese")));ar_meaning.add(cursor.getString(cursor.getColumnIndexOrThrow("meaning")));cursor.moveToNext();}cursor.close();drawHanja();}private float x1=0;private float x2=0;@Overridepublic boolean onTouchEvent(MotionEvent event) {if(event.getAction() == MotionEvent.ACTION_DOWN){x1 = event.getX();}else if(event.getAction() == MotionEvent.ACTION_UP){x2 = event.getX();if(x1 > x2 && x1 - x2 > 30){drawHanja();}}//return true;return super.onTouchEvent(event);}private void drawHanja(){if(pos < ar_chinese.size()){TextView txt1 = (TextView)this.findViewById(R.id.txt01);TextView txt2 = (TextView)this.findViewById(R.id.txt02);txt1.setText(ar_chinese.get(pos));txt2.setText(ar_meaning.get(pos));pos++;}else{Toast.makeText(this, "수고하셨습니다.", Toast.LENGTH_LONG).show();setResult(RESULT_OK);finish();}}} - activity_exam.xml 파일 추가
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:id="@+id/txt01"android:layout_width="fill_parent"android:layout_height="150dip"android:layout_alignParentTop="true"android:textSize="34dip"android:text="문제"android:gravity="center"/><TextView android:id="@+id/txt02"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@id/txt01"android:textSize="24dip"android:gravity="center_horizontal"android:text=""/><RadioGroup android:id="@+id/radiogroup01"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"><RadioButton android:id="@+id/radio01"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="24dip"android:text="뜻/의미"android:tag="1"/><RadioButton android:id="@+id/radio02"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="24dip"android:text="뜻/의미"android:tag="2"/><RadioButton android:id="@+id/radio03"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="24dip"android:text="뜻/의미"android:tag="3"/><RadioButton android:id="@+id/radio04"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="24dip"android:text="뜻/의미"android:tag="4"/><RadioButton android:id="@+id/radio05"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="24dip"android:text="뜻/의미"android:tag="5"/></RadioGroup></RelativeLayout>
- ExamActivity 클래스 수정
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126package kr.co.moak.hanjaedu2016;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.os.PersistableBundle;import android.support.v7.app.AppCompatActivity;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.Collections;import java.util.Random;/*** Created by happy on 2016-10-19.*/public class ExamActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener{private DBHelper mHelper;private SQLiteDatabase db;private TextView txt01;private TextView txt02;private RadioGroup radiogroup;private RadioButton[] radio;private ArrayList<String[]> arMun;private int pos=-1;private int ok_cnt=0;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_exam);//DB 설정mHelper = new DBHelper(this, "hanja.db", null, 2);db = mHelper.getReadableDatabase();//.getWritableDatabase();//DB 설정txt01 = (TextView)this.findViewById(R.id.txt01);txt02 = (TextView)this.findViewById(R.id.txt02);radiogroup = (RadioGroup)this.findViewById(R.id.radiogroup01);radiogroup.setOnCheckedChangeListener(this);radio = new RadioButton[5];radio[0] = (RadioButton)this.findViewById(R.id.radio01);radio[1] = (RadioButton)this.findViewById(R.id.radio02);radio[2] = (RadioButton)this.findViewById(R.id.radio03);radio[3] = (RadioButton)this.findViewById(R.id.radio04);radio[4] = (RadioButton)this.findViewById(R.id.radio05);String sql = "SELECT * FROM whanchar WHERE grade = 80 ORDER BY _id LIMIT 20";Cursor cursor = db.rawQuery(sql, null);cursor.moveToFirst();Random random = new Random();arMun = new ArrayList<String[]>();for(int i=0; i<cursor.getCount(); i++){String[] m = new String[]{"","","", "","","","",""};m[0] = cursor.getString(cursor.getColumnIndexOrThrow("chinese")).trim();m[1] = cursor.getString(cursor.getColumnIndexOrThrow("meaning")).trim();m[2] = cursor.getString(cursor.getColumnIndexOrThrow("korean")).trim();int n = random.nextInt(5);m[n+3] = m[1]; //정답을 5지선다 중 1개에 삽입arMun.add(m);cursor.moveToNext();}cursor.close();Collections.shuffle(arMun);drawHanja();}private void drawHanja(){Cursor cursor = null;pos = (pos + 1) % arMun.size();//mun.length;String sql = "SELECT * FROM whanchar WHERE meaning <> '" + arMun.get(pos)[1]+ "' AND grade=80 ORDER BY random() LIMIT 5";cursor = db.rawQuery(sql, null);cursor.moveToFirst();for(int i=0; i<5; i++){if(arMun.get(pos)[i+3].compareTo("") == 0){arMun.get(pos)[i+3] = cursor.getString(cursor.getColumnIndexOrThrow("meaning"));}cursor.moveToNext();}String mun = (pos+1) + ". " + arMun.get(pos)[0];txt01.setText(mun);txt02.setText("");for(int i=0; i<5; i++){radio[i].setText(arMun.get(pos)[i+3]);radio[i].setChecked(false);}}@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {RadioButton radio = (RadioButton) findViewById(checkedId);if(radio.getText() == arMun.get(pos)[1]){if(txt02.getText() == ""){ok_cnt++;}if(pos < arMun.size()-1){drawHanja();}else{Toast.makeText(this, arMun.size() + " 문제중 " + ok_cnt + "개 맞음",Toast.LENGTH_LONG).show();setResult(RESULT_OK);finish();}}else{txt02.setText(arMun.get(pos)[1]);}}}