본문 바로가기
안드로이드 웹앱 콘테츠 개발자 양성(국비지원)/Data 저장

Android Studio Data 저장 2 (File, Shared Preference, Data base, web서버)

by 차누감 2019. 9. 24.

1) File - 두 가지로 분류 (Internal Storage, External Storage)

2) Shared Preference

3) Data base

4) Web서버

 

1) File - 두 가지로 분류 (External Storage)

화면 구성은 아래와 같이 똑같이 만들고, 어디에 저장하는 지만 다르게 만들것이다.

 

Internal Storage예제랑 다른점

1. 외부 메모리[내부보다 조금더 상위 폴더 예제 핸드폰은 legacy ]에 저장하는 것이다. (Internal Storage는 내부 메모리[android-data]에 저장.)

2. 동적 퍼미션이 필요한 접근 허용을 해서 원하는 폴더 경로에 저장하는 버튼 추가 (ex.카메라 접근을 허용하시겠습니까?)

②Internal Storage

 

activity_main.xml 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">
    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="input data"
        android:inputType="text"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="save"
        android:onClick="clickSave"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="load"
        android:onClick="clickLoad"/>
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="show data"
        android:padding="8dp"/>
 
 
 
</LinearLayout>
 
 

MainActivity.java 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
 
import androidx.annotation.NonNull;
 
import android.Manifest;
 
 
public class MainActivity extends AppCompatActivity {
 
    EditText et;
    TextView tv;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        et=findViewById(R.id.et);
        tv=findViewById(R.id.tv);
    }
 
    public void clickSave(View view) {
 
        //외장메모리(SD card)가 있는지?
        String state=Environment.getExternalStorageState();
        //외장메모리 상태가 연결(mounted) 되어 있는지 확인
        if(!state.equals(Environment.MEDIA_MOUNTED)){
            Toast.makeText(this"SDcard is not mounted", Toast.LENGTH_SHORT).show();
            return;
        }
 
        //여기까지 커서가 오면..
        //외부메모리가 연결되어있다고 볼 수 있음.
        //외부메모리에 데이터 저장 작업 시작
 
        String data= et.getText().toString();
        et.setText("");
 
        File path; //파일저장될 경로정보를 가진 객체 [Data.txt파일이 저장될 경로]
 
        //Matshmallow(api 23버전) 이상에서는
        //SD카드의 아무 위치에 직접 저장하는 것이
        //불가능하도록 보안을 강화함
        //오로지 각 앱에게 할달됭 고유한 영역에만
        //저장이 가능함.
        //고유한 영역의 경로를 얻어오기!
//        File[] dirs= getExternalFilesDirs("MyDir"); //getExternalFilesDirs()안에 매개 변수는 경로를 만드는 것이다. 폴더도 자동 생성 시킴
//        path= dirs[0];
//        tv.setText(path.getpath());
        File[] dirs = getExternalFilesDirs("MyDir"); //sd카드 내부의 Android-data-com.tisotry-files-"Mydir"라는 폴더를 만들겠다
        path = dirs[0];
        tv.setText(path.getPath());
 
        File file= new File(path, "Data.txt");
 
        try {
            FileOutputStream fos= new FileOutputStream(file, true);
            PrintWriter writer= new PrintWriter(fos);
 
            writer.println(data);
            writer.flush();
            writer.close();
 
            Toast.makeText(this,"SAVED",Toast.LENGTH_SHORT).show();
 
 
        } catch (FileNotFoundException e) { e.printStackTrace();}
 
    }
 
    public void clickLoad(View view) {
 
        //외부메모리가 존재하는지 확인
        String state= Environment.getExternalStorageState();
        if(state.equals(Environment.MEDIA_MOUNTED) ||
                state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){
 
            //읽을 수 있는 상태
            File path = getExternalFilesDirs("MyDir")[0];   //리턴 값이 배열이기 때문에 이렇게 많이 쓴다.
            File file= new File(path,"Data.txt");
            try {
                FileReader fr= new FileReader(file);
                BufferedReader reader= new BufferedReader(fr);
                StringBuffer buffer = new StringBuffer();
 
                String line= reader.readLine();
                while(line!=null){
                    buffer.append(line+"\n");
                    line= reader.readLine();
                }
                tv.setText(buffer.toString());
                reader.close();
 
            } catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {
                e.printStackTrace();
            }
 
 
        }
    }
 
    //requestPermissions()메소드를 실행해서
    //보여진 퍼미션 요청 다이얼로그의
    //DENY, ALLOW 버튼 중 하나를 선택하면
    //자동으로 실행되는 콜백메소드
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 
        switch(requestCode){
            case 100//아까 버튼을 눌렀을때 써준 임의의 requestCode =100
                //사용자가 선택한 결과가 ALLOW 인가?
                if(grantResults[0]==PackageManager.PERMISSION_GRANTED){ //허용
                    Toast.makeText(this"외부 저장소 쓰기 가능", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(this,"거부하셨기에 외부 저장소 사용 불가", Toast.LENGTH_SHORT).show();
                }
 
                break;
        }
    }
 
    public void clickBtn(View view) {
        //외부메모리의 특정 위치에 저장하려면
        //동적 퍼미션이 필요함. (api 23버전 이상부터)
 
        //외부메모리가 연결되어 있는지 확인
        String state= Environment.getExternalStorageState();
        if(!state.equals(Environment.MEDIA_MOUNTED)){
            Toast.makeText(this"저장된 데이터가 없다.",Toast.LENGTH_SHORT).show();
            return;
        }
 
        //동적퍼미션 체크작업(api 23버전 이상일때)
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            //이 앱이 사용자로부터 퍼미션을 받았는지 체크
            int checkResult=checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
 
            //퍼미션이 허용되어 있지 않다면?
            if(checkResult== PackageManager.PERMISSION_DENIED) { //PackageManager.PERMISSION_DENIED 또는 PackageManager.PERMISSION_GRANTED 가 있다. (허용, 허용되지 않음)
                //사용자에게 퍼미션을 요청하는 다이얼로그를 보여주는 메소드를 실행
                String[] permisions= new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
                requestPermissions(permisions,100); //두번째 인자값은 임의로 아무 숫자 써주면 됨.
                return;
            }
 
        }//
 
        //퍼미션이 허가되었다면
        //외부메모리에 저장하기!!
        //SDcard의 특정 위치에 aaa.txt 문서 저장
        File path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); //
        if(path!=null) tv.setText(path.getParent());
 
        File file=new File(path, "aaa.txt");//경로+파일명
 
        try {
            FileWriter fw=new FileWriter(file, true);
            PrintWriter writer= new PrintWriter(fw);
 
            writer.println(et.getText().toString());
            writer.flush();
            writer.close();
 
            et.setText("");
            tv.append("SAVED");
 
        } catch (IOException e) {e.printStackTrace(); }
    }
}
 
 
 

첫 번째 SAVE 버튼 눌렀을 경우

storage->emulated->legacy->Android->data->여기에 내가 저장한 파일이 있다.

(경로는 핸드폰마다 조금씩 다르다.)

여기까지하면 완선!!!! 하지만 약간 다른 방법도 있다.

이 위 경로는 약간 고정적인 경로다..

 

-----------세 번째 버튼버튼 추가---------------------------

카카오톡에서 받은 파일이 어디에 저장되는지 보았는가? 그것처럼 그 방법을 알아보자.

clickBtn 실행하면 허용 다이얼로그 띄우고, 접근을 허용하면 코드에 작성한 경로에 임의 파일 생성및 저장.

(동적퍼미션)

우리는 Download에 aaa.txt를 만들것이다.

 

코드에는 세 번재 버튼까지 다 포함되어 있다.

 

<실행 화면>

댓글