将现有数据库从assets文件夹复制到内部数据库文件夹错误

时间:2016-08-01 22:35:18

标签: android database sqlite

我有一个名为 palavras.db 的数据库:

palavras.db

它位于我的 res文件夹

inside res folder

我使用这样的数据库:

public class UserListActivity extends AppCompatActivity {

  /* As soon as this activity starts, it sets it's recycler view's adapter as 
   list of words from a result from a query */

  private RecyclerView mRecyclerView;
  private RecyclerView.Adapter mAdapter;
  private RecyclerView.LayoutManager mLayoutManager;

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

    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    mRecyclerView.setHasFixedSize(true);

    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);

    Database db = new Database(getApplicationContext());
    List<Word> words =  db.search();

    mAdapter = new WordAdapter(words);
    mRecyclerView.setAdapter(mAdapter);
  }

数据库类:

public class Database {
  private SQLiteDatabase db;
  private String tableName = "'PALAVRAS'";
  private DatabaseHelper databaseHelper;

  public Database(Context context) {
    databaseHelper = new DatabaseHelper(context);
    databaseHelper.createDatabase();
    databaseHelper.openDatabase();
  }

  public List<Word> search() {
    return databaseHelper.search(tableName);
  }

数据库助手类:

public class DatabaseHelper extends SQLiteOpenHelper {

  private String DB_PATH = "";
  private static final String DB_NAME = "palavras.db";
  private SQLiteDatabase mDatabase;
  private final Context mContext;

  public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, 1);
    this.mContext = context;
    this.DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/";
    Log.d("porra", DB_PATH);
  }

  public void createDatabase() {
    boolean dbExists = checkDatabase();
    if(dbExists) {

    } else {
      this.getReadableDatabase();
      try {
        copyDatabase();
      } catch (IOException e) {
        throw new Error("Error copying database");
      }
    }
  }

  private boolean checkDatabase() {
    SQLiteDatabase checkDB = null;
    try {
      String myPath = DB_PATH + DB_NAME;
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {

    }
    if (checkDB != null) {
      checkDB.close();
    }
    return checkDB != null ? true : false;
  }

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

  public void openDatabase() throws SQLiteException {
    String myPath = DB_PATH + DB_NAME;
    mDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
  }

  @Override
  public void onCreate(SQLiteDatabase db) {

  }

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

  }

  @Override
  public synchronized void close() {
    if (mDatabase != null) {
        mDatabase.close();
    }
    super.close();
  }

  public List<Word> search(String tableName) {
    List<Word> list = new ArrayList<Word>();
    String[] colunas = new String[]{"original", "traduzido"};

    Cursor c = mDatabase.rawQuery("SELECT * FROM "+tableName, null);

    if (c.moveToFirst()) {
      while ( !c.isAfterLast() ) {
        Log.d("Porra", "Table Name=> "+c.getString(0));
        c.moveToNext();
      }
    }
    /*
    Cursor cursor = db.query(tableName, colunas, null, null, null, null, "original ASC");

    if (cursor.getCount() > 0) {
      cursor.moveToFirst();

      do {
        Word w = new Word();
        w.setOriginal(cursor.getString(0));
        w.setTraduzido(cursor.getString(1));
        list.add(w);
      } while(cursor.moveToNext());
    }
    */
    // dbCore.close();
    return list;
  }

我在这里运行的所有东西都是我得到的:

  

08-01 19:20:45.723 4453-4453 / app.visage.testesql E / SQLiteLog:(14)无法在[bda77dda96]第32456行打开文件       08-01 19:20:45.723 4453-4453 / app.visage.testesql E / SQLiteLog:(14)os_unix.c:32456:(2)open(/data/data/app.visage.testesql/databases/palavras。 D b) -       08-01 19:20:45.725 4453-4453 / app.visage.testesql E / SQLiteDatabase:无法打开数据库&#39; /data/data/app.visage.testesql/databases/palavras.db'。                                                                          android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码14):无法打开数据库                                                                              在android.database.sqlite.SQLiteConnection.nativeOpen(本机方法)                                                                              在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)                                                                              在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)                                                                              在android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)                                                                              在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)                                                                              在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)                                                                              在android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)                                                                              在android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)                                                                              在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)                                                                              在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)                                                                              在app.visage.testesql.database.DatabaseHelper.checkDatabase(DatabaseHelper.java:53)                                                                              at app.visage.testesql.database.DatabaseHelper.createDatabase(DatabaseHelper.java:36)                                                                              在app.visage.testesql.database.Database。(Database.java:27)                                                                              at app.visage.testesql.activities.UserListActivity.onCreate(UserListActivity.java:32)                                                                              在android.app.Activity.performCreate(Activity.java:6664)                                                                              在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)                                                                              在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)                                                                              在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)                                                                              在android.app.ActivityThread.-wrap12(ActivityThread.java)                                                                              在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1460)                                                                              在android.os.Handler.dispatchMessage(Handler.java:102)                                                                              在android.os.Looper.loop(Looper.java:154)                                                                              在android.app.ActivityThread.main(ActivityThread.java:6077)                                                                              at java.lang.reflect.Method.invoke(Native Method)                                                                              在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:865)                                                                              在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)       08-01 19:20:45.760 4453-4453 / app.visage.testesql D / AndroidRuntime:关闭VM       08-01 19:20:45.761 4453-4453 / app.visage.testesql E / AndroidRuntime:FATAL EXCEPTION:main                                                                          处理:app.visage.testesql,PID:4453                                                                          java.lang.Error:复制数据库时出错                                                                              at app.visage.testesql.database.DatabaseHelper.createDatabase(DatabaseHelper.java:44)                                                                              在app.visage.testesql.database.Database。(Database.java:27)                                                                              at app.visage.testesql.activities.UserListActivity.onCreate(UserListActivity.java:32)                                                                              在android.app.Activity.performCreate(Activity.java:6664)                                                                              在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)                                                                              在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)                                                                              在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)                                                                              在android.app.ActivityThread.-wrap12(ActivityThread.java)                                                                              在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1460)                                                                              在android.os.Handler.dispatchMessage(Handler.java:102)                                                                              在android.os.Looper.loop(Looper.java:154)                                                                              在android.app.ActivityThread.main(ActivityThread.java:6077)                                                                              at java.lang.reflect.Method.invoke(Native Method)                                                                              在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:865)                                                                              在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

无法复制数据库并且无法打开它。

我的代码是否有问题我无法看到?

另外,当我浏览到我的数据库文件夹时,我发现它已被复制到那里!但并非完整,表 PALAVRAS 不存在,只有 android_metadata

1 个答案:

答案 0 :(得分:1)

  

它放在我的res文件夹中

这不会起作用,因为您的文件不会成为您应用的一部分。您无法创建新位置以将文件放入项目中,例如将其悬挂在res/之外。

  

当我浏览到我的数据库文件夹时,我发现它已被复制到那里

不,不是。

  

但并非完整,表PALAVRAS不存在,只有android_metadata。

这是在您创建空数据库时为您创建的。

或者:

  1. Use SQLiteAssetHelper,它为您提供了一个简单的库来替换您问题中的大部分代码

  2. 阅读您复制并粘贴到项目中的代码,该代码显示正在从资产中复制原始数据库

  3. 在任何一种情况下,您的数据库都将进入assets/目录,而不是res/目录。