我正在使用Android应用程序外部数据库,它是在所有模拟器和真正的三星设备的正常工作。但是,当我的宏碁智能手机上的检查,我的应用程序要与下面的异常崩溃:
android.database.sqlite.SQLiteException:没有这样的表:
奇怪的是我。我在文件浏览器在我的数据库和所有表都present数据文件夹下检查。
我没有得到为什么它正在发生。
请指引我。在此先感谢
$ C $ SQL助手类c是如下:
公共类MyDatabaseHelper扩展SQLiteOpenHelper { //应用数据库系统路径。 私人静态字符串DB_PATH = MyApplication.getAppContext() .getFilesDir()。getParentFile()的getPath() +/数据库/; 私人静态字符串DB_NAME =MYDB; 私人SQLiteDatabase MYDATABASE; 私人最终上下文myContext; / ** *构造函数和不断传递的上下文中的一个参考,以 *访问应用程序的资产和资源。 * * @参数方面 * / 公共MyDatabaseHelper(上下文的背景下){ 超级(上下文,DB_NAME,空,1); this.myContext =背景; } / ** *在系统上创建一个空数据库,并与自己的数据库重写它。 * * / 公共无效的CreateDatabase()抛出IOException checkDataBase(); //创建空的数据库默认的系统路径 this.getReadableDatabase(); 尝试{ copyDataBase(); }赶上(IOException异常五){ 抛出新的错误(错误复制数据库); } } / ** *检查是否已存在于数据库,以避免重新复制每个文件 *每当应用程序打开的时间。 * *如果存在返回:真的,假的,如果它不 * / 私人布尔checkDataBase(){ SQLiteDatabase CHECKDB = NULL; 尝试{ 字符串mypath中= DB_PATH + DB_NAME; CHECKDB = SQLiteDatabase.openDatabase(mypath中,空, SQLiteDatabase.OPEN_READONLY); }赶上(SQLiteException E){ e.printStackTrace(); } 如果(CHECKDB!= NULL){ checkDB.close(); } 返回CHECKDB!= NULL?真假; } / ** *副本数据库本地资产文件夹复制到刚创建的空 *数据库系统中的文件夹,并从那里可以访问和 *使用字节流传输处理。 * * / 私人无效copyDataBase()抛出IOException //打开本地数据库的输入流 InputStream的myInput = myContext.getAssets()开(DB_NAME +.db的); //刚刚创建的空分贝的路径 字符串outFileName = DB_PATH + DB_NAME; //打开空分贝的输出流 的OutputStream myOutput =新的FileOutputStream(outFileName); //传递从输入文件到输出文件的字节 字节[]缓冲区=新的字节[1024]; INT长; 而((长度= myInput.read(缓冲液))大于0){ myOutput.write(缓冲液,0,长度); } //关闭流 myOutput.flush(); myOutput.close(); myInput.close(); } 公共SQLiteDatabase的openDatabase()抛出的SQLException { //打开数据库 字符串mypath中= DB_PATH + DB_NAME; 返回SQLiteDatabase.openDatabase(mypath中,空, SQLiteDatabase.OPEN_READONLY); } @覆盖 公共同步无效的close(){ 如果(MYDATABASE!= NULL) myDataBase.close(); super.close(); } @覆盖 公共无效的onCreate(SQLiteDatabase为arg0){ // TODO自动生成方法存根 } @覆盖 公共无效onUpgrade(SQLiteDatabase为arg0,ARG1 INT,INT ARG2){ // TODO自动生成方法存根 }}
解决方案
最后我解决我的问题。
我只是得到可读数据库到数据库中并关闭它刚过再次打开它。我完全code是如下:
公共类MyDatabaseHelper扩展SQLiteOpenHelper { //应用数据库系统路径。 私人静态字符串DB_PATH = MyApplication.getAppContext() .getFilesDir()。getParentFile()的getPath() +/数据库/; 私人静态字符串DB_NAME =MYDB; 私人SQLiteDatabase MYDATABASE; 私人最终上下文myContext; / ** *构造函数和不断传递的上下文中的一个参考,以 *访问应用程序的资产和资源。 * * @参数方面 * / 公共MyDatabaseHelper(上下文的背景下){ 超级(上下文,DB_NAME,空,1); this.myContext =背景; } / ** *在系统上创建一个空数据库,并与自己的数据库重写它。 * * / 公共无效的CreateDatabase()抛出IOException checkDataBase(); SQLiteDatabase db_Read = NULL; //创建空的数据库默认的系统路径 db_Read = this.getReadableDatabase(); db_Read.close(); 尝试{ copyDataBase(); }赶上(IOException异常五){ 抛出新的错误(错误复制数据库); } } / ** *检查是否已存在于数据库,以避免重新复制每个文件 *每当应用程序打开的时间。 * *如果存在返回:真的,假的,如果它不 * / 私人布尔checkDataBase(){ SQLiteDatabase CHECKDB = NULL; 尝试{ 字符串mypath中= DB_PATH + DB_NAME; CHECKDB = SQLiteDatabase.openDatabase(mypath中,空, SQLiteDatabase.OPEN_READONLY); }赶上(SQLiteException E){ e.printStackTrace(); } 如果(CHECKDB!= NULL){ checkDB.close(); } 返回CHECKDB!= NULL?真假; } / ** *副本数据库本地资产文件夹复制到刚创建的空 *数据库系统中的文件夹,并从那里可以访问和 *使用字节流传输处理。 * * / 私人无效copyDataBase()抛出IOException //打开本地数据库的输入流 InputStream的myInput = myContext.getAssets()开(DB_NAME +.db的); //刚刚创建的空分贝的路径 字符串outFileName = DB_PATH + DB_NAME; //打开空分贝的输出流 的OutputStream myOutput =新的FileOutputStream(outFileName); //传递从输入文件到输出文件的字节 字节[]缓冲区=新的字节[1024]; INT长; 而((长度= myInput.read(缓冲液))大于0){ myOutput.write(缓冲液,0,长度); } //关闭流 myOutput.flush(); myOutput.close(); myInput.close(); } 公共SQLiteDatabase的openDatabase()抛出的SQLException { //打开数据库 字符串mypath中= DB_PATH + DB_NAME; 返回SQLiteDatabase.openDatabase(mypath中,空, SQLiteDatabase.OPEN_READONLY); } @覆盖 公共同步无效的close(){ 如果(MYDATABASE!= NULL) myDataBase.close(); super.close(); } @覆盖 公共无效的onCreate(SQLiteDatabase为arg0){ // TODO自动生成方法存根 } @覆盖 公共无效onUpgrade(SQLiteDatabase为arg0,ARG1 INT,INT ARG2){ // TODO自动生成方法存根 }}
我发现我的答案这里:
I am using an external database in android app and it is working fine on all emulators and on samsung real devices. But when I am checking on the Acer smart phone, my application going crash with following exception:
android.database.sqlite.SQLiteException: no such table:
It is strange to me. I have checked under the data folder in file explorer where my databases and all tables are present.
I am not getting why it is happening.
Please guide me. Thanks in advance
Code of sql helper class is as following:
public class MyDatabaseHelper extends SQLiteOpenHelper {
// System path of application database.
private static String DB_PATH = MyApplication.getAppContext()
.getFilesDir().getParentFile().getPath()
+ "/databases/";
private static String DB_NAME = "myDB";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* @param context
*/
public MyDatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with own database.
*
*/
public void createDataBase() throws IOException {
checkDataBase();
// Creates empty database default system path
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
/**
* Checks if the database already exist to avoid re-copying the file each
* time whenever the application opened.
*
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies database from local assets-folder to the just created empty
* database in the system folder and from where it can be accessed and
* handled using byte stream transferring.
*
*/
private void copyDataBase() throws IOException {
// Open local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME + ".db");
// Path of 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 input file to the output file
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 SQLiteDatabase openDataBase() throws SQLException {
// Opens the database
String myPath = DB_PATH + DB_NAME;
return SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
解决方案
Finally I resolved my question.
I just get readable database into the database and close it just after open it again. My complete code is as follows:
public class MyDatabaseHelper extends SQLiteOpenHelper {
// System path of application database.
private static String DB_PATH = MyApplication.getAppContext()
.getFilesDir().getParentFile().getPath()
+ "/databases/";
private static String DB_NAME = "myDB";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* @param context
*/
public MyDatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with own database.
*
*/
public void createDataBase() throws IOException {
checkDataBase();
SQLiteDatabase db_Read = null;
// Creates empty database default system path
db_Read = this.getReadableDatabase();
db_Read.close();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
/**
* Checks if the database already exist to avoid re-copying the file each
* time whenever the application opened.
*
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies database from local assets-folder to the just created empty
* database in the system folder and from where it can be accessed and
* handled using byte stream transferring.
*
*/
private void copyDataBase() throws IOException {
// Open local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME + ".db");
// Path of 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 input file to the output file
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 SQLiteDatabase openDataBase() throws SQLException {
// Opens the database
String myPath = DB_PATH + DB_NAME;
return SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
I found my answer here: