안드로이드 11 파일 쓰기 읽기

필자는 본래 백엔드 계통이다. 프런트를 별로 하고 싶어하진 않는다.


얼마전 반강제로 프런트, 그것도 퓨어 자바만 써야하는! 안드로이드를 하게 되었다.

(라이브러리가 자바로 떡칠되어 있어 어쩔 수 없는 선택이었다)


5년전에 Toy App 하나 만들고 한번도 안드한 적이 없었는데 세상에.

그 사이 세상은 많이 바뀌었더라. 그땐 Android 6했었나? 지금은 11이네 세상에.



5년만에 한 안드 프로젝트에서, 가장 고생했던게 안드로이드 11에서의 파일 쓰기였다.


테스트를 안드로이드 9.0에서 했는데, 다음 코드가 잘 돌아갔다.

보통 인터넷에 떠다니는 코드다.

// 이 경로는 "/sdcard/asdf/"와 같다.
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/asdf/";
    // path에 폴더명 + 파일명까지 넣어주기
public String readTextFile(String path){
StringBuffer strBuffer = new StringBuffer();
try{
InputStream is = new FileInputStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line="";
while((line=reader.readLine())!=null){
strBuffer.append(line+"\n");
}
reader.close();
is.close();
}catch (IOException e){
e.printStackTrace();
return "";
}
return strBuffer.toString();
}
// 폴더명, 파일명은 각각 입력
// overwrite가 0이 아닌 경우 파일 삭제 후 재생성
public int writeTextFile(String foldername, String filename, String contents, int overwrite) {
try {
File dir = new File(foldername);
if (!dir.exists()) {
dir.mkdir();
}
if(overwrite != 0){
File f = new File(foldername + "/" + filename );
if(f.exists()){ // 파일 삭제 후 재작성
f.delete();
}
}
FileOutputStream fos = new FileOutputStream(foldername + "/" + filename, true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos));
writer.write(contents);
writer.flush();
writer.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return 1;
}
return 0;
}

신나게 개발을 다 하고, 안드 11에 release 했다.

세상에나. 저게 안돌아간단다.


원인을 찾아보니, 구글에서 보안 패치를 업데이트 하면서 "/sdcard/"에 막 쓸 수 없게 막았다고 한다. (자세한 건 구글링~)


결국 내부 Storage를 쓰기로 하고, 임시 방편으로 다음 땜빵코드로 바꿨다.

1
2
3
4
5
6
7
    // Android 9.0 에서
    // 이 경로는 "/sdcard/asdf/"와 같다.
    //String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/asdf/";
 
    // Android 11.0 에서
    // 이 경로는 "/storage/emulated/0/Android/data/com.example.앱명/files/" 와 같다.
    String path = context.getExternalFilesDir(null).getPath();

눈물을 머금고 sdcard에서 내부 storage로 변경해서 이슈를 해결했다.


개인적으로 안드는 다시는 하고 싶지 않다.

댓글