Answer the question
In order to leave comments, you need to log in
Why does the app only crash on Android P (API 28)?
Hello!
I searched the forum for this topic but didn't find anything similar.
Help to catch the error and solve it please.
The essence of the problem is that the application does not run on the emulator with Android P. On the rest below, it works.
Mistake:
Caused by: android.database.sqlite.SQLiteException: no such table: authors (code 1 SQLITE_ERROR): , while compiling: select a.authorName, Count(p._id) from authors a, poem p where a._id=p.authorID group by a.authorName
...
public class MainActivity extends AppCompatActivity {
private ListView lvAuthorsAndPoems;
private AuthorsAdapter authorsAdapter;
private List<Authors> authorsList;
private DatabaseHelper mDBHelper;
//private AdView adView;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Poems");
lvAuthorsAndPoems = (ListView) findViewById(R.id.lvAuthorsAndPoems);
mDBHelper = new DatabaseHelper(this);
// Check exists database
final File database = getApplicationContext().getDatabasePath(DatabaseHelper.DBNAME);
deleteDatabase(DatabaseHelper.DBNAME);
if (!database.exists()){
mDBHelper.getReadableDatabase();
// Copy db
if(copyDatabase(this)){
//Toast.makeText(this, "",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Ошибка обновления БД!",Toast.LENGTH_SHORT).show();
return;
}
}
// Get Members list when db exists
//poemList = mDBHelper.getListPoem();
authorsList = mDBHelper.getAuthorPoems();
// Initialize adapter
authorsAdapter = new AuthorsAdapter(this, authorsList);
// Set adapter for listview
lvAuthorsAndPoems.setAdapter(authorsAdapter);
lvAuthorsAndPoems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Intent intent = new Intent(MainActivity.this, AuthorPoemsActivity.class);
intent.putExtra("authorName", authorsList.get(position).getAuthorName());
startActivity(intent);
}
});
}
// COPY DATABASE METHOD
private boolean copyDatabase(Context context){
try {
InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME;
/*
DatabaseHelper helper = new DatabaseHelper(this);
SQLiteDatabase database = helper.getWritableDatabase();
String outFileName = database.getPath();
database.close();
*/
OutputStream outputStream = new FileOutputStream(outFileName);
byte[] buff = new byte[1024];
int length = 0;
while ((length = inputStream.read(buff)) > 0){
outputStream.write(buff,0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
Log.v("DBCopyEvent","DB Copied!");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "poems.db";
public static String DBLOCATION="";
public static int DBVERSION=3;
private Context mContext;
public SQLiteDatabase mDatabase;
public DatabaseHelper (Context context){
super(context, DBNAME, null ,DBVERSION);
if (android.os.Build.VERSION.SDK_INT >= 17)
DBLOCATION = context.getApplicationInfo().dataDir + "/databases/";
else
DBLOCATION = "/data/data/" + context.getPackageName() + "/databases/";
this.mContext = context;
}
public void openDatabase(){
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if (mDatabase != null && mDatabase.isOpen()){
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath,null,SQLiteDatabase.OPEN_READWRITE);
this.getWritableDatabase();
}
public void closeDatabase(){
if (mDatabase != null){
mDatabase.close();
}
}
public List<Authors> getAuthorPoems(){
Authors ap = null;
List<Authors> authorsList = new ArrayList<>();
openDatabase();
Cursor cursor = mDatabase.rawQuery("select a.authorName, Count(p._id) from authors a, poem p where a._id=p.authorID group by a.authorName",null);
cursor.moveToFirst();
while (!cursor.isAfterLast()){
ap = new Authors(cursor.getString(0),cursor.getString(1));
authorsList.add(ap);
cursor.moveToNext();
}
cursor.close();
closeDatabase();
return authorsList;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Напомню еще раз, что такая ошибка только на Android P, на остальных все нормально.
Answer the question
In order to leave comments, you need to log in
Problem solved by closing the database when checking for existence:
Added: mDBHelper.close();
// Check exists database
final File database = getApplicationContext().getDatabasePath(DatabaseHelper.DBNAME);
deleteDatabase(DatabaseHelper.DBNAME);
if (!database.exists()){
mDBHelper.getReadableDatabase();
mDBHelper.close();
// Copy db
if(copyDatabase(this)){
//Toast.makeText(this, "",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Ошибка обновления БД!",Toast.LENGTH_SHORT).show();
return;
}
}
Not enough information. The error says that there is no label. Did you check if the database file was copied normally? The fact that the database is opened by a helper means nothing, the openDatabase method creates an empty database if there is no database on the path and if it is possible. Also, you have sugar-coded paths to the database, maybe on Android P they changed the path for the default databases?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question