在android项目中不能包含预先填充的sqlitedatabase

时间:2014-02-10 14:07:05

标签: android sqlite

我查看过有关包含预先填充的sqlite数据库的帖子,但我仍然收到错误消息。这是我的数据库助手类:

public class MyDBHelper extends SQLiteOpenHelper {

private static MyDBHelper mInstance = null;
private static final int DB_VERSION = 5;
private static final String DB_NAME = "database.sqlite";
static final String TABLE_NAME = "PRODUCTS";
private final Context mContext;
private static SQLiteDatabase myWritableDb;
private static final String DATABASE_PATH = "/data/data/com.example.barcodescanner/databases/";

public static MyDBHelper getInstance(Context ctx) {
    if (mInstance == null) {
        mInstance = new MyDBHelper(ctx.getApplicationContext());
    }
    return mInstance;
}

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

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {

}

public void createDatabase() throws IOException {
    createDB();
}

private void createDB() throws IOException {

    boolean dbExist = DBExists();
    if (!dbExist) {
        this.getReadableDatabase();
        copyDBFromResource();
    }

}

private boolean DBExists() {
    File dbFile = new File(DATABASE_PATH + DB_NAME);
    return dbFile.exists();
}

private void copyDBFromResource() throws IOException {
    InputStream inputStream = null;
    OutputStream outStream = null;
    String dbFilePath = DATABASE_PATH + DB_NAME;

    try {
        inputStream = mContext.getAssets().open(DB_NAME);
        outStream = new FileOutputStream(dbFilePath);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outStream.write(buffer, 0, length);
        }

        outStream.flush();
        outStream.close();
        inputStream.close();
    } catch (Exception ex) {
        System.out.println(ex.getMessage());
    }
}


@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion,
        int newVersion) {
    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    onCreate(sqLiteDatabase);
}


}

我创建了如下数据库:

public MyDBHelper helper = MyDBHelper.getInstance(this);        
helper.createDatabase();

问题是,在copyDBFromResource函数中,在以下行中:

outStream = new FileOutputStream(dbFilePath);

我得到一个例外说

java.io.FileNotFoundException: /data/data/com.example.barcodescanner/databases/database.sqlite: open failed: ENOENT (No such file or directory)

我做错了什么?我的DATABASE_PATH变量中的包名称是MainActivity所在的包名称。那是错的吗?有人可以帮我解决吗?

由于

2 个答案:

答案 0 :(得分:1)

如果您尝试从其他应用程序访问数据库,您应该知道应用程序只能从内部存储器访问自己的文件,因此您的应用程序无法从其他应用程序访问数据库。但是,如果它们位于“外部”存储上,您可以访问其他应用程序的文件:

Android Training: Saving Files

  

内部存储:

     
      
  • 它始终可用。
  •   
  • 此处保存的文件默认只能由您的应用访问。
  •   
  • 当用户卸载您的应用时,系统会从内部存储中删除所有应用的文件。
  •   

更新

如上面的评论中所述,您不需要提供应用程序数据库的路径(并且您不必直接访问该文件),您只需要在您的构造函数中提供数据库名称MyDBHelper类(你做过)。我建议看看here,在我看来,它解释了如何在Android中使用数据库。

答案 1 :(得分:0)

  • 永远不要为应用程序专用文件设置核心路径
  • 只要需要包含包名称
  • ,就使用context.getPackageName()

数据库路径应该是。

final File databaseFile = context.getDatabasePath(DB_NAME);