달력

4

« 2024/4 »

  • 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
728x90
반응형

안드로이드 - SQLite assets 데이터베이스로 연결하기

 

원본출처:http://crlog.com/49 

안드로이드와 SQLite 관련해서 데이터베이스를 만들고 연결하는 팁들은 검색을 해 보면 금방 찾을 수 있었습니다. 제가 생각한 것은 미리 배포버전 자체내 데이터베이스에 데이터를 만들어 놓고  어플만 다운 받으면 데이터를 가져오는 연결을 하지 않아도 데이터를 이용하고 싶은 생각이 들었습니다.


자료를 찾다보니 안드로이드 개발 프로젝트 폴더 중에 assets가 있는데요. 여기에 SQLite 데이터베이스 파일을 저장해두고 이를 어플이 처음 실행 할 때 스마트폰 기기로 저장을 하는 방법을 사용하더군요. 바로 이거다 했지요!.

개발에 필요한 핵심 요소들을 이렇게 정했습니다.
1. assets 폴더에 sqlite 데이터베이스를 만들어 놓자.
2. 스마트폰의 지정한 위치에 데이터베이스가 없으면 복사를 하자.
3. 파일이 있으면 이를 데이터베이스로 연결하여 사용하자. 끝. ^^

가장 먼저 구한 방법이 데이터베이스를 복사하는 소스였습니다.

private void copyDatabase() throws IOException {
InputStream myInput = crContext.getAssets().open(DB_NAME);
 
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
 
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}

복사하는 메소드는 딱 봐도 군더더기 없이 깔끔해 보입니다. ^^

다음은 assets 폴더에 데이터베이스를 만드는 일 입니다. 처음 생각에는 가장 쉬울 줄 알았는데,  막상 하려고 해보니 몇 가지 문제점이 있었습니다. 그 하나는 sqlite 데이터베이스를 어떻게 만드는가 하는 거죠. 원본 데이터는 데이터베이스 서버에 저장이 되어 있는 상태이고 이를 간단하게 Export 해서 SQLite에 Import를 하려고 한 것 인데요. 그 데이터들이 SQLite에 잘 저장되지 않습니다. 

문제는 한글 입니다. !!!

CSV로 저장하는 과정에서 UTF-8으로 저장을 해야하는데, 계속해서 한글이 깨진 상태로 저장이 됩니다. 별별 방법을 동원해 가면서 하루를 스트레스로 보내야만 했습니다.  ^^


결국 SQLite Databse Browser 로는 할 수가 없다는 결론을 내렸습니다. 한글에 대한 방법이 없을 뿐아니라, 자주 멈추거나 슬그머니 종료가 되기까지 합니다. 그러다가 SQLite Manager 라는 툴을 발견했습니다. 부분 무료 이기 때문에 결제를 하라는 메시지가 빈번하게 나타나긴 하지만, 중요한 것은 한글을 처리 할 수 있다는 것 이지요. ^^


아무튼 겨우 MySQL에서 뽑아온 CSV 파일을 SQLite Manager 로 Import 했습니다.  

데이터베이스를 만들고 스마트폰에 복사를 하는 모듈을 먼저 만들었습니다. 위에 소스 copyDatabase() 하나면 충분합니다.
이제 파일을 연결해서 이를 데이터베이스로 사용하는 일만 남았습니다. 여기에서의 가장 문제점은 데이터베이스 연결이 안된다는 겁니다. !!

다시 원점으로 돌아가서 무엇이 잘못된 것인가를 찾아내는데 다시 하루를 보냈습니다.
문제는 또 한글이었습니다.!!  

 public void openDataBase() throws SQLException{
 String myPath = DB_PATH + DB_NAME;
 sqlite = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.NO_LOCALIZED_COLLATORS);
         }

SQLite에서 다국어 처리를 하려면 SQLiteDatabase.NO_LOCALIZED_COLLATORS를 사용해야 된다고 하네요. ^^

public class DBAdapter {
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(this.context);
try {
DBHelper.createDatabase();
DBHelper.openDataBase();
} catch (IOException e) {
Log.d("DBAdapter", e.toString());
} catch (SQLException e) {
Log.d("DBAdapter", e.toString());
}
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
private SQLiteDatabase sqlite;
private final Context crContext;
DatabaseHelper(Context context)
{
super(context, DB_NAME, null, 3);
         this.crContext = context;
}
public void createDatabase() throws IOException {
if (!checkDatabase()){
this.getReadableDatabase();
try {
copyDatabase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
public boolean checkDatabase() {
SQLiteDatabase checkDB = null;
try{
     String myPath = DB_PATH + DB_NAME;
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
    
     } catch (SQLiteException e) {
     Log.d("checkDatabase", e.toString());
     }
 
     if(checkDB != null){
     checkDB.close();
     }
     return checkDB != null ? true : false;
}
private void copyDatabase() throws IOException {
     InputStream myInput = crContext.getAssets().open(DB_NAME);
 
     String outFileName = DB_PATH + DB_NAME;
     OutputStream myOutput = new FileOutputStream(outFileName);
 
     byte[] buffer = new byte[1024];
     int length;
     while ((length = myInput.read(buffer))>0){
     myOutput.write(buffer, 0, length);
     }
     myOutput.flush();
     myOutput.close();
     myInput.close();
    }
 
 public void openDataBase() throws SQLException{
 String myPath = DB_PATH + DB_NAME;
 sqlite = SQLiteDatabase.openDatabase(myPath, null,  SQLiteDatabase.NO_LOCALIZED_COLLATORS);
 }
 @Override
 public synchronized void close() {
         if(sqlite != null)
          sqlite.close();
         super.close();
 }
 
 @Override
 public void onCreate(SQLiteDatabase db) {
 }
 
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 }  
}
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
public void close()
{
DBHelper.close();
}
}

이틀 동안 삽질한 보람이 있네요. 테스트 폰에서는 아주 잘 돌아갑니다.
728x90
반응형
:
Posted by mapagilove