2016-12-29 72 views
-1

我有存儲在名爲myDatabase.db資產/數據庫數據庫數據庫時,我想在這裏使用的代碼將其複製到內部存儲:沒有這樣的表:table1的錯誤複製從資產

public class DatabaseOpener extends SQLiteOpenHelper { 

private static String DB_PATH; 

private static String DB_NAME = "table1.db"; 

private static int DB_VERSION = 4; 

private SQLiteDatabase myDataBase; 

private static Context myContext; 

private static DatabaseOpener instance; 

private DatabaseOpener(Context context) { 
    super(context, DB_NAME, null, DB_VERSION); 
    this.myContext = context; 
} 

public static synchronized DatabaseOpener getInstance(Context context) { 
    if (instance==null) { 
     instance = new DatabaseOpener(context); 
    } 

    if(Build.VERSION.SDK_INT >= 4.2) { 
     DB_PATH = myContext.getApplicationInfo().dataDir + "/databases/"; 
    } else { 
     DB_PATH = "/data/data/" + myContext.getPackageName() + "/databases/"; 
    } 
    return instance; 
} 

public void createDataBase() throws IOException { 
    boolean dbExist = checkDataBase(); 
    if(dbExist) { 

    } else { 
     this.getReadableDatabase(); 
     try { 
      copyDataBase(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private boolean checkDataBase(){ 
    SQLiteDatabase checkDB = null; 
    try{ 
     String myPath = DB_PATH + DB_NAME; 
     File file = new File(myPath); 
     if (file.exists() && !file.isDirectory()) { 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
     } 
    }catch(SQLiteException e){ 
     e.printStackTrace(); 
    } 

    if(checkDB != null){ 
     checkDB.close(); 
    } 

    return checkDB != null ? true : false; 
} 

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 { 
    String myPath = DB_PATH + DB_NAME; 
    File file = new File(myPath); 
    if (file.exists() && !file.isDirectory()) { 
     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) { 

} 

上述代碼工作成功,直到我卸載我的應用程序。問題是數據庫沒有成功複製。我擁有的文件是可以的,但是當它被複制到路徑中時,如果我在DB瀏覽器中將其打開並且它沒有表格。如果我將它推入模擬器,它會再次運行,但我無法將其推入無根設備。唯一的方法是在路徑上創建一個數據庫文件,並從資產中複製一個。那麼,我做錯了什麼? 此外,這是我如何調用DatabaseOpener類:

DatabaseOpener db = DatabaseOpener.getInstance(context); 
    try { 
     db.createDataBase(); 
    } catch (IOException e) { 
     throw new Error ("Unable to create database"); 
    } 
    try { 
     db.openDataBase(); 
    }catch(SQLException sqle){ 
     throw sqle; 
    } 

    Object object = db.getObjectByName(name); 

    db.close(); 
    return object; 

編輯:我收到的錯誤是android.database.sqlite.SQLiteException: no such table: table1 (code 1): , while compiling

+1

使用[SQLiteAssetHelper](https://github.com/jgilfelt/android-sqlite - 資產輔助)。 –

+0

擴展SQLiteAssetHelper而不是SQLiteOpenHelper時發生相同的錯誤:android.database.sqlite.SQLiteException:沒有這樣的表:table1(代碼1):編譯時。除了更改DatabaseOpener的父類之外,還必須執行其他操作嗎? –

回答

0

我解決了用下面的代碼的問題:

public DatabaseOpener(Context context) throws IOException { 
    super(context, DB_NAME, null, DB_VERSION); 
    this.myContext = context; 

    if (Build.VERSION.SDK_INT >= 4.2) { 
     DB_PATH = myContext.getApplicationInfo().dataDir + "/databases/"; 
    } else { 
     DB_PATH = "/data/data/" + myContext.getPackageName() + "/databases/"; 
    } 

    boolean dbexist = checkDataBase(); 
    if (dbexist) { 
     openDataBase(); 
    } else { 
     System.out.println("Database doesn't exist"); 
     createDataBase(); 
    } 
} 

public void createDataBase() throws IOException { 
    boolean dbexist = checkDataBase(); 
    if (dbexist) { 
     // System.out.println(" Database exists."); 
    } else { 
     this.getReadableDatabase(); 
     try { 
      copyDataBase(); 
     } catch (IOException e) { 
      throw new Error("Error copying database"); 
     } 
    } 
} 

private boolean checkDataBase() { 
    boolean checkdb = false; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     File dbfile = new File(myPath); 
     checkdb = dbfile.exists(); 
    } catch (SQLiteException e) { 
     System.out.println("Database doesn't exist"); 
    } 
    return checkdb; 
} 

private void copyDataBase() throws IOException { 
    // Open your local db as the input stream 
    InputStream myinput = myContext.getAssets().open("databases/" + 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(DB_PATH + DB_NAME); 

    // transfer byte to inputfile to 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_READWRITE); 
} 

@Override 
public synchronized void close() { 
    if (myDataBase != null) 
     myDataBase.close(); 

    super.close(); 
} 
0

一旦你卸載應用程序android刪除所有與應用程序相關的本地數據存儲,因此SQLDatabase將被銷燬。

而當您重新安裝應用程序時,您在創建表之前嘗試訪問它,因此會拋出錯誤。確保您在操作其數據之前創建表。

你需要寫在onCreate(SQLiteDatabase db)

db.execSQL(CREATE_TABLE_QUERY);