Skip to content

Most visited

Recently visited

navigation

저장소 옵션

저장소 간략히 보기

  • 원시 데이터에 대해 공유 기본 설정을 사용합니다.
  • 전용 데이터에 대해 내부 기기 저장소를 사용합니다.
  • 전용 데이터가 아닌 대규모 데이터 집합에 대해 외부 저장소를 사용합니다.
  • 구조적 저장소에 대해 SQLite 데이터베이스를 사용합니다.

이 문서의 내용

  1. SharedPreferences 사용
  2. 내부 저장소 사용
  3. 외부 저장소 사용
  4. 데이터베이스의 사용
  5. 네트워크 연결 사용

참고 항목

  1. 콘텐트 제공자와 콘텐츠 확인자

Android는 지속적인 애플리케이션 데이터를 저장하는 여러 옵션을 제공합니다. 선택하는 솔루션은 데이터를 해당 애플리케이션 전용 데이터로 할지 다른 애플리케이션(및 사용자)이 액세스할 수 있도록 할지, 그리고 데이터가 필요로 하는 공간 등 특정 필요에 따라 다릅니다.

데이터 저장소 옵션은 다음과 같습니다.

공유 기본 설정
전용 원시 데이터를 키-값 쌍으로 저장합니다.
내부 저장소
전용 데이터를 기기 메모리에 저장합니다.
외부 저장소
공용 데이터를 공유 외부 저장소에 저장합니다.
SQLite 데이터베이스
구조적 데이터를 전용 데이터베이스에 저장합니다.
네트워크 연결
자신의 네트워크 서버를 사용하여 데이터를 웹에 저장합니다.

Android는 콘텐츠 제공자를 사용하여 전용 데이터도 다른 애플리케이션에 노출할 수 있는 방법을 제공합니다. 콘텐츠 제공자는 개발자가 설정한 제한에 따라 애플리케이션 데이터에 대한 읽기/쓰기 액세스 권한을 노출하는 선택적 구성 요소입니다. 콘텐츠 제공자 사용에 대한 자세한 내용은 콘텐츠 제공자 문서를 참조하세요.

SharedPreferences 사용

SharedPreferences 클래스는 원시 데이터 유형의 지속적인 키-값 쌍을 저장 및 검색할 수 있는 일반 프레임워크를 제공합니다. SharedPreferences를 사용하여 부울, 부동 수, 정수, long 및 문자열 등 원시 데이터를 저장할 수 있습니다. 이 데이터는 (애플리케이션이 중지된 경우에도) 사용자 세션 동안 지속됩니다.

애플리케이션에 대한 SharedPreferences 객체를 가져오려면 다음 두 메서드 중 하나를 사용합니다.

값을 쓰려면:

  1. edit()을 호출하여 SharedPreferences.Editor를 가져옵니다.
  2. putBoolean()putString()과 같은 메서드를 사용하여 값을 추가합니다.
  3. commit()을 사용하여 새 값을 커밋합니다.

값을 읽으려면 getBoolean()getString()와 같은 SharedPreferences 메서드를 사용합니다.

다음은 계산기에서 무음 키 누름 모드에 대한 기본 설정을 저장하는 예입니다.

public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .

       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }

    @Override
    protected void onStop(){
       super.onStop();

      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!
      editor.commit();
    }
}

내부 저장소 사용

기기의 내부 저장소에 파일을 직접 저장할 수 있습니다. 기본적으로, 내부 저장소에 저장된 파일은 해당 애플리케이션의 전용 파일이며 다른 애플리케이션(및 사용자)은 해당 파일에 액세스할 수 없습니다. 사용자가 애플리케이션을 제거하면 해당 캐시 파일은 제거됩니다.

전용 파일을 내부 저장소에 만들고 쓰려면:

  1. 작업 모드와 파일 이름을 사용하여 openFileOutput()을 호출합니다. 그러면 FileOutputStream이 반환됩니다.
  2. write()를 사용하여 파일에 씁니다.
  3. close()를 사용하여 스트림을 닫습니다.

예:

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

MODE_PRIVATE는 파일을 생성하여(또는 동일한 이름의 파일을 대체하여) 해당 파일을 여러분의 애플리케이션에 대해 전용으로 만듭니다. 사용 가능한 다른 모드로는 MODE_APPEND, MODE_WORLD_READABLEMODE_WORLD_WRITEABLE이 있습니다.

참고: 상수 MODE_WORLD_READABLEMODE_WORLD_WRITEABLE은 API 레벨 17 이후로 지원이 중단되었습니다. Android N부터 이를 사용하면 SecurityException이 발생합니다. 즉, Android N 이상을 대상으로 하는 앱은 전용 파일을 이름으로 공유할 수 없으며 "file://" URI를 공유하려고 시도하면 FileUriExposedException이 발생합니다. 앱이 전용 파일을 공유할 필요가 있는 경우 FileProviderFLAG_GRANT_READ_URI_PERMISSION을 함께 사용할 수 있습니다. 파일 공유도 참조하세요.

내부 저장소의 파일을 읽으려면

  1. openFileInput()을 호출하여 읽을 파일 이름을 전달합니다. 그러면 FileInputStream이 반환됩니다.
  2. read()를 사용하여 파일에서 바이트를 읽습니다.
  3. close()를 사용하여 스트림을 닫습니다.

팁: 컴파일할 때 애플리케이션에 정적 파일을 저장하려면 프로젝트 res/raw/ 디렉터리에 해당 파일을 저장하세요. openRawResource()을 사용하여 해당 파일을 열어 R.raw.<filename> 리소스 ID를 전달할 수 있습니다. 이 메서드는 파일을 읽기 위해 사용할 수 있는(그러나 원본 파일에는 쓸 수 없는) InputStream을 반환합니다.

캐시 파일 저장

어떤 데이터를 영구적으로 저장하지 않고 캐시하려면 getCacheDir()를 사용하여 애플리케이션이 임시 캐시 파일을 저장할 내부 디렉터리를 나타내는 File을 열어야 합니다.

기기의 내부 저장소 공간이 부족한 경우 Android는 해당 캐시 파일을 삭제하여 공간을 복구할 수 있습니다. 그러나 해당 캐시 파일을 정리하는 작업을 시스템에 의존해서는 안 됩니다. 캐시 파일은 항상 직접 관리하고 사용된 공간의 합리적인 제한(예: 1MB) 내에 있도록 유지해야 합니다. 사용자가 애플리케이션을 제거하면 해당 캐시 파일은 제거됩니다.

기타 유용한 메서드

getFilesDir()
내부 파일이 저장된 파일 시스템 디렉터리의 절대 경로를 가져옵니다.
getDir()
내부 저장소 공간 내부에 디렉터리를 만듭니다. (또는 기존 디렉터리를 엽니다.)
deleteFile()
내부 저장소에 저장된 파일을 삭제합니다.
fileList()
애플리케이션이 현재 저장한 파일 배열을 반환합니다.

외부 저장소 사용

모든 Android 호환 기기는 파일을 저장하는 데 사용할 수 있는 공유된 "외부 저장소"를 지원합니다. 해당 저장소는 제거할 수 있는 저장소 미디어(예: SD 카드) 또는 (제거할 수 없는) 내부 저장소일 수 있습니다. 외부 저장소에 저장된 파일은 누구든지 읽을 수 있으며, 컴퓨터에서 파일을 전송하도록 USB 대용량 저장소를 사용하는 경우 사용자가 수정할 수 있습니다.

주의: 외부 저장소는 사용자가 외부 저장소를 컴퓨터에 탑재하거나 해당 미디어를 제거하는 경우 사용이 불가능해질 수 있으며 외부 저장소에 저장하는 파일에는 보안이 적용되지 않을 수 있습니다. 모든 애플리케이션은 외부 저장소에 배치된 파일을 읽거나 쓸 수 있으며 사용자는 그 파일을 제거할 수 있습니다.

범위가 지정된 디렉터리 액세스 사용

Android 7.0 이상에서 외부 저장소의 특정 디렉터리에 대한 액세스 권한이 필요한 경우 범위가 지정된 디렉터리 액세스를 사용합니다. 범위가 지정된 디렉터리 액세스는 애플리케이션이 표준 외부 저장소 디렉터리(예: Pictures 디렉터리)에 액세스하는 방법을 단순화하며 애플리케이션이 액세스 권한을 요청하고 있는 디렉터리를 명확하고 자세히 설명하는 간단한 권한 UI를 제공합니다. 범위가 지정된 디렉터리 액세스에 대한 자세한 내용은 범위가 지정된 디렉터리 액세스 사용을 참조하세요.

외부 저장소에 대한 액세스 권한 얻기

외부 저장소의 파일을 읽거나 쓰려면 앱이 READ_EXTERNAL_STORAGE 또는 WRITE_EXTERNAL_STORAGE 시스템 권한을 획득해야 합니다. 예:

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

파일을 읽고 쓰려면 읽기 액세스 권한도 암시적으로 요청하는 WRITE_EXTERNAL_STORAGE 권한만 요청하면 됩니다.

참고: Android 4.4 이상에서 이러한 권한은 앱 전용 파일만 읽거나 쓰는 경우에는 필요하지 않습니다. 자세한 내용은 아래의 앱 전용 파일 저장을 참조하세요.

미디어 사용 가능성 확인

외부 저장소를 사용하여 작업을 수행하기 전에 항상 getExternalStorageState()을 호출하여 미디어를 사용할 수 있는지 확인해야 합니다. 미디어는 컴퓨터에 탑재할 수 있으며 누락되거나 읽기 전용이거나 다른 상태에 있을 수 있습니다. 예를 들어, 다음 두 메서드는 가용성을 확인하는 데 사용할 수 있는 메서드입니다.

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

getExternalStorageState() 메서드는 미디어가 공유 중인지(컴퓨터에 연결되었는지), 완전히 누락되었는지, 잘못 제거되었는지 등 확인하길 원하는 다른 상태를 반환합니다. 애플리케이션이 미디어에 액세스할 필요가 있을 때 이를 사용하여 사용자에게 추가 정보를 알릴 수 있습니다.

다른 앱과 공유할 수 있는 파일 저장

일반적으로 사용자가 앱을 통해 획득할 수 있는 새 파일은 다른 앱이 액세스하고 사용자가 기기에서 쉽게 복사할 수 있도록 기기의 "공용" 위치에 저장해야 합니다. 그렇게 할 경우 Music/, Pictures/Ringtones/과 같은 공유 공용 디렉터리 중 하나를 사용해야 합니다.

적절한 공용 디렉터리를 나타내는 File을 가져오려면 getExternalStoragePublicDirectory()를 호출하고 DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES 등과 같은 원하는 디렉터리 유형에 전달합니다. 파일을 해당 미디어 유형 디렉터리에 저장하여 시스템의 미디어 스캐너가 시스템에서 파일을 적절히 범주화할 수 있습니다(예를 들어, 벨소리는 시스템 설정에서 음악이 아니라 벨소리로 나타남).

예를 들어, 다음은 공용 사진 디렉터리에 새 사진 앨범용 디렉터리를 만드는 메서드입니다.

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

앱 전용 파일 저장

다른 앱이 사용하지 않도록 파일(예: 특정 앱만 사용하는 그래픽 텍스처 또는 음향 효과)을 처리하려면 getExternalFilesDir()를 호출하여 외부 저장소의 개인 저장소 디렉터리를 사용해야 합니다. 또한 이 메서드는 type 인수를 취하여 하위 디렉터리 유형(예: DIRECTORY_MOVIES)을 지정합니다. 특정 미디어 디렉터리가 필요하지 않은 경우 null을 전달하여 앱의 전용 디렉터리의 루트 디렉터리를 수신합니다.

Android 4.4 이상에서 앱 전용 디렉터리 파일 읽기 또는 쓰기는 READ_EXTERNAL_STORAGE 또는 WRITE_EXTERNAL_STORAGE 권한이 필요하지 않습니다. 따라서 maxSdkVersion 특성을 추가하여 Android의 하위 버전에서만 권한이 필요함을 선언할 수 있습니다.

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     android:maxSdkVersion="18" />
    ...
</manifest>

주의: 사용자가 애플리케이션을 제거하면 이 디렉터리와 해당하는 모든 콘텐츠가 삭제됩니다. 또한 해당 디렉터리의 파일은 MediaStore 콘텐츠 제공자가 액세스할 수 없으므로 시스템 미디어 스캐너가 읽을 수 없습니다. 따라서 앱을 사용하여 캡처 또는 편집한 사진 또는 앱을 사용하여 사용자가 구입한 음악과 같이 궁극적으로 사용자에게 속한 미디어용으로 이러한 디렉터리를 사용해서는 안 됩니다. 해당 파일은 공용 디렉터리에 저장해야 합니다.

또한 외부 저장소로 사용하도록 내부 메모리의 파티션을 할당한 기기가 SD 카드 슬롯을 제공할 수도 있습니다. 그런 기기가 Android 4.3 이하를 실행 중인 경우 getExternalFilesDir() 메서드는 내부 파티션에만 액세스 권한을 제공하며 앱은 SD 카드를 읽거나 쓸 수 없습니다. 그러나 Android 4.4 이상에서 각 위치 항목을 포함한 File 배열을 반환하는 getExternalFilesDirs()를 호출하여 두 위치에 액세스할 수 있습니다. 배열의 첫 번째 항목은 기본 외부 저장소로 간주되며, 가득 차거나 사용 불가능하지 않은 경우 해당 위치를 사용해야 합니다. Android 4.3 이하가 지원되는 상황에서 두 위치 모두에 액세스하려면 지원 라이브러리의 정적 메서드 ContextCompat.getExternalFilesDirs()를 사용하면 됩니다. 이는 File 배열도 반환하지만 Android 4.3 이하에서 항상 단일 항목만 포함합니다.

주의 getExternalFilesDir()getExternalFilesDirs()가 제공하는 디렉터리는 MediaStore 콘텐츠 제공자가 액세스할 수 없지만 READ_EXTERNAL_STORAGE 권한을 가진 다른 앱은 이들을 비롯한 외부 저장소의 모든 파일에 액세스할 수 있습니다. 파일에 대한 액세스 권한을 완전히 제한하려면 파일을 내부 저장소에 대신 쓰면 됩니다.

캐시 파일 저장

캐시 파일을 저장할 외부 저장소 디렉터리를 나타내는 File을 열려면 getExternalCacheDir()를 호출합니다. 사용자가 애플리케이션을 제거하면 해당 파일은 자동으로 삭제됩니다.

위에서 설명한 ContextCompat.getExternalFilesDirs()와 유사한 방식으로 ContextCompat.getExternalCacheDirs()를 호출하여 보조 외부 저장소의 캐시 디렉터리에도 액세스할 수 있습니다(사용 가능한 경우).

팁: 파일 공간을 보존하고 앱 성능을 유지하려면 캐시 파일을 주의 깊게 관리하고 앱의 수명 주기 동안 더 이상 필요로 하지 않는 캐시 파일을 제거해야 합니다.

데이터베이스의 사용

Android는 SQLite 데이터베이스에 대한 전체 지원을 제공합니다. 만든 데이터베이스는 애플리케이션 내부(외부가 아님) 클래스에 이름으로 액세스할 수 있습니다.

새 SQLite 데이터베이스를 생성하는 권장 방법은 SQLiteOpenHelper의 서브클래스를 생성하고, onCreate() 메서드를 재정의하는 것입니다. 그러면 SQLite 명령을 실행하여 데이터베이스에 테이블을 생성할 수 있습니다. 예:

public class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}

그리고 나서 정의한 생성자를 사용하여 SQLiteOpenHelper 구현 인스턴스를 가져올 수 있습니다. 데이터베이스에서 쓰고 읽으려면 getWritableDatabase()getReadableDatabase()를 각각 호출합니다. 이 둘은 데이터베이스를 나타내는 SQLiteDatabase 객체를 반환하며 SQLite 작업에 대한 메서드를 제공합니다.

SQLiteDatabase query() 메서드를 사용하여 SQLite 쿼리를 실행할 수 있습니다. 이 메서드는 쿼리할 테이블, 프로젝션, 선택, 열, 그룹화 등과 같은 다양한 쿼리 매개변수를 받아들입니다. 열 별칭을 필요로 하는 쿼리와 같은 복잡한 쿼리의 경우, SQLiteQueryBuilder를 사용해야 합니다. 이 메서드는 쿼리를 빌드하기 위한 여러 편리한 방법을 제공합니다.

모든 SQLite 쿼리는 쿼리를 통해 찾은 모든 행을 가리키는 Cursor를 반환합니다. Cursor는 항상 데이터베이스 쿼리에서 결과를 탐색하고 행과 열을 읽을 수 있는 메커니즘입니다.

Android에서 SQLite 데이터베이스를 사용하는 방법을 보여주는 샘플 앱은 메모장검색 가능한 사전 애플리케이션을 참조하세요.

데이터베이스 디버깅

Android SDK는 SQLite 데이터베이스에서 테이블 콘텐츠를 찾아보고 SQL 명령을 실행하고 기타 유용한 기능을 수행할 수 있는 sqlite3 데이터베이스 도구를 포함합니다. 이 도구를 실행하는 방법은 원격 셸에서 sqlite3 데이터베이스 검사를 참조하세요.

네트워크 연결 사용

연결된 네트워크를 사용하여 웹 기반 서비스에서 데이터를 저장 및 검색할 수 있습니다. 네트워크 작업을 수행하려면 다음 패키지의 클래스를 사용합니다.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)