과목명 : 모바일 프로그래밍(Mobile programming with Android Studio)
수업일자 : 2023년 04월 21일 (금)
1. 내장 메모리 파일 처리
1-1. 내장 메모리 파일 처리
(1) 애플리케이션을 종료하고 다시 실행할 때, 사용한 곳에 이어서 작업하고 싶은 경우 내장 메모리 파일 처리를 이용합니다.
(2) 내장 메모리의 저장 위치 : / data / data / 패키지명 / files 디렉토리
1-2. 내장 메모리에서의 파일 처리 과정
- (1) → (2) → (3) 순서대로 진행
(1) openFileOutput() / openFileInput() 메소드로 파일 열기
- FileOutputStream / FileInputStream 반환
(2) read() / write() 메소드로 파일 읽기, 쓰기
(3) close() 메소드로 파일 닫기
1-3. 파일 처리 기본 Code
(1) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnWrite"
android:text="내장 메모리에서 파일 쓰기"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnRead"
android:text="내장 메모리에서 파일 읽기"/>
</LinearLayout>
(2) MainActivity.java
package com.example.fileprocessing;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnRead, btnWrite;
btnRead = (Button) findViewById(R.id.btnRead);
btnWrite = (Button) findViewById(R.id.btnWrite);
btnWrite.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
FileOutputStream outFs = openFileOutput("file.txt", Context.MODE_PRIVATE);
String str = "파일 처리 테스트";
outFs.write(str.getBytes());
outFs.close();
} catch (IOException e) { }
}
});
btnRead.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
FileInputStream inFs = openFileInput("file.txt");
byte[] txt = new byte[30];
inFs.read(txt);
String str = new String(txt);
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
inFs.close();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "파일 없음", Toast.LENGTH_SHORT).show();
}
}
});
}
}
<실행 결과>
- 애플리케이션 초기 구동 화면입니다.
- 버튼 클릭 시 파일 읽어오기가 가능합니다.
2. 파일 처리 테스트 : 일기장 예제 Application Code
2-1. activity_main.xml
(1) 화면 디자인 및 편집하기
- DatePicker, EditText, Button 위젯을 각 1개씩 생성합니다.
- 각 위젯의 아이디 속성은 datePicker1, edtDiary, btnWrite으로 부여합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<DatePicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:datePickerMode="spinner"
android:id="@+id/datePicker1"
android:calendarViewShown="false" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/edtDiary"
android:background="#0000ff"
android:lines="8"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/btnWrite"
android:text="Button"/>
</LinearLayout>
<위젯 배치 결과>
2-2. MainActivity.java
(1) activity_main.xml 파일에 존재하는 3개 위젯에 대응하는 위젯 변수 3개를 선언합니다.
(2) 파일 이름을 지정할 문자열 변수를 선언합니다.
- 파일 이름은 "연_월_일.txt" 형식으로 지정
(3) 위젯 변수에 activity_main.xml의 위젯을 대입합니다.
(4) Calendar 클래스를 사용해 현재 날짜의 연/월/일을 구한 후 DatePicker를 초기화합니다.
(5) DatePicker의 날짜가 변경되면 변경된 날짜에 해당하는 일기 파일(연_월_일.txt) 내용을 EditText 부분에 출력합니다.
(6) 현재 날짜 파일(연_월_일.txt)을 읽어들여 일기 내용을 반환하는 readDiary() 메소드를 구현합니다.
(7) 맨 아래 버튼을 클릭했을 때, 동작하는 내용을 onCreate() 메인 메소드 내부에 구현합니다.
package com.example.a8weekssimplediary2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
DatePicker dp;
EditText edtDiary;
Button btnWrite;
String fileName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Simple Diary");
dp = (DatePicker) findViewById(R.id.datePicker1);
edtDiary = (EditText) findViewById(R.id.edtDiary);
btnWrite = (Button) findViewById(R.id.btnWrite);
Calendar cal = Calendar.getInstance();
int cYear = cal.get(Calendar.YEAR);
int cMonth = cal.get(Calendar.MONTH);
int cDay = cal.get(Calendar.DAY_OF_MONTH);
dp.init(cYear, cMonth, cDay, new DatePicker.OnDateChangedListener() {
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
fileName = Integer.toString(year) + "_"
+ Integer.toString(monthOfYear + 1) + "_"
+ Integer.toString(dayOfMonth + 1) + ".txt";
String str = readDiary(fileName);
edtDiary.setText(str);
btnWrite.setEnabled(true);
}
String readDiary(String fName) {
String diaryStr = null;
FileInputStream inFs;
try {
inFs = openFileInput(fName);
byte[] txt = new byte[500];
inFs.read(txt);
inFs.close();
diaryStr = (new String(txt)).trim();
btnWrite.setText("수정하기");
} catch (IOException e) {
edtDiary.setHint("일기 없음");
btnWrite.setText("새로 저장");
}
return diaryStr;
}
});
btnWrite.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
FileOutputStream outFs = openFileOutput(fileName, Context.MODE_PRIVATE);
String str = edtDiary.getText().toString();
outFs.write(str.getBytes());
outFs.close();;
Toast.makeText(getApplicationContext(), fileName +" 이 저장됨", Toast.LENGTH_SHORT).show();
} catch (IOException e) {}
}
});
}
}
<실행 결과>
- 애플리케이션 초기 실행 화면입니다
- 애플리케이션 실행 시점 2023년 4월 22일을 기준으로 작성된 내용이 없으므로 EditText 영역이 공백입니다.
- 2023년 4월 21일에 내용을 작성했기 때문에 날짜를 바꿔보면 EditText 영역에 읽어들여진 텍스트가 출력됩니다.
- 해당 일자의 일기가 존재하기 때문에 맨 하단 버튼이 "수정하기"로 변경되었습니다.
- 선택한 날짜에 일기가 없다면 EditText 영역에 "일기 없음" 문구가 노출되고 맨 하단의 버튼이 "새로 저장"으로 변경됩니다.
- 현재 금일 기준으로 일기가 없으므로 새로운 내용을 쓰고 내용을 저장할 수 있습니다.
3. 파일 처리 기본 : 내장 메모리 파일 처리
3-1. 일기장 Application에 대한 저장된 텍스트 파일 확인해 보기
(1) Android Studio 최상단 메뉴 View → Tool Windows → Device File Explorer 메뉴를 클릭합니다.
(2) Android Studio에서 제공하는 DDMS Tool을 사용하여 쓰여진 텍스트 파일을 확인합니다.
- 확인 경로 : / data / data / 프로젝트의 패키지명 / files
(3) 파일들을 Local 환경으로 가져올 수 있으며 마우스 오른쪽 버튼을 클릭해 "Save As..." 메뉴를 통해 저장할 로컬 디렉토리를 설정할 수 있습니다.
4. raw 디렉토리 파일 처리
4-1. raw 디렉토리 파일 처리
(1) 프로젝트의 / res / raw 디렉토리에 필요한 파일을 저장해서 사용합니다.
(2) openRawResource() 메소드를 사용해서 접근(InputStream 클래스 사용)합니다.
(3) / res / raw 디렉토리는 프로젝트에 포함된 디렉토리이므로 읽기 전용만 사용 가능합니다.
4-2. raw 디렉토리 파일 읽기 예제 Code
(1) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnRead"
android:text="/res/raw에서 파일 읽기"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edtRaw"
android:lines="10"/>
</LinearLayout>
<위젯 배치 결과>
(2) raw 디렉토리 생성
- 프로젝트 디렉토리 경로에서 res 디렉토리 기준 마우스 우측 클릭
- New → Android Resource Directory → Resource type은 raw, Directory name까지 raw로 설정합니다.
(3) 생성된 raw 디렉토리에 raw_test.txt 파일을 생성하고 읽어들일 텍스트를 별도로 입력합니다.
(4) MainActivity.java
package com.example.a8weekssimplediary;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnRead;
final EditText edtRaw;
btnRead = (Button) findViewById(R.id.btnRead);
edtRaw = (EditText) findViewById(R.id.edtRaw);
btnRead.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
InputStream inputS = getResources().openRawResource(R.raw.raw_test);
byte[] txt = new byte[inputS.available()];
inputS.read(txt);
edtRaw.setText(new String(txt));
inputS.close();
} catch (IOException e) {}
}
});
}
}
<실행 결과>
- 애플리케이션 초기 구동 화면입니다.
- 파일 읽기 버튼을 통해 저장된 파일을 아래와 같이 불러올 수 있게 됩니다.
5. Etc
5-1. 안드로이드 파일 처리 (1)
(1) 내장 메모리의 파일 저장 위치는 / data / data / 패키지명 / files이다.
(2) 읽기 전용 파일의 경우 프로젝트의 / res / raw 디렉토리를 사용할 수 있다.
(3) 외장 메모리 카드(SD카드)에 저장하는 외부 저장소 이름은 sdcard이다.
5-2. 안드로이드의 대화 상자(Dialog)
(1) 안드로이드에서 대화 상자(Dialog)에서 <OK> 버튼은 setPositiveButton, <Cancel> 버튼은 setNegativeButton, 라디오 버튼(RadioButton) 목록 출력은 setSingleChoiceItems, 체크박스(CheckBox) 목록 출력은 setMultiChoiceItems를 사용합니다.
5-3. 안드로이드 파일 처리 (2)
(1) 내장 메모리에서 파일을 읽거나 쓰는 일반적인 절차는 다음과 같습니다.
- 파일을 읽기 위해 openFileInput() 메소드를 사용하는데 이 메소드는 FileInputStream을 반환합니다.
- 파일을 쓰기 위해 openFileOutput() 메소드를 사용하면 FileOutputStream을 반환합니다.
- Java에서 제공하는 파일을 읽거나 쓰는 java.io.FileInputStream 클래스와 java.io.FileOutputStream의 read(), write() 메소드를 사용하여 파일을 처리합니다.
5-4. raw 디렉토리 처리
(1) 다음은 / res / raw 디렉토리의 mytext.txt를 읽는 Java 코드입니다.
InputStream inputS = getResources().openRawResource.(R.raw.mytext);
byte[] txt = new byte[inputS.available()];
inputS.read(txt);
InputStream inputS = getResources().openRawResource(R.raw.mytext);
byte[] txt = new byte[inputS.available()];
inputS.read(txt);
6. Reference
(1) Reference
- Android Studio를 활용한 안드로이드 프로그래밍 / 한빛아카데미(Hanbit Academy, Inc.)
(2) URL
https://www.hanbit.co.kr/store/books/look.php?p_code=B1212492850
- 학부에서 수강했던 전공 수업 내용을 정리하는 포스팅입니다.
- 내용 중에서 오타 또는 잘못된 내용이 있을 시 지적해 주시기 바랍니다.
댓글