我遇到了一个奇怪的问题。我正在查询数据库表中的单词列表,并能够获得该列表。但是我无法更新该表。奇怪的是,logcat显示Code 14错误。我卸载了应用程序,重新运行它,所以数据库是新复制的,但是什么都没有改变。
以下是dbHandler代码:
public VocabDatabase(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
this.DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
}
/**
* 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.getWritableDatabase();
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() {
this.getReadableDatabase();
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (checkDB != null) {
checkDB.close();
}
return (checkDB != null) ? true : false;
}
private boolean checkDataBaseAlt(){
File chkdb = new File(DB_PATH);
return chkdb.exists();
}
/**
* 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 = 0;
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();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
try {
copyDataBase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 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.
//add your public methods for insert, get, delete and update data in database.
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
}
public long insert(String table, String nullColumnHack, ContentValues contentValues) {
SQLiteDatabase db = this.getWritableDatabase();
return db.insert(table, nullColumnHack, contentValues);
}
public Cursor rawQuery(String string, String[] selectionArguments) {
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery(string, selectionArguments);
}
public long update(String table, ContentValues contentValues, String whereClause, String[] whereArgs) {
SQLiteDatabase db = this.getWritableDatabase();
return db.update(table, contentValues, whereClause, whereArgs);
}
}
这是服务代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
vdb = new VocabDatabase(this);
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
createDB();
queryDB();
return super.onStartCommand(intent, flags, startId);
}
private void createDB() {
vdb.getWritableDatabase();
try {
vdb.createDataBase();
vdb.openDataBase();
} catch (Exception e) {
e.printStackTrace();
}
}
public void queryDB() {
String vet = "";
ArrayList<String> lister = new ArrayList<>();
Cursor cr = vdb.query(TABLE_NAME, null, null, null, null, null, null);
if (cr.moveToFirst()) {
do {
lister.add(cr.getString(0));
} while (cr.moveToNext());
}
cr.close();
String vet="";
for (String v : lister) {
vet += v + "\t";
}
}
字符串兽医显示在烤面包中,我可以看到表格第一列中的所有单词。但是我无法更新行。
private void updateInDatabase(String up, String pot) {
ContentValues conval = new ContentValues();
conval.put(pot, "1");
try {
long res = vdb.update(TABLE_NAME, conval, "Word=?", new String[]{up});
} catch (Exception e) {
}
}
我已经给了它存储权限,并对其进行了双重检查。
清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.hack.corrector">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".scrapeservice"/>
</application>
错误日志:
05-17 13:39:04.614 28088-28088/com.example.hack.corrector E/SQLiteLog: (14) cannot open file at line 31282 of [5a3022e081]
05-17 13:39:04.615 28088-28088/com.example.hack.corrector E/SQLiteLog: (14) os_unix.c:31282: (21) open(/data/user/0/com.example.hack.corrector/databases/) -
05-17 13:39:04.616 28088-28088/com.example.hack.corrector E/SQLiteDatabase: Failed to open database '/data/user/0/com.example.hack.corrector/databases/'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:207)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:191)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
at com.example.hakc.corrector.VocabDatabase.checkDataBase(VocabDatabase.java:81)
at com.example.hakc.corrector.VocabDatabase.createDataBase(VocabDatabase.java:48)
at com.example.hakc.corrector.scrapeservice.createDB(scrapeservice.java:48)
at com.example.hakc.corrector.scrapeservice.onStartCommand(scrapeservice.java:39)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3049)
at android.app.ActivityThread.access$2300(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1479)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5571)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)
05-17 1
我相信您会发现,无法打开数据库错误实际上不是故障,而是问题的迹象。这就是checkdataBase方法遇到的打开错误,因为它无法按消息所述打开数据库。由于它被捕获,因此不会导致故障。
相反,所发生的是,checkDatabase方法返回false,因为它无法打开数据库,因此每次运行应用程序时都会从资产中复制数据库。从而撤消以前运行的任何更改。
使用两行代码诊断/调试这一点很简单。
根据:-
/**
* Creates a empty database on the system and rewrites it with your own database.
*/
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
Log.d("DBEXISTCHK", "Method checkdataBase returned" + String.valueOf(dbExist)); //<<<<<<<<<< ADDED
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.getWritableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
和
根据:-
private void copyDataBase() throws IOException {
Log.d("DBCOPY","Database is being copied from the Assets."); //<<<<<<<<<< ADDED
//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 = 0;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
结果日志将类似于(注意最后两行):-
05-17 10:12:22.591 1152-1152/bcdbfa.basiccopydbfromassets E/SQLiteLog: (14) cannot open file at line 30174 of [00bb9c9ce4]
(14) os_unix.c:30174: (21) open(/data/data/bcdbfa.basiccopydbfromassets/databases/) -
05-17 10:12:22.591 1152-1152/bcdbfa.basiccopydbfromassets E/SQLiteDatabase: Failed to open database '/data/data/bcdbfa.basiccopydbfromassets/databases/'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
at bcdbfa.basiccopydbfromassets.VocabDatabase.checkDataBase(VocabDatabase.java:85)
at bcdbfa.basiccopydbfromassets.VocabDatabase.createDataBase(VocabDatabase.java:45)
at bcdbfa.basiccopydbfromassets.MainActivity.onCreate(MainActivity.java:18)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
05-17 10:12:22.591 1152-1152/bcdbfa.basiccopydbfromassets W/System.err: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
05-17 10:12:22.599 1152-1152/bcdbfa.basiccopydbfromassets W/System.err: at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
at bcdbfa.basiccopydbfromassets.VocabDatabase.checkDataBase(VocabDatabase.java:85)
at bcdbfa.basiccopydbfromassets.VocabDatabase.createDataBase(VocabDatabase.java:45)
at bcdbfa.basiccopydbfromassets.MainActivity.onCreate(MainActivity.java:18)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
05-17 10:12:22.599 1152-1152/bcdbfa.basiccopydbfromassets D/DBEXISTCHK: Method checkdataBase returnedfalse
05-17 10:12:22.599 1152-1152/bcdbfa.basiccopydbfromassets D/DBCOPY: Database is being copied from the Assets.
修复更简单,这只是一个改变的问题:-
String myPath = DB_PATH;
到
String myPath = DB_PATH + DB_NAME;
在checkDatabase
方法中。
在这种情况下,日志中的结果(如果保留日志)将为:-
05-17 10:30:49.809 1265-1265/? D/DBEXISTCHK: Method checkdataBase returnedtrue
仅创建同名的空数据库。
这是因为在调用createDatabase方法之前,您正在createDB方法中调用getWritableDatabase
。也就是说,如果没有数据库,getWritableDatabase
将创建一个空数据库(禁止sqlite_master表,对于android,禁止android_metadata表),然后调用onCreate
方法。这就解释了为什么当完整路径正确时,会绕过数据库的副本,并且因此存在数据库空数据库。
但是当我把“myPath”改回myPath=DB\u Path时;整个数据库都被复制了,但问题仍然存在。
如前所述,当路径不正确时,checkDatabase方法将始终返回false,因此调用copyDatabase方法,因为使用的路径正确。
所以
private void createDB() {
vdb.getWritableDatabase(); //<<<<<<<<<< The villainous line
try {
vdb.createDataBase();
vdb.openDataBase();
} catch (Exception e) {
e.printStackTrace();
}
}
应该是
private void createDB() {
try {
vdb.createDataBase();
vdb.openDataBase();
} catch (Exception e) {
e.printStackTrace();
}
}
显然,所有路径都是包含数据库名称的完整路径。
就像例外告诉我们的:
无法打开数据库/data/user/0/com.example.hack.corrector/databases/。
您正试图使用变量DB\u PATH打开SQLite DB,如下所示
this.DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
您不设置文件名,只设置目录路径<代码>数据库//code>是一个目录。
将文件名设置为您的路径:
this.DB_PATH = context.getApplicationInfo().dataDir + "/databases/my_db";
编辑:您有两个DB名称变量。。。您正在使用DB\u NAME打开与助手的连接(在超级构造函数中),然后在您使用的检查方法中。
因此,您可以从助手获得连接
this.getWritableDatabase(); //Using the DB at `DB_NAME`
但Will没能联系上
String myPath = DB_PATH;
SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
因为您使用了DB_PATH
而不是DB_NAME
。您使用了2个不同的数据库路径。
如果您在API级别23或更高版本上运行应用程序,则会出现此问题,因为本文引入了新的实时权限模型。在这些版本中,用户在应用运行时向应用授予权限
为了在运行时获得权限,您必须请求用户。您可以通过以下方式完成:
请求权限
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, REQUEST_CODE); //REQUEST_CODE can be any Integer value
并检查您的权限结果
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Permission granted.
//Now you can try your database creating and writing stuff.
}
else{
//Permission denied.
}
break;
}
}
如果这不能解决您的问题,请转到此链接。对于同一个问题,这里有许多解决方案。
Android数据库sqlite。SqliteContoPenDatabaseException:未知错误(代码14):无法打开数据库
错误代码 宏定义 #define RT_EOK 0 无错误 #define RT_ERROR 1 一般错误 #define RT_ETIMEOUT 2 超时错误 #define RT_EFULL 3 资源已满 #define RT_EEMPTY 4 资源已空 #define RT_ENOMEM 5 内存不足 #de
说明:编写一条if语句,验证字符串是否包含字符。 添加一个if语句,检查是否大于零。不要忘记if语句末尾的!如果字符串中确实有一些字符,则打印用户的单词。否则(即:语句),请打印空。您需要多次运行代码,测试空字符串和带字符的字符串。当你确信你的代码可以工作时,继续下一个练习。 我被卡住了,因为我一直遇到以下错误。我做错了什么?
我的服务器上的Https不工作并得到。我尝试了太多的东西,但无法得到任何结果。我的带有Nginx反向代理的HttpSpring启动服务器工作得很好。 下面是我的 /etc/nginx/conf.d/*. conf文件: 我已经检查了我的443端口是否打开并正在监听。 我不知道我哪里做错了任何帮助都将感激不尽
1005:创建表失败 1006:创建数据库失败 1007:数据库已存在,创建数据库失败 1008:数据库不存在,删除数据库失败 1009:不能删除数据库文件导致删除数据库失败 1010:不能删除数据目录导致删除数据库失败 1011:删除数据库文件失败 1012:不能读取系统表中的记录 1020:记录已被其他用户修改 1021:硬盘剩余空间不足,请加大硬盘可用空间 1022:关键字重复,更改记录失败
public static final int ERROR_CODE_SUCCESS = -1; public static final int ERROR_CODE_INTERNAL_ERROR = 0; public static final int ERROR_CODE_INVALID_REQUEST = 1; public static final int ERROR_CODE_NETWO
问题内容: 我有桌子 当我尝试运行此查询时: 错误代码:1292。第1行“ data_apertura”列的日期值错误:“ 01-05-2012” * 我要改变什么?(我试图将格式的日期从gg / mm / yyyy更改为gg-mm-yyyy,但未进行任何更改) 问题答案: 以以下格式示例插入日期,