2013-09-22 3 views
1

기존 데이터베이스를 assets 폴더에 복사하고이 데이터베이스를 응용 프로그램 데이터베이스의 기본 시스템 경로에 복사하기위한 코드를 작성하는 자습서는 거의 읽지 않았습니다.assets 폴더에 복사 된 데이터베이스에 액세스하여 쿼리하는 방법은 무엇입니까?

package com.example.c1; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 

public class DataBaseHelper extends SQLiteOpenHelper { 

    //The Android's default system path of your application database. 
     private static String DB_PATH = "/data/data/com.example.c/databases/"; 

     private static String DB_NAME = "MyDatabase"; 

     private SQLiteDatabase myDataBase; 

     private final Context myContext; 

     /** 
      * Constructor 
      * Takes and keeps a reference of the passed context in order to access to the application assets and resources. 
      * @param context 
      */ 
     public DataBaseHelper(Context context) { 

     super(context, DB_NAME, null, 1); 
     this.myContext = context; 
     } 

     /** 
      * Creates a empty database on the system and rewrites it with your own database. 
      * */ 
     public void createDataBase() throws IOException{ 

     boolean dbExist = checkDataBase(); 

     if(dbExist){ 
     //do nothing - database already exist 
     }else{ 

     //By calling this method and empty database will be created into the default system path 
     //of your application so we are gonna be able to overwrite that database with our database. 
     this.getReadableDatabase(); 

     try { 

     copyDataBase(); 

     } catch (IOException e) { 

     throw new Error("Error copying database"); 

     } 
     } 

     } 

     /** 
      * Check if the database already exist to avoid re-copying the file each time you open the application. 
      * @return true if it exists, false if it doesn't 
      */ 
     private boolean checkDataBase(){ 

     SQLiteDatabase checkDB = null; 

     try{ 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

     }catch(SQLiteException e){ 

     //database does't exist yet. 

     } 

     if(checkDB != null){ 

     checkDB.close(); 

     } 

     return checkDB != null ? true : false; 
     } 

     /** 
      * Copies your database from your local assets-folder to the just created empty database in the 
      * system folder, from where it can be accessed and handled. 
      * This is done by transfering bytestream. 
      * */ 
     private void copyDataBase() throws IOException{ 

     //Open your local db as the input stream 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 

     // Path to the just created empty db 
     String outFileName = DB_PATH + DB_NAME; 

     //Open the empty db as the output stream 
     OutputStream myOutput = new FileOutputStream(outFileName); 

     //transfer bytes from the inputfile to the outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer))>0){ 
     myOutput.write(buffer, 0, length); 
     } 

     //Close the streams 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 

     } 

     public void openDataBase() throws SQLException{ 

      //Open the database 
      String myPath = DB_PATH + DB_NAME; 
      myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

      } 

      @Override 
      public synchronized void close() { 

      if(myDataBase != null) 
      myDataBase.close(); 

      super.close(); 

      } 

      @Override 
      public void onCreate(SQLiteDatabase db) { 

      } 

      @Override 
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      } 



      // Add your public helper methods to access and get content from the database. 
      // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy 
      // to you to create adapters for your views. 

} 

애셋 폴더에서 기본 경로로 데이터베이스를 복사하는 데이 코드를 사용합니다.

package com.example.c1; 

import java.io.IOException; 
import com.example.c1.DataBaseHelper; 
import android.os.Bundle; 
import android.app.Activity; 
import android.database.SQLException; 
import android.view.Menu; 
import android.widget.TextView; 

public class C1 extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.c1); 

     DataBaseHelper myDbHelper = new DataBaseHelper(this); 


     try { 

     myDbHelper.createDataBase(); 

     } catch (IOException ioe) { 

     throw new Error("Unable to create database"); 

     } 

     try { 

     myDbHelper.openDataBase(); 

     }catch(SQLException sqle){ 

     throw sqle; 

     } 


    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.c1, menu); 
     return true; 
    } 

} 

이 기능을 실행하면 에뮬레이터에서 c1이 중지되었다고 말합니다. DDMS보기를 클릭하고 파일 탐색기에서 패키지를 선택합니다. "데이터베이스"폴더를 찾았습니다. 자산 폴더에 내 데이터베이스 즉,; "MyDatabase"가 여기에 있습니다. 그러나 파일을 가져 와서 sqlite 브라우저에서 열면 android_metadata 테이블 만 표시되지만 내 데이터베이스에는 다른 테이블이 표시되지 않습니다. 또한 어떤 쿼리도 실행할 수 없습니다. 데이터베이스에 액세스하고 쿼리하려면 어떻게합니까? DataBaseHelper 클래스에서 "Select"문을 실행하고 결과를 표시하는 것과 같습니다. 나는 내 문제로 분명히 희망한다. 자산 폴더에 복사 된 데이터베이스와이 데이터베이스를 기본 경로에 복사하는 코드가 있습니다. 코드가 맞습니까? 그렇지 않다면 내가해야 할 교정은 무엇입니까? 쿼리를 어떻게 실행해야합니까?

답변

1
그런 다음이

protected Boolean openDatabase() 
{ 
    if(isDatabaseExist(false)) 
    { 
     // Open the database 
     String myPath = DB_PATH + DB_NAME; 
     try 
     { 
      Log.i("Database", "Trying to Open Database!"); 
      if(myDataBase != null) 
      { 
       if(!myDataBase.isOpen()) 
       { 
        Log.i("Database", "Database is closed now opening it!"); 
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 

       } 
       else 
       { 
        Log.i("Database", "Database is already Open!"); 
       } 
       Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !"); 
       return true; 

      } 
      else 
      { 
       myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
       Log.i("Database", "Database is Opened successfully in OPEN_READWRITE Mode !"); 
       return true; 
      } 

     } 
     catch(Exception e) 
     { 
      Log.e("Database", "Some error occured while opening Database Error:" + e.getMessage()); 
      myDataBase = null; 
      return false; 
     } 

    } 
    else 
    { 
     copyDataBase(); 
    } 
    return false; 
} 
를 사용하여 데이터베이스를 내가

private void copyDataBase() 
{ 
    Log.i("Database", "New database is being copied to device!"); 
    byte[] buffer = new byte[1024]; 
    OutputStream myOutput = null; 
    int length; 
    // Open your local db as the input stream 
    InputStream myInput = null; 
    try 
    { 
     myInput = myContext.getAssets().open(DB_NAME); 
     // transfer bytes from the inputfile to the 
     // outputfile 
     myOutput = new FileOutputStream(DB_PATH + DB_NAME); 
     while((length = myInput.read(buffer)) > 0) 
     { 
      myOutput.write(buffer, 0, length); 
     } 
     myOutput.close(); 
     myOutput.flush(); 
     myInput.close(); 
     Log.i("Database", "New database has been copied to device!"); 
     cmn.mailDetails(); 

    } 
    catch(IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

열기를 copyDatabase이를 사용

를 열려면이 파일을 사용하여 응용 프로그램 디렉토리 폴더로 데이터베이스 파일을 복사해야

+0

copyDataBase() 및 openDataBase()를 코드로 교체했습니다. 그것은 나를 위해 일했습니다. 이제 테이블에서 어떻게 검색 할 수 있습니까? 예를 들어 : 나는 테이블의 여섯 번째 행의 내용을 표시하고 싶습니다. 내가 어떻게 할 수 있니? 죄송합니다. 답변을 표시하려했지만 15 가지 평판을 묻는 메시지를 시도했습니다. – user2648852

+0

@ user2648852 OK 나중에 – Trikaldarshi

+0

을 수행 할 수 있으며 sqlite.org 또는 vogella의 자습서를 통해 sqlite에 대해 자세히 알아 보거나 다른 문제에 대해 새 질문을 할 수 있습니다. – Trikaldarshi

관련 문제