A
A
Andres Iniesta2019-07-27 15:41:08
Java
Andres Iniesta, 2019-07-27 15:41:08

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

Classes in which it throws an error:
...
 
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;
        }
 
    }
 
}

DB class:
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

2 answer(s)
A
Andres Iniesta, 2019-08-01
@nuroraf

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;
            }
        }

D
Denis, 2019-07-29
@akaish

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 question

Ask a Question

731 491 924 answers to any question