가끔 앱배포시에 DB파일을 함께 배포하는 방법을 문의하는 분들이 계셔서
제가 가지고 있는 정보를 공유하려고 합니다.

DB파일을 배포하는 방법에는 여러가지가 있겠지만(http://www.androidpub.com/7629 회색님 댓글 참조)
제가 공유하는 방법은 apk파일속에 넣어서 배포하는 방법입니다.

순서
1. 1MB가 넘는 DB파일은 900KB씩 잘라서 assets 폴더에 넣는다.
   (assets 폴더에 1MB이상 되는 파일을 넣고 읽으려면 에러가 발생합니다.)
2. 어플이 맨처음 실행될때 assets 폴더에 있는 DB파일을 순서대로 읽어서
   /data/data/패키지명/databases/DB파일명.db 로 하나의 DB파일을 만든다.

먼저 DB파일을 900KB씩 자르는 소스는

FileInputStream fis = new FileInputStream("경로/DB파일명.db");
BufferedInputStream bis  = new BufferedInputStream(fis);
        
FileOutputStream fos = fos = new FileOutputStream("경로/잘라진 DB파일명1.db");;
BufferedOutputStream bos = bos = new BufferedOutputStream(fos);;
        
byte[] b = new byte[1024];
int read = -1;
int count = 1;
int count2 = 1;
        
while((read = bis.read(b, 0, 1024)) != -1)
{            
    bos.write(b, 0, read);
    bos.flush();
            
    if(count2 % 900 == 0)
    {
        count++;
                
        if(fos != null) fos.close();
        if(bos != null) bos.close();
                
        fos = new FileOutputStream("경로/잘라진 DB파일명" + count + ".db");
        bos = new BufferedOutputStream(fos);
    }
            
    count2++;
}
        
fis.close();
bis.close();
if(fos != null) fos.close();
if(bos != null) bos.close();

위와 같이 900KB씩 자른 DB파일을 assets 폴더에 넣습니다.
그리고 어플이 맨처음 실행될때 아래와 같이 /data/data/패키지명/databases/생성될 DB명.db 로 만들어줍니다.

if(어플이 맨처음 실행이면)
{
    AssetManager am = null;
    InputStream[] arrIs = new InputStream[5]; // assets 폴더에 있는 DB파일 갯수 5개
    BufferedInputStream[] arrBis = new BufferedInputStream[5]; // assets 폴더에 있는 DB파일 갯수 5개
        
    FileOutputStream fos = null;    
    BufferedOutputStream bos = null;
        
    try
    {
        File f = new File("/data/data/패키지명/databases/생성될 DB명.db");
          
        // 혹시나 DB가 있으면 지우고 0바이트의 DB파일을 새로 만든다.
        if(f.exists())
        {
            f.delete();
            f.createNewFile();
        }
            
        am = this.getResources().getAssets();
           
        for(int i = 0; i < arrIs.length; i++)
        {
            arrIs[i] = am.open("assets 폴더에 있는 DB명" + (i + 1) + ".db");
            arrBis[i] = new BufferedInputStream(arrIs[i]);
        }
            
        fos = new FileOutputStream(f);
        bos = new BufferedOutputStream(fos);
            
        int read = -1;
        byte[] buffer = new byte[1024];
            
        for(int i = 0; i < arrIs.length; i++)
        {
            while((read = arrBis[i].read(buffer, 0, 1024)) != -1)
            {
                bos.write(buffer, 0, read);
            }
                
            bos.flush();
        }
    }
    catch(Exception e){}
    finally
    {
        for(int i = 0; i < arrIs.length; i++)
        {
            try{if(arrIs[i] != null) arrIs[i].close();}catch(Exception e){}
            try{if(arrBis[i] != null) arrBis[i].close();}catch(Exception e){}
        }
            
        try{if(fos != null) fos.close();}catch(Exception e){}
        try{if(bos != null) bos.close();}catch(Exception e){}
            
        arrIs = null;
        arrBis = null;
    }
}


이상입니다.
그리고 assets 폴더에 있는 파일을 삭제하려고
여기저기 알아봤는데 결국에는 못찾았습니다.
불가능하다는 답변만......
불가능하지 않은 방법을 아시는 분은 말씀해주시면 감사드리겠습니다.

약 1년전쯤 SDK 1.0에서 만든 소스인데 2.0에서도 잘 돌아가고
모토로이에서도 잘 돌아가네요..^^


2011.12.28 추가

위의 소스코드는 db 파일을 900kb 씩 자르는 방식을 사용했는데요..

저건 제가 아는게 없을때 사용했던 방법이고

현재는 1MB 이상인 파일일 경우 900kb 씩 자르지 않고 'DB파일명.mp3' 같이 확장자만 mp3로 바꿔서

assets 폴더에 넣고 프로그램이 실행될때 mp3 확장자만 db 확장자로 바꿔주고

/data/data/패키지명/databases/DB파일명.db 로 저장하면 된다고 하네요..


귀차니즘 때문에 해보지는 않았다는......

profile