Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Tags more
Archives
Today
Total
관리 메뉴

맨땅에 코딩

안드로이드 DB 데이터 csv 파일로 추출 본문

앱 개발/Java

안드로이드 DB 데이터 csv 파일로 추출

맨땅 2021. 12. 23. 14:08

목차

    반응형

    java로 작성하였습니다.

     

    우선 Manifest에 권한을 추가해줍니다

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <application
        android:requestLegacyExternalStorage="true"
       >

    application 에서 android:requestLegacyExternalStorage도 "true"로 설정해줍니다

     

     

    아래 함수가 DB를 csv 파일로 추출하는 함수입니다

     

    [MainActivity.java]

    private void exportDB() {
    
    
            // 파일 경로를 Download로 지정
            File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
            File file = new File(root, "test.csv");
    
            try
            {
                file.createNewFile();
                CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
                SQLiteDatabase db = dbHandler.getReadableDatabase();
                // table 이름 써주기 
                Cursor curCSV = db.rawQuery("SELECT * FROM student",null);
                csvWrite.writeNext(curCSV.getColumnNames());
                while(curCSV.moveToNext())
                {
                    //내가 쓰고 싶은 열 순서대로 써주기
                    String arrStr[] ={curCSV.getString(0),curCSV.getString(1), curCSV.getString(2),curCSV.getString(3)};
                    csvWrite.writeNext(arrStr);
                }
                csvWrite.close();
                curCSV.close();
            }
            catch(Exception sqlEx)
            {
                Log.e("MainActivity", sqlEx.getMessage(), sqlEx);
            }
        }

     

    Table 이름은 자신의 DB Table 이름으로 변경해주시면됩니다

    저는 Table에 칼럼이 _id, name, age, address 이렇게 4개이기 때문에 getString을 0~3까지 해주었습니다.

     

     

    CSVWriter 클래스도 만들어 줍니다.

    DBHandler는 여러분의 DB를 사용해주시면 됩니다

     

    [CSVWriter.java]

    public class CSVWriter {
    
        private PrintWriter pw;
    
        private char separator;
    
        private char quotechar;
    
        private char escapechar;
    
        private String lineEnd;
    
        /** The character used for escaping quotes. */
        public static final char DEFAULT_ESCAPE_CHARACTER = '"';
    
        /** The default separator to use if none is supplied to the constructor. */
        public static final char DEFAULT_SEPARATOR = ',';
    
        /**
         * The default quote character to use if none is supplied to the
         * constructor.
         */
        public static final char DEFAULT_QUOTE_CHARACTER = '"';
    
        /** The quote constant to use when you wish to suppress all quoting. */
        public static final char NO_QUOTE_CHARACTER = '\u0000';
    
        /** The escape constant to use when you wish to suppress all escaping. */
        public static final char NO_ESCAPE_CHARACTER = '\u0000';
    
        /** Default line terminator uses platform encoding. */
        public static final String DEFAULT_LINE_END = "\n";
    
        /**
         * Constructs CSVWriter using a comma for the separator.
         *
         * @param writer
         *            the writer to an underlying CSV source.
         */
        public CSVWriter(Writer writer) {
            this(writer, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER,
                    DEFAULT_ESCAPE_CHARACTER, DEFAULT_LINE_END);
        }
    
        /**
         * Constructs CSVWriter with supplied separator, quote char, escape char and line ending.
         *
         * @param writer
         *            the writer to an underlying CSV source.
         * @param separator
         *            the delimiter to use for separating entries
         * @param quotechar
         *            the character to use for quoted elements
         * @param escapechar
         *            the character to use for escaping quotechars or escapechars
         * @param lineEnd
         *             the line feed terminator to use
         */
        public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd) {
            this.pw = new PrintWriter(writer);
            this.separator = separator;
            this.quotechar = quotechar;
            this.escapechar = escapechar;
            this.lineEnd = lineEnd;
        }
    
        /**
         * Writes the next line to the file.
         *
         * @param nextLine
         *            a string array with each comma-separated element as a separate
         *            entry.
         */
        public void writeNext(String[] nextLine) {
    
            if (nextLine == null)
                return;
    
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < nextLine.length; i++) {
    
                if (i != 0) {
                    sb.append(separator);
                }
    
                String nextElement = nextLine[i];
                if (nextElement == null)
                    continue;
                if (quotechar !=  NO_QUOTE_CHARACTER)
                    sb.append(quotechar);
                for (int j = 0; j < nextElement.length(); j++) {
                    char nextChar = nextElement.charAt(j);
                    if (escapechar != NO_ESCAPE_CHARACTER && nextChar == quotechar) {
                        sb.append(escapechar).append(nextChar);
                    } else if (escapechar != NO_ESCAPE_CHARACTER && nextChar == escapechar) {
                        sb.append(escapechar).append(nextChar);
                    } else {
                        sb.append(nextChar);
                    }
                }
                if (quotechar != NO_QUOTE_CHARACTER)
                    sb.append(quotechar);
            }
    
            sb.append(lineEnd);
            pw.write(sb.toString());
    
        }
    
        /**
         * Flush underlying stream to writer.
         *
         * @throws IOException if bad things happen
         */
        public void flush() throws IOException {
    
            pw.flush();
    
        }
    
        /**
         * Close the underlying stream writer flushing any buffered content.
         *
         * @throws IOException if bad things happen
         *
         */
        public void close() throws IOException {
            pw.flush();
            pw.close();
        }
    
    }

     

     

    그러나 이렇게만 해준결과

    1. file createnewfile permission denied 

    2. 어플이 꺼지진 않지만 추출되지 않는 현상

    이 발생했습니다. (= 외부 저장소에 새 파일을 생성할 때 권한 거부)

     

    찾아보니 API 23+에 필요한 권한 팝업 때문이라는데 정확한 이유는 잘 모르겠습니다.

     

     

     

    그래서 하루종일 고생해서 찾아낸 해결방법을 알려드리겠습니다.

     

    [MainActivity.java]에 아래의코드를 따로 추가해줍니다

    // Storage Permissions
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

     

     

    권한과 관련된 함수도 추가해줍니다.

    public static void verifyStoragePermissions(Activity activity) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }

     

    그 후 onCreate부분에 아래의 코드를 추가해주시면 됩니다.

    verifyStoragePermissions(this);

     

     

     

    실행 결과

     

     

    위 코드에서 test.csv라고 설정해준 이름대로 csv 파일이 생성된 것을 확인할 수 있습니다.

     

     

    값도 맞게 들어간 것을 확인할 수 있습니다.

    반응형