스토리지는 우리 모두가 알고 있지만 항상 당연하게 여기는 것입니다. 얼마 전까지만 해도 스토리지 용량의 모든 도약은 점진적이었고 불가능해 보였습니다. 오늘날 우리는 기기에 얼마나 많은 용량이 있는지 생각할 때 두 번 생각하지 않습니다(그리고 차이점에 대해 덜 신경 쓰지 않을 수 없음).
더 큰 요점은 메모리에 저장되는 내용의 진화를 살펴보는 것입니다. 스마트폰 이전에는 가끔 사진 한두 장, 게임 몇 개, 수많은 문자 메시지를 저장했습니다. 그러나 이제 모든 표준 전화에는 응용 프로그램, 문서, 사진, 비디오, 음악 파일 등이 포함됩니다. 기기의 저장 공간을 애플리케이션에 활용하는 방법을 알아보겠습니다.
이 기사에서 다룰 내용은 다음과 같습니다.
- Android 휴대전화의 다양한 저장용량
- 저장소 유형의 차이점
- 애플리케이션에서 스토리지를 사용하는 방법
각 애플리케이션은 내부의 두 가지 스토리지 유형에 액세스할 수 있습니다. 및 외부 . 이 두 가지 유형의 스토리지에는 큰 차이점이 있으며, 이를 알고 있으면 다음 애플리케이션을 디자인할 때 도움이 됩니다.
시작하기 전에 스토리지와 캐시에 대해 한 가지 말해야 합니다. 저장소는 영구적으로 저장하려는 항목을 위한 것이고 캐시는 일시적으로 저장하는 것입니다.
내부 저장소
각 응용 프로그램이 운영 체제에서 실행될 때 자체 내부 저장소가 있습니다. 이 저장소는 개인용이며 응용 프로그램에서만 사용할 수 있습니다. 즉, 다른 응용 프로그램은 액세스할 수 없으며 사용자도 액세스할 수 없습니다. 내부 저장소를 사용할 때 염두에 두어야 할 또 다른 사항은 가용성입니다. 외부 저장소와 달리 내부 저장소는 항상 응용 프로그램에 사용할 수 있습니다.
하지만 이 스토리지를 사용하면 단점이 있습니다. 사용자가 애플리케이션을 제거하면 앱의 내부 저장소에 저장된 모든 데이터도 제거됩니다. 휴대전화에 게임을 설치했는데 길 어딘가에서 게임을 제거하기로 결정했다면 어떤 일이 벌어질지 상상해 보세요. 혹시라도 게임을 다시 설치하게 된다면 게임 진행 상황을 저장하고 싶습니다.
그렇다면 내부 저장소에 파일을 저장하는 방법은 무엇입니까?
public void saveFileInternalStorage() {
String FILENAME = "hello_world_file";
String inputToFile = "Hello From Internal Storage!";
try {
FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fileOutputStream.write(inputToFile.getBytes());
fileOutputStream.close();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has been saved successfully",
Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
}
}
코드 예제에서 볼 수 있듯이 hello_world_file이라는 파일을 저장하고 있습니다. "Hello From Internal Storage!"라는 텍스트가 포함된 . 나는 이것을 시도할 때 발생할 수 있는 예외를 보여주기 위해 두 개의 catch 절을 만들었지만 일반 Exception 개체를 사용하여 하나의 catch 절로 최소화할 수 있습니다.
openFileOutput 메소드가 파일이 이미 있으면 파일을 열지만 없으면 파일을 만듭니다. 이 방법의 두 번째 매개변수는 파일 모드입니다. 이 매개변수는 파일의 범위와 파일에 대한 액세스를 지정합니다. 기본값은 MODE_PRIVATE로, 응용 프로그램에서만 파일에 액세스할 수 있습니다.
이 매개변수의 다른 두 값은 MODE_WORLD_READABLE 및 MODE_WORLD_WRITEABLE이지만 API 17부터 더 이상 사용되지 않습니다. 다른 응용 프로그램과 개인 파일을 공유하면 여기에서 자세히 읽을 수 있는 다른 논리 집합을 사용합니다. 마지막으로 파일에 쓸 때 문자열을 바이트로 변환하고 마지막에 파일을 닫아야 합니다.
외부 저장소
이름이 의미하는 것과는 반대로 항상 액세스할 수 있는 것은 아니라는 사실로 정의된 저장소입니다. 이는 외부 SD 카드(보조 외부 저장소)일 수 있지만 장치에 있는 저장소(기본 외부 저장소)일 수도 있음을 의미할 수 있습니다.
사실을 집으로 가져오기 위해 외부 저장소는 USB 케이블을 통해 장치를 컴퓨터에 연결할 때 액세스할 수 있는 저장소입니다. 짐작하셨겠지만 이러한 유형의 저장소에 저장된 모든 항목은 기기의 다른 애플리케이션에서 액세스할 수 있지만 애플리케이션을 제거하면 그대로 유지됩니다.
외부 저장소에 파일을 저장하는 방법을 보여주기 전에 다음 두 가지 작업을 수행해야 합니다.
- 파일을 저장할 공간이 충분한지 확인하세요.
- 런타임 중 권한 요청
충분한 저장 공간이 있는지 확인하려면 다음 코드 줄이 필요합니다.
//Check if you can read/write to external storage
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
외부 저장소에 액세스하려면 AndroidManifest.xml에 다음 권한을 추가해야 합니다.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
또한 API 23부터 위험한 권한은 설치 시간이 아닌 런타임 중에 승인됩니다. 외부 저장소에 쓰기는 하나로 분류되므로 사용자가 애플리케이션 권한 부여 여부를 결정할 수 있도록 로직을 추가해야 합니다.
public void saveFileExternalStorage(View view) {
if (isExternalStorageWritable()) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
writeFileToExternalStorage();
} else{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 0:
{
writeFileToExternalStorage();
break;
}
}
}
writeFileToExternalStorage 이렇게 생겼습니다:
public void writeFileToExternalStorage() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_files");
if (!myDir.exists()) {
myDir.mkdirs();
}
try {
File file = new File(myDir, "myfile.txt");
FileOutputStream out = new FileOutputStream(file);
out.write(inputToFile.getBytes());
out.close();
Toast.makeText(getApplicationContext(),
"File myfile.txt" + " has been saved successfully to external storage",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
여기에 제공된 모든 코드의 예를 보려면 이 GitHub 리포지토리로 이동하세요.
알아두면 좋은 정보
위의 내용은 애플리케이션에 대해 서로 다른 유형의 스토리지를 사용하는 방법에 대한 두 가지 간단한 예였습니다. 우리는 시스템이 관리하는 리소스를 다루기 때문에 이와 관련된 동작도 알고 있어야 합니다.
기본적으로 애플리케이션은 내부 저장소에 설치됩니다(internalOnly 설명 참조 ), 그러나 API 레벨 8에서는 installLocation 속성을 추가할 수 있습니다. , 애플리케이션을 외부 저장소에 설치할 수 있도록 매니페스트에 추가합니다. 그렇게 하는 한 가지 이유는 응용 프로그램이 매우 크고 더 많은 공간이 있기 때문에 사용자가 장치의 외부 저장소에 설치하는 것을 선호하는 경우입니다.
이 속성에는 세 가지 값이 있습니다.
- 자동 - 응용 프로그램을 설치할 특정 환경 설정이 없음을 의미합니다. 응용 프로그램은 내부 저장소에 설치를 시도하지만 꽉 차면 외부 저장소에 설치합니다.
- 내부 전용 - 응용 프로그램은 내부 저장소에만 설치되며 공간이 부족하면 설치되지 않습니다.
- 외부 선호 - 애플리케이션이 외부 저장소에 설치되기를 원하지만 공간이 충분하지 않은 경우 내부적으로 설치됨을 의미합니다.
auto 및 preferredExternal 옵션 모두에 대해 사용자는 애플리케이션을 외부 저장소에서 내부 저장소로 또는 그 반대로 이동할 수 있는 옵션이 있습니다.
사용자가 장치를 컴퓨터에 연결하고 데이터를 공유하거나 SD 카드를 마운트 해제하면 외부 저장소에서 실행되는 모든 응용 프로그램이 파괴됩니다. 응용 프로그램에서 다음 기능 중 하나를 사용하는 경우 외부 저장소에 설치해서는 안 됩니다.
다양한 서비스(알람 서비스 s 특히), 입력 방식 엔진, 라이브 배경 화면, 애플리케이션 위젯, 계정 관리자, 동기화 어댑터, 장치 관리자 및 부팅을 수신하는 브로드캐스트 수신기가 완료되었습니다.