Я также просматривал этот вопрос: проблема с базой данных sqlite, такой таблицы нет:
но не удалось решить проблему.
Как упоминается в заголовке, точно такой же код был в состоянии нормально работать на эмуляторе (отображает таблицу), но встречается исключение, так как на устройстве не найдено "такой таблицы". Использование HTC Desire Z Android версии 2.2.1
Я в основном следовал этому уроку: http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
Идея заключается в том, чтобы скопировать предварительно загруженную базу данных в каталог, который приложение Android будет использовать для внесения изменений, а затем скопировать на SD-карту при вызове сохранения. Однако, хотя копия из папки активов в каталог базы данных приложения работает нормально, а копия на SD-карту работает нормально (проверено путем открытия файла db, скопированного на карту sd с помощью браузера sqlite), при попытке отобразить базу данных на устройстве вызывает у меня проблемы, в то время как у меня не было проблем с эмулятором.
вот код для помощника базы данных:
public class DatabaseHelper extends SQLiteOpenHelper{
private static String DB_PATH = "/data/data/com.mko.preloaddb/databases/";
private static String DB_NAME = "preloaddb";
private SQLiteDatabase myDB;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/**
* Creates DB by copying over DB from assets if it doesn't exist yet
* @throws IOException
*/
public void createDatabase() throws IOException{
boolean dbExist = checkDatabase();
if(dbExist){
Log.e("DatabaseHelper","database exists");
}else{
this.getReadableDatabase().close();
try{
//copy preloaded db from assets if it doesn't exist yet
copyDatabase();
}catch(IOException e){
throw new Error("Error copying database");
}
}
}
public void openDatabase() throws SQLException{
//open the database
String myPath = DB_PATH + DB_NAME;
myDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
/***
* Copies preloaded db from assets
* @throws IOException
*/
private void copyDatabase() throws IOException{
//Open local db as input steam
InputStream myInput = myContext.getAssets().open(DB_NAME);
//Path to just created empty db
String outFileName = DB_PATH + DB_NAME;
//open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while((length = myInput.read(buffer))>0){
myOutput.write(buffer,0,length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
private boolean checkDatabase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database doesn't exist yet, so checkDB will be null
}
if(checkDB !=null){
checkDB.close();
}
return checkDB !=null ? true : false;
}
}
А вот код активности, которая его вызывает:
public class PreloadDBTestActivity extends Activity {
/** Called when the activity is first created. */
Application myApp;
DatabaseHelper myDbHelper;
SQLiteDatabase myDb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myApp = this.getApplication();
myDbHelper = new DatabaseHelper(this);
setContentView(R.layout.main);
}
public void refreshViewTable(View v){
TableLayout tl = (TableLayout)findViewById(R.id.tbl_dbview);
if(myDb==null || !myDb.isOpen()){
openDB(null);
}
String[] result_columns = new String[]{"_id","baseclassname","basehealth"};
Cursor allRows = myDb.query(true, "baseclasses", result_columns, null, null, null, null, null, null);
if(allRows.moveToFirst()){
do{
String classname = allRows.getString(1);
TableRow curr = new TableRow(this);
TextView text = new TextView(this);
text.setText(classname);
curr.addView(text);
tl.addView(curr);
}while(allRows.moveToNext());
}
}
public void openDB(View v){
TextView tv = (TextView)findViewById(R.id.lbl_debug);
try{
myDbHelper.createDatabase();
}catch (IOException ioe){
throw new Error("Unable to create database");
}
try{
myDb = myDbHelper.getWritableDatabase();
}catch(SQLiteException e){
tv.setText("Unable to open writable database");
}
Toast.makeText(this, "Successful open, copy should work", Toast.LENGTH_LONG).show();
}
public boolean copyDbToSd(View v){
File dbfile = new File(Environment.getDataDirectory()+"/data/com.mko.preloaddb/databases/preloaddb");
File exportDir = new File(Environment.getExternalStorageDirectory(),"/exampledata/example");
TextView tv = (TextView)findViewById(R.id.lbl_debug);
if(myDb.isOpen()){
myDb.close();
}
if(!exportDir.exists()){
boolean success = exportDir.mkdirs();
tv.setText("Making dir");
if(success){
Toast.makeText(this, "Success expor dir !"+exportDir.getAbsolutePath(), Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "No success expor dir =("+exportDir.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
}
if(!dbfile.exists()){
tv.setText("Database file does not exist or wrong directory "+dbfile.getAbsolutePath());
}else{
tv.setText("Database file found! " +dbfile.getAbsolutePath());
}
File file = new File(exportDir,dbfile.getName());
try{
file.createNewFile();
if(!file.exists()){
Toast.makeText(this, "DestinationFile does not exist!", Toast.LENGTH_LONG).show();
}
this.copyfile(dbfile, file);
return true;
}catch (IOException e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
Log.e("Preload", e.getMessage(), e);
return false;
}
}
private void copyfile(File src, File dst) throws IOException{
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();
try{
inChannel.transferTo(0, inChannel.size(), outChannel);
}finally{
if(inChannel!=null){
inChannel.close();
}
if(outChannel!=null){
outChannel.close();
}
}
}
private boolean isExternalStorageAvail(){
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
На всякий случай, если это сбивает с толку, я привязал методы «openDB», «copyDbToSd» и «refreshViewTable» к кнопкам на графическом интерфейсе, и я нажимал кнопки в порядке «openDB», «refreshViewTable» и « copyDBToSd "