如何使用 SQLiteOpenHelper 与 sd 卡上的数据库?
根据此处和网络扩展应用程序中的各种答案及其继承的方法 getDatabasePath() 将允许设置从标准内部存储器位置到插入的更大尺寸的 SD 卡的数据库存储路径。
这对我不起作用。建议的构造仍然使用内存上的数据库。事实上,SQLiteOpenHelper 永远不会调用 getDatabasePath() 方法。
我想让这个启动并运行。
这是我到目前为止所做的:
1.)扩展应用程序:
public class MyApplication extends Application {
@Override
public File getDatabasePath(String name) {
// Just a test
File file = super.getDatabasePath(name);
return file;
}
@Override
public void onCreate() {
// Just a test
super.onCreate();
}
}
2.)将扩展应用程序添加到清单:
<application
...
android:name="MyApplication"
... >
3.)扩展和使用 SQLiteOpenHelper:
public class MySqliteOpenHelper extends SQLiteOpenHelper {
public void onCreate(SQLiteDatabase sqliteDatabase) {
...
}
@Override
public void onUpgrade(SQLiteDatabase sqliteDatabase, int oldVersion, int newVersion) {
...
}
}
4.)以通常的方式在我的活动中使用扩展的 SQLiteOpenHelper:
public class MyActivity extends Activity {
private MySqliteOpenHelper mySqliteOpenHelper;
private SQLiteDatabase sqliteDatabase;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
...
mySqliteOpenHelper = new MySqliteOpenHelper(getApplicationContext());
sqliteDatabase = mySqliteOpenHelper.getReadableDatabase();
...
}
@Override
protected void onDestroy() {
if (mySqliteOpenHelper != null) {
mySqliteOpenHelper.close();
mySqliteOpenHelper = null;
}
super.onDestroy();
}
}
我想指出发现扩展的应用程序类总体上正在工作。我可以看到这一点,因为 MyApplication.onCreate() 被调用。但 MyApplication.getDatabasePath() 未被调用。
非常感谢任何帮助。
According to various answers here and in the web extending Application and it's inherited method getDatabasePath() would allow to set the database storage path from the standard internal memory location to an inserted SD-card of bigger size.
This is not working for me. The suggested construct is still using the database on internal memory. In fact the method getDatabasePath() is never called by SQLiteOpenHelper.
I would like to get this up and running.
Here's what I did so far:
1.) Extending Application:
public class MyApplication extends Application {
@Override
public File getDatabasePath(String name) {
// Just a test
File file = super.getDatabasePath(name);
return file;
}
@Override
public void onCreate() {
// Just a test
super.onCreate();
}
}
2.) Adding extended Application to the Manifest:
<application
...
android:name="MyApplication"
... >
3.) Extending and using SQLiteOpenHelper:
public class MySqliteOpenHelper extends SQLiteOpenHelper {
public void onCreate(SQLiteDatabase sqliteDatabase) {
...
}
@Override
public void onUpgrade(SQLiteDatabase sqliteDatabase, int oldVersion, int newVersion) {
...
}
}
4.) Using the extended SQLiteOpenHelper in my Activities in the usual way:
public class MyActivity extends Activity {
private MySqliteOpenHelper mySqliteOpenHelper;
private SQLiteDatabase sqliteDatabase;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
...
mySqliteOpenHelper = new MySqliteOpenHelper(getApplicationContext());
sqliteDatabase = mySqliteOpenHelper.getReadableDatabase();
...
}
@Override
protected void onDestroy() {
if (mySqliteOpenHelper != null) {
mySqliteOpenHelper.close();
mySqliteOpenHelper = null;
}
super.onDestroy();
}
}
I want to point out that the extended Application class is working in general. I can see this because MyApplication.onCreate() is called. But MyApplication.getDatabasePath() is not called.
Any help is highly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我发现我可以在 Android 2.2 中使用完整路径,但在 2.1 中 Context.openOrCreateDatabase() 方法抛出异常。为了解决这个问题,我将该方法包装为直接调用 SQLiteDatabase.openOrCreateDatabase() 。这是我的扩展 SQLOpenHelper 的构造函数
I found I could use a full path in Android 2.2, but in 2.1 the Context.openOrCreateDatabase() method threw an exception. To work around this I wrapped that method to call SQLiteDatabase.openOrCreateDatabase() directly. Here is the constructor for my extended SQLOpenHelper
重写 SQLOpenHelper 以使用 SD 卡目录而不是上下文,然后扩展它似乎对我有用。
这是当上面由 Roger Keays 描述的方法在 Android 4.0.3 上停止工作时完成的。
Rewriting SQLOpenHelper to use the SD card directory rather than the context and then extending that seems to work for me.
This was done when the method described above by Roger Keays stopped working on Android 4.0.3.
这段代码解决了我的类似问题,我的应用程序类:
希望它会对您有所帮助。
This code fixed my similar problem, my application class:
Hope it will help you.
好吧,我想你不能那样做。如果有人知道方法,请告诉我们如何做。
因此,当您调用时,
一切都应该没问题,就像我们查看 实现 我们看到:
一切都很好。但是如果我们看一下几行:
所以它实际上是在调用另一个方法,如果失败,只有然后它才会继续使用 getDatabasePath()。
如果我们看一下 getWritableDatabase 的实现 - 我们可以清楚地看到它没有使用 getDatabasePath 而是:
这让我们看到 openOrCreateDatabase 是如何实现的,我们将看一下 ContextImpl.java
因此,我们可以看到,如果此帮助器方法 validateFilePath 获取完整路径(如 /some/truly/full/path)或尝试将 getDatabasesDir() 与文件名连接,则它返回 File 。
getDatabasesDir() 实现使用 getDataDirFile() ,它是公共的,理论上可能会被覆盖..但您必须检查。
目前我看到两种解决方案:
1)如果您不需要写入访问强制 sqlite db 进入只读模式,则 getWritableDatabase 将失败并且 getDatabasePath 将被调用
2)将完整路径传递到 SQLiteOpenHelper 构造函数中,并确保 db 可写,如下所示:
这对我来说确实没有意义,但查看 android 源代码(至少 2.3.1),似乎这就是它的实现方式。
Well, i guess you cannot do that. If anyone knows a way, please tell us how.
So when you are calling
It should all be ok as if we look at the implementation we see that:
All good. But if we take a look few lines up:
So it is actually calling another method, and if it fails, only then it procedes to use getDatabasePath().
If wee look at the implementation of getWritableDatabase - we can clearly see that it does not use getDatabasePath but instead:
This brings us to see how openOrCreateDatabase is implemented for that we'll take a look at ContextImpl.java
So we can see that this helper method validateFilePath returns File if it gets a full path (like /some/truly/full/path) or tries to concat getDatabasesDir() with filename.
getDatabasesDir() implementation uses getDataDirFile() which is public and maybe in theory could be overwritten .. but you would have to check.
Currently i see two solutions:
1) If you don't need write access force sqlite db into readonly mode, getWritableDatabase will fail and getDatabasePath will get called
2) Pass in full path into SQLiteOpenHelper constructor, and make sure db is writable, something like:
This truly makes no sense to me, but looking at android sources (at least 2.3.1) it seems this is the way it is implemented.
调用此函数将调用 SqliteOpen 帮助程序类中的 onCreate 方法
oncreate 方法如下所示
DATABASE_CREATE 是包含用于创建数据库的查询的字符串
Calling this function will invoke the onCreate method in the SqliteOpen helper class
The oncreate method is like this
DATABASE_CREATE is the string which contain the query for creating database
您的数据库保存在其内部存储器中,以便其他应用程序无法访问它并更改/损坏数据。
android数据库的默认路径是 /data/data/APPLICATIONPACKAGENAME/databases/ 。以下是关于如何将数据库存储在文件中然后在运行时填充它的很好的指南。
文章
Your database is kept in its internal memory so that other applications can't access it and change/corrupt data.
The default path of the android database is /data/data/APPLICATIONPACKAGENAME/databases/ . The following is a pretty good guide on how to store your database in a file and then populate it at run time.
Article