Так что это мой помощник по базе данных, который я использовал довольно долгое время.
public class DatabaseHelper extends SQLiteOpenHelper {
//public static String PACKAGE_NAME;
//The Androids default system path of your application database.
private static String DB_PATH = "/data/data/"+MainActivity.PACKAGE_NAME+"/databases/";
private static String DB_NAME = "fulldb";//name of your Database
File DBFile = new File(DB_PATH, "fulldb");
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 DatabaseHelper(Context context) {
super(context, DB_NAME, null, 3);
this.myContext = context;
}
/**
* 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.getReadableDatabase();
try {
copyDataBase(DBFile);
} 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(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch(SQLiteException e){
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase(File DBFile) throws IOException
{
AssetManager am = myContext.getAssets();
OutputStream os = new FileOutputStream(DBFile);
DBFile.createNewFile();
byte []b = new byte[1024];
int i, r;
String []Files = am.list("");
Arrays.sort(Files);
for(i=1;i<15;i++) //I have definitely less than 10 files; you might have more
{
String fn = String.format("0%d.db", i);
if(Arrays.binarySearch(Files, fn) < 0) //No such file in assets - time to quit the loop
break;
InputStream is = am.open(fn);
while((r = is.read(b)) != -1)
os.write(b, 0, r);
is.close();
}
os.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@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) {
}
}
Это прекрасно работает на моем эмуляторе в версии 27 android. Но в версии 28 я получаю:
2020-03-08 22:03:24.833 6843-6843/com.packagename E/SQLiteLog: (14) cannot open file at line 36667 of [0c55d17973]
2020-03-08 22:03:24.833 6843-6843/com.packagename E/SQLiteLog: (14) os_unix.c:36667: (2) open(/data/data/com.packagename/databases/fulldb) -
2020-03-08 22:03:24.838 6843-6843/com.packagename E/SQLiteDatabase: Failed to open database '/data/data/com.packagename/databases/fulldb'.
и в результате этого получаю
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.packagename/appname.MainActivity}: android.database.sqlite.SQLiteException: no such table:
Я предполагаю, что разные версии android сохраняют базы данных по разным путям, и кажется, что путь должен быть установлен более динамично.
private static String DB_PATH = "/data/data/"+MainActivity.PACKAGE_NAME+"/databases/";
Какие у вас, ребята, догадки? Вы видите какую-либо причину, почему на этой конкретной версии база данных не найдена? Могу ли я сделать путь к базе данных динамическим c, чтобы решить эту проблему?
Спасибо