레이블이 real file path인 게시물을 표시합니다. 모든 게시물 표시
레이블이 real file path인 게시물을 표시합니다. 모든 게시물 표시

2015년 8월 25일 화요일

Android File Chooser and URI to File Path.

파일을 Intent.ACTION_GET_CONTENT을 이용하여 선택하고 URIFile Path로 변환하기

Image 나 Video 같은 파일을 얻어오는 예제는 많지만 일반 파일을 선택하는 예제가 없어서 며칠 찾아 보다가 직접 external.db에서 값을 얻어와야 한다는 결론을 얻었습니다.

/data/data/com.android.providers.media/databases 경로에 가면 모든 파일을 DB로 관리합니다.

root@odroidc:/data/data/com.android.providers.media/databases # ls -l
-rw-rw---- u0_a4    u0_a4      163840 2015-08-25 03:23 external.db
-rw-rw---- u0_a4    u0_a4       32768 2015-08-25 03:21 external.db-shm
-rw-rw---- u0_a4    u0_a4       28872 2015-08-25 03:21 external.db-wal
-rw-rw---- u0_a4    u0_a4      212992 2015-08-20 06:22 internal.db
-rw------- u0_a4    u0_a4       32768 2015-08-25 03:21 internal.db-shm
-rw------- u0_a4    u0_a4      453232 2015-08-25 03:21 internal.db-wal
root@odroidc:/data/data/com.android.providers.media/databases #

external.db를 sqliteman 프로그램을 이용하여 열어 보시면 아래와 같이 되어 있습니다.
files 테이블에 '_data'란 column에 실제 file path가 들어 있습니다.



private static final int FILE_SELECT_CODE = 0;

private void showFileChooser() {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_GET_CONTENT);

아래와 같이 할 경우 mime-type에 해당하는 파일만 선택 가능해 집니다.
    intent.setType("application/zip");
    intent.addCategory(Intent.CATEGORY_OPENABLE);

    try {
        startActivityForResult(
                Intent.createChooser(intent, "Select a File"),
                FILE_SELECT_CODE);
    } catch (android.content.ActivityNotFoundException ex) {
        // Potentially direct the user to the Market with a Dialog
        Toast.makeText(this, "Please install a File Manager.",
                Toast.LENGTH_SHORT).show();
    }
}

showFileChooser()를 실행하면 아래와 같은 file dialog가 실행 됩니다.


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case FILE_SELECT_CODE:
            if (resultCode == RESULT_OK) {
                // Get the Uri of the selected file
                Uri uri = data.getData();
URI -> real file path
                String file_path = getRealPathFromURI(uri);
            }
            break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


private String getRealPathFromURI(Uri uri) {
    String filePath = "";
    filePath = uri.getPath();
경로에 /storage가 들어가면 real file path로 판단
    if (filePath.startsWith("/storage"))
        return filePath;

    String wholeID = DocumentsContract.getDocumentId(uri);

wholeID는 파일명이 abc.zip이라면 /document/B5D7-1CE9:abc.zip와 같습니다.

    // Split at colon, use second item in the array
    String id = wholeID.split(":")[1];

    Log.e(TAG, "id = " + id);

    String[] column = { MediaStore.Files.FileColumns.DATA };

파일의 이름을 통해 where 조건식을 만듭니다.

    String sel = MediaStore.Files.FileColumns.DATA + " LIKE '%" + id + "%'";

External storage에 있는 파일의 DB를 접근하는 방법 입니다.
    Cursor cursor = getContentResolver().query(MediaStore.Files.getContentUri("external"),
            column, sel, null, null);

SQL문으로 표현하면 아래와 같이 되겠죠????
SELECT _dtat FROM files WHERE _data LIKE '%selected file name%'

    int columnIndex = cursor.getColumnIndex(column[0]);

    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }
    cursor.close();
    return filePath;
}