Home » Android » App crashing SQLlite DBhandler

App crashing SQLlite DBhandler

Posted by: admin November 1, 2017 Leave a comment

Questions:

my app is crashing I am trying to read a prebuilt db and load in the columns from there but currently, it crashes on launch and think it has something to do with my DHhandler and how it’s setting up GetJobList but I am pretty new to Android and programming in General so I’m not entirely sure

DBhandler is Below

package com.example.joelg.clapp;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

/**
 * Created by joelg on 22/10/2017.
 */

public class IntDataBaseHelper extends SQLiteOpenHelper{

private static String DB_PATH ="C:\Users\joelg\AndroidStudioProjects\CLAPP\app\build\intermediates\assets";
private static String DB_NAME = "JobList";
private static String DB_COLUMN = " JobNM";
private static String DB_TABLE = "Job";
private static String DB_JOB_IS_DONE = "JobComplete";
private SQLiteDatabase JobListDatabase;
private final Context jobContext;



/**
 * constructor t
 */



public IntDataBaseHelper (Context context) {

    super (context, DB_NAME,null, 1);
    this.jobContext = context;
  }

  public void createDataBase() throws IOException {
     boolean dbExist = checkDataBase();
     if(dbExist){
         //do nothing database already exists
     }else{

         // calling this method will create an empty database
         this.getReadableDatabase();
         try {
             copyDataBase();
         } catch (IOException e){
             throw new Error("Error copying database");
         }

     }
 }

 // check if database exists to avoid recopying it
private boolean checkDataBase (){
    SQLiteDatabase checkDB = null;
    try{
        String JobListPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(JobListPath, null, 
SQLiteDatabase.OPEN_READONLY);
    }catch(SQLiteException e){
        // database doesnt exist yet
    }

    if(checkDB !=null){
        checkDB.close();
}
return checkDB !=null ? true : false;
}
// copies db from local assets file, were it can be accessed and handled
private void copyDataBase() throws IOException {
    // open local database as the input stream
    InputStream JobInput = jobContext.getAssets().open(DB_NAME);

   // path to the just created empty database
    String OutFileName = DB_PATH + DB_NAME;

    // open the empty db as the output stra,
    OutputStream myOutPut = new FileOutputStream(OutFileName);

    // transfer bytes from the input file to the output file
    byte[] buffer = new byte[1024];
    int length;
    while ((length = JobInput.read(buffer))>0){
        myOutPut.write(buffer,0,length);


    }
    myOutPut.flush();
    myOutPut.close();
    JobInput.close();
}
public void openDataBase() throws SQLiteException {

    // open the database
    String JobListPath = DB_PATH+DB_NAME;
    JobListDatabase = 
SQLiteDatabase.openDatabase(JobListPath,null,SQLiteDatabase.OPEN_READONLY);

}
// Getting Job Count
public ArrayList<String> getJobList() {
    ArrayList<String> JobList = new ArrayList<>();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor =  db.query(DB_TABLE,new String[]
 {DB_COLUMN},null,null,null,null,null);
    while(cursor.moveToNext()){
        int index = cursor.getColumnIndex(DB_COLUMN);
        JobList.add(cursor.getString(index));
    }
    cursor.close();
    db.close();
    return JobList;
 }


@Override
public synchronized void close(){

    if(JobListDatabase !=null){
        JobListDatabase.close();

        super.close();
    }



}
@Override
public  void onCreate(SQLiteDatabase db) {

}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}


}

here is the logcat output

 10-24 03:07:05.081 11072-11072/com.example.joelg.clapp E/SQLiteLog: (1) no such table: job
10-24 03:07:05.084 11072-11072/com.example.joelg.clapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: com.example.joelg.clapp, PID: 11072
                                                                         java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.joelg.clapp/com.example.joelg.clapp.MainActivity}: android.database.sqlite.SQLiteException: no such table: job (code 1): , while compiling: SELECT  jobNM FROM job
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                                                                             at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:105)
                                                                             at android.os.Looper.loop(Looper.java:164)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                                          Caused by: android.database.sqlite.SQLiteException: no such table: job (code 1): , while compiling: SELECT  jobNM FROM job
                                                                             at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                             at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                             at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                             at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                             at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                             at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                             at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                             at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
                                                                             at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1165)
                                                                             at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1036)
                                                                             at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1204)
                                                                             at 

 com.example.joelg.clapp.IntDataBaseHelper.getJobList(IntDataBaseHelper.java:128)
                                                                         at 
 com.example.joelg.clapp.MainActivity.onCreate(MainActivity.java:46)
                                                                         at 
 android.app.Activity.performCreate(Activity.java:6975)
                                                                         at 
 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                                                                         at 
 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                                                                         at 
 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
                                                                         at 
 android.app.ActivityThread.-wrap11(Unknown Source:0) 
                                                                         at 
 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                                         at 
 android.os.Handler.dispatchMessage(Handler.java:105) 
                                                                         at 
 android.os.Looper.loop(Looper.java:164) 
                                                                         at 
 android.app.ActivityThread.main(ActivityThread.java:6541) 
                                                                         at 
 java.lang.reflect.Method.invoke(Native Method) 
                                                                         at 
 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                                                                         at 
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

here is the location of the job db file

enter image description here
Here is the latest error logcat

                                                   [ 10-24 05:22:39.920  
1508: 
2079 D/         ]

SurfaceInterface::setAsyncMode: set async mode 1
10-24 05:22:39.925 1611-1631/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:39.925 1611-1631/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:39.925 1611-1631/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:39.938 1611-1631/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:40.523 1611-1628/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:40.523 1611-1628/? E/ResourcesManager: failed to add asset path 
/data/app/com.example.joelg.clapp-0JSJFIAy0bMCNOuIEgUs3g==/base.apk
10-24 05:22:42.973 1508-1598/? E/TaskPersister: File error accessing recents 
directory (directory doesn't exist?).
10-24 05:22:53.636 1508-1598/? E/TaskPersister: File error accessing recents 
directory (directory doesn't exist?).
10-24 05:22:54.924 1508-1521/? E/memtrack: Couldn't load memtrack module
10-24 05:23:26.999 1508-1521/? E/memtrack: Couldn't load memtrack module
10-24 05:23:27.010 1508-1521/? E/memtrack: Couldn't load memtrack module
10-24 05:23:39.285 1508-1525/? E/BatteryStatsService: modem info is invalid: 
`ModemActivityInfo{ mTimestamp=0 mSleepTimeMs=0 mIdleTimeMs=0 mTxTimeMs[]=
[0, 0, 0, 0, 0] mRxTimeMs=0 mEnergyUsed=0}`
10-24 05:23:43.109 1508-1521/? E/memtrack: Couldn't load memtrack module
10-24 05:24:00.005 1508-1521/? E/memtrack: Couldn't load memtrack module

latest logcat output

10-24 12:01:30.319 2669-2669/? E/SQLiteLog: (14) cannot open file at line 35648 of [036ebf729e]
10-24 12:01:30.319 2669-2669/? E/SQLiteLog: (14) os_unix.c:35648: (2) open(/data/user/0/com.example.joelg.clapp/databases/JobList) - 
10-24 12:01:30.320 2669-2669/? E/SQLiteDatabase: Failed to open database '/data/user/0/com.example.joelg.clapp/databases/JobList'.
                                                 android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
                                                     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
                                                     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
                                                     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)
                                                     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
                                                     at com.example.joelg.clapp.CopyDBFromAssets.checkDataBase(CopyDBFromAssets.java:94)
                                                     at com.example.joelg.clapp.CopyDBFromAssets.createDataBase(CopyDBFromAssets.java:25)
                                                     at com.example.joelg.clapp.MainActivity.onCreate(MainActivity.java:25)
                                                     at android.app.Activity.performCreate(Activity.java:6975)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                                                     at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                                                     at android.os.Handler.dispatchMessage(Handler.java:105)
                                                     at android.os.Looper.loop(Looper.java:164)
                                                     at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
10-24 12:01:30.322 2669-2669/? E/CHECKASSET: Asset JobListcould not be found. Assets that exists are:-  CleanIngListTemplate.db.sqbpro JobList.db JobList.db.sqbpro JobList.sqbpro images webkit
10-24 12:01:30.322 2669-2669/? E/CREATEDB: Error getting asset JobList
10-24 12:01:30.325 2669-2669/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: com.example.joelg.clapp, PID: 2669
                                                 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.joelg.clapp/com.example.joelg.clapp.MainActivity}: java.lang.RuntimeException: No Usable Database exists or was copied from the assets.
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                                                     at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                                                     at android.os.Handler.dispatchMessage(Handler.java:105)
                                                     at android.os.Looper.loop(Looper.java:164)
                                                     at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                  Caused by: java.lang.RuntimeException: No Usable Database exists or was copied from the assets.
                                                     at com.example.joelg.clapp.MainActivity.onCreate(MainActivity.java:34)
                                                     at android.app.Activity.performCreate(Activity.java:6975)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
                                                     at android.app.ActivityThread.-wrap11(Unknown Source:0) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:105) 
                                                     at android.os.Looper.loop(Looper.java:164) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:6541) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
Answers:

In response to the issues according to the comments.

1) It is vital that the file copied into the assets folder has the exact same name as the database. So if the database is to be called JobList, then that must be the file name in the assets folder.

2) Before I get to the code, a little bit of an explanation of the confusion. This was a double whammy if things weren’t exactly right. That is no matter what the situation a Database would be created. First the single line this.getReadableDatabase(); in the createDatabase method of the IntDataBaseHelper would run if the database didn’t exist. However, addtitonally even if this were’t to run (e.g. commented out) as you have create an instance of the IntDataBaseHelper class then any attempt to open the database would also try to create it. In the absence of code in the onCreate method the result would be an empty database with effectively no tables *(tables sqlite_master and android_metadata would exist, but they are system type tables)**

As such I’ve decided to split the create/copy of the database away from the DBHelper as well as hopefully making the code issue more descriptive messages.

So the code that I suggest you use.

First there is a new class which I’ve called CopyDBFromAssets. This is basically the code from the IntDatabaseHelper but written in a more long winded way. There is a new method checkAssetExists, which by it’s name should be self-explanatory regrading it’s use.

The invoking MainActivity is a little different. Instead of getting an instance of IntDatabaseHelper. The code initially calls the createDatabase method in the new CopyDBFromAssets class, which returns a boolean.

  • true if all is OK (with a caveat regarding file flush and close, perhaps it should also return false if there is an exception in these).
  • false if things aren’t as should be, in which case a runtime exception is issued.

If true then an Instance of IntDatabaseHelper is created and all should be fine.

CopyDBFromAssets

1) Create a new class CopyDBFromAssets.java and then copy in the following code :-

public class CopyDBFromAssets {

    boolean copied = false;

    public static boolean createDataBase(Context context, String databasename) {

        boolean copied = false;

        boolean dbExist = checkDataBase(context, databasename);

        if(!dbExist) {

            // calling this method will create an empty database
            // which will hopefully be overidden, if not then
            // empty database will exist ?????????
            //this.getReadableDatabase(); <<<<< NOTE Commented out as empty db with no tables is useless
            if (!checkAssetExists(context, databasename, "")) {
                Log.e("CREATEDB", "Error getting asset " + databasename);
            } else {
                 return copyDataBase(context, databasename);
            }
            return false;
        }
        return true;
    }


    private static boolean checkAssetExists(Context context, String assetfile, String path) {
        boolean rv = false;     // assume asset file doesn't exist
        String[] assetsfound = new String[]{};
        // Get the list of assets at the given path

        try {
            assetsfound = context.getAssets().list(path);
        } catch (IOException e) {
            Log.e("CHECKASSET","IO Exception when checking for the asset file." + e.getMessage());
            return false;
        }
        // Check to see if the desired asset (passed assetfile) exists
        for (String s: assetsfound) {
            if (s.equals(assetfile)) {
                rv = true;
                break;
            }
        }
        if (rv) {
            Log.d("CHECKASSET", "Asset " + assetfile + "was found.");
        } else {
            String assetlist = "";
            for (String s: assetsfound) {
                assetlist = assetlist + " " + s;
            }
            Log.e("CHECKASSET", "Asset " + assetfile +
                    "could not be found. Assets that exists are:- " +
                    assetlist
            );
        }
        // Asset not found lets try ignoring case
        if (!rv) {
            for (String s: assetsfound) {
                if ((s.toLowerCase()).equals(assetfile.toLowerCase())) {
                    Log.e("CHECKASSET","Found asset as " + assetfile +
                            " but looking for " + s +
                            ", although they are similar the case is different."
                    );
                }
            }
        }
        return rv;
    }

    // check if database exists to avoid recopying it
    private static boolean checkDataBase (Context context, String database){
        SQLiteDatabase checkDB = null;
        String dbpath = context.getDatabasePath(database).getPath();

        try{
            checkDB = SQLiteDatabase.openDatabase(dbpath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch(SQLiteException e){
            // database doesnt exist yet
        }

        if(checkDB !=null){
            checkDB.close();
        }
        return checkDB !=null ? true : false;
    }
    // copies db from local assets file, were it can be accessed and handled
    private static boolean copyDataBase(Context context, String  databasename)  {

        InputStream asset;
        OutputStream db;
        int bytescopied = 0;
        int length_read;
        int buffersize = 16384;
        int blockcount = 0;
        boolean rv = false;

        try {
            asset = context.getAssets().open(databasename);
        } catch (IOException e) {
            Log.e("COPYDB",
                    "IO Error opening the asset " +
                            databasename +
                            ". Error Message was " +
                            e.getMessage()
            );
            return false;
        }

        try {
            db = new FileOutputStream(context.getDatabasePath(databasename).getPath());
        }  catch (IOException e) {
            Log.e("COPYDB",
                    "IO Error opening the output file for the database with path " +
                            databasename +
                            ". error Message was " +
                            e.getMessage()
            );
            try {
                asset.close();
            } catch (IOException e2) {
                Log.e("COPYDB",
                        "IO Error closing the asset. Message was " + e2.getMessage()
                );
            }
            return false;
        }

        byte[] buffer = new byte[buffersize];
        try {
            while ((length_read = asset.read(buffer)) > 0) {
                db.write(buffer);
                bytescopied = bytescopied + length_read;
                blockcount++;
                rv = true;
            }
        } catch (IOException e) {
            Log.e("COPYDB",
                    "IO Error Copying Database. Bytes Copied = "
                            + bytescopied +
                            " in " +
                            blockcount +
                            " blocks of " +
                            buffersize
            );
        }
        Log.d("COPYDB","Succesfully copied Database " + databasename + " from the assets." +
                " Number of bytes copied = " + bytescopied +
                " in " + blockcount + " blocks of length " + buffersize
        );
        try {
            db.flush();
            db.close();
            asset.close();
        } catch (IOException e) {
            Log.e("COPYDB",
                    "IO Error flushing or closing Database or closing asset."
            );
        }
        return rv;
    }
}

IntDataBaseHelper

This is a slimmed down version, one thing to note is that DB_NAME, DB_COLUMN and DB_TABLE have been changed to be public static final (as they are used elsewhere).

here’s the code :-

public class IntDataBaseHelper extends SQLiteOpenHelper {
    private static String DB_PATH ="C:\Users\joelg\AndroidStudioProjects\CLAPP\app\build\intermediates\assets";
    public static final String DB_NAME = "JobList";
    public static final String DB_COLUMN = "JobNM";
    public static final String DB_TABLE = "Job";
    private static String DB_JOB_IS_DONE = "JobComplete";
    private SQLiteDatabase JobListDatabase;
    private final Context jobContext;

    /**
     * constructor t
     */
    public IntDataBaseHelper (Context context) {

        super (context, DB_NAME,null, 1);
        this.jobContext = context;
        DB_PATH = jobContext.getDatabasePath(DB_NAME).getPath();
    }

    public void openDataBase() {
        // open the database
        String JobListPath = DB_PATH;
        JobListDatabase =
                SQLiteDatabase.openDatabase(JobListPath,null,SQLiteDatabase.OPEN_READONLY);
    }

    // Getting Job Count
    public ArrayList<String> getJobList() {
        ArrayList<String> JobList = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor =  db.query(DB_TABLE,new String[]
                {DB_COLUMN},null,null,null,null,null);
        while(cursor.moveToNext()){
            int index = cursor.getColumnIndex(DB_COLUMN);
            JobList.add(cursor.getString(index));
        }
        cursor.close();
        db.close();
        return JobList;
    }

    @Override
    public synchronized void close(){

        if(JobListDatabase !=null){
            JobListDatabase.close();

            super.close();
        }
    }
    @Override
    public  void onCreate(SQLiteDatabase db) {

    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

MainActivty

This is just example code of using the above, note that if the database can’t be created if it doesn’t exist then a runtime exception will be issued (examples will follow) :-

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the database (only if it doesn't exists)
        // does so by copying from the assets
        if (CopyDBFromAssets.createDataBase(this,IntDataBaseHelper.DB_NAME)) {
            IntDataBaseHelper myhelper = new IntDataBaseHelper(this);

            // Get the data from the database
            ArrayList<String> jobs = myhelper.getJobList();
            for (String s: jobs) {
                Log.d("TESTDB","Found Job " + s);
            }
        } else {
            throw new RuntimeException("No Usable Database exists or was copied from the assets.");
        }
    }
}

Run Example 1 (no asset file found)

So first let’s assume that the file in the assets folder is name Job not JobList (or anything other than JobList) assuming the App has just been installed. Then running the above will result in something along the lines of:-

The assets folder as per Windows explorer:-

enter image description here

10-24 20:31:04.994 2346-2346/? E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
10-24 20:31:04.994 2346-2346/? E/SQLiteLog: (14) os_unix.c:30046: (2) open(/data/data/mjt.joblist/databases/JobList) - 
10-24 20:31:04.994 2346-2346/? E/SQLiteDatabase: Failed to open database '/data/data/mjt.joblist/databases/JobList'.
                                                 android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
                                                     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
                                                     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
                                                     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
                                                     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
                                                     at mjt.joblist.CopyDBFromAssets.checkDataBase(CopyDBFromAssets.java:93)
                                                     at mjt.joblist.CopyDBFromAssets.createDataBase(CopyDBFromAssets.java:25)
                                                     at mjt.joblist.MainActivity.onCreate(MainActivity.java:18)
                                                     at android.app.Activity.performCreate(Activity.java:5990)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                     at android.os.Looper.loop(Looper.java:135)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-24 20:31:05.004 2346-2346/? E/CHECKASSET: Asset JobListcould not be found. Assets that exists are:-  Job images sounds webkit
10-24 20:31:05.004 2346-2346/? E/CREATEDB: Error getting asset JobList
10-24 20:31:05.004 2346-2346/? D/AndroidRuntime: Shutting down VM


                                                 --------- beginning of crash
10-24 20:31:05.004 2346-2346/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: mjt.joblist, PID: 2346
                                                 java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.joblist/mjt.joblist.MainActivity}: java.lang.RuntimeException: No Usable Database exists or was copied from the assets.
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                     at android.os.Looper.loop(Looper.java:135)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                  Caused by: java.lang.RuntimeException: No Usable Database exists or was copied from the assets.
                                                     at mjt.joblist.MainActivity.onCreate(MainActivity.java:27)
                                                     at android.app.Activity.performCreate(Activity.java:5990)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:151) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                     at android.os.Looper.loop(Looper.java:135) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at java.lang.reflect.Method.invoke(Method.java:372) 
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
10-24 20:31:05.008 738-1262/? W/ActivityManager:   Force finishing activity 1 mjt.joblist/.MainActivity

The following lines detail the issue:-

10-24 20:31:05.004 2346-2346/? E/CHECKASSET: Asset JobListcould not be found. Assets that exists are:-  Job images sounds webkit
10-24 20:31:05.004 2346-2346/? E/CREATEDB: Error getting asset JobList

That is JobList could not be found, the assets found are Job (wrongly named) images, sounds and webkit (last three nothing to do with this).

As does the runtime exception (2nd) as per :-

java.lang.RuntimeException: Unable to start activity ComponentInfo{mjt.joblist/mjt.joblist.MainActivity}: java.lang.RuntimeException: No Usable Database exists or was copied from the assets.

RunExample 2 – The assets file is correctly named :-

enter image description here

The log shows :-

10-24 20:43:01.160 8696-8696/? E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
10-24 20:43:01.160 8696-8696/? E/SQLiteLog: (14) os_unix.c:30046: (2) open(/data/data/mjt.joblist/databases/JobList) - 
10-24 20:43:01.162 8696-8696/? E/SQLiteDatabase: Failed to open database '/data/data/mjt.joblist/databases/JobList'.
                                                 android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
                                                     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
                                                     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
                                                     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
                                                     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
                                                     at mjt.joblist.CopyDBFromAssets.checkDataBase(CopyDBFromAssets.java:93)
                                                     at mjt.joblist.CopyDBFromAssets.createDataBase(CopyDBFromAssets.java:25)
                                                     at mjt.joblist.MainActivity.onCreate(MainActivity.java:18)
                                                     at android.app.Activity.performCreate(Activity.java:5990)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                     at android.os.Looper.loop(Looper.java:135)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-24 20:43:01.169 8696-8696/? D/CHECKASSET: Asset JobListwas found.
10-24 20:43:01.175 8696-8696/? D/COPYDB: Succesfully copied Database JobList from the assets. Number of bytes copied = 98304 in 6 blocks of length 16384
10-24 20:43:01.204 8696-8696/? D/TESTDB: Found Job Job001
10-24 20:43:01.204 8696-8696/? D/TESTDB: Found Job Job002
10-24 20:43:01.204 8696-8696/? D/TESTDB: Found Job Job003
10-24 20:43:01.204 8696-8696/? D/TESTDB: Found Job Job004

An exception is raised (Database not found, as when check if it exists), but it doesn’t crash and we see that JobList was found and that 98304 bytes were copied in 6 blocks of 16k.

We then see the data in the database, this obtained via the DBHelper method.


Run 3 – A subsequent run :-

Just :-

10-24 20:52:34.944 13879-13879/? D/TESTDB: Found Job Job001
10-24 20:52:34.944 13879-13879/? D/TESTDB: Found Job Job002
10-24 20:52:34.944 13879-13879/? D/TESTDB: Found Job Job003
10-24 20:52:34.944 13879-13879/? D/TESTDB: Found Job Job004

Questions:
Answers:

As per my comment you appear to be specifying the Windows path to the Assets folder, the device/emulator will not know about this. Rather when the App is built and installed the assets will be included and placed in the assets file within the devices /data/data/.

e.g.

Looking from Windows :-

enter image description here

After Build and Run and looking at Android Device :-

enter image description here

Code in the App to access the database being :-

    final String DBNAME = "books.sqlpro";
    final String DBPATH = this.getDatabasePath(DBNAME).getPath();
    final String TBNAME = "books";
    final String AUTHOR_COL = "author";
    String outfilename = DBPATH + DBNAME;
    SQLiteDatabase booksdb;

    try {
        booksdb = SQLiteDatabase.openDatabase(outfilename, null, SQLiteDatabase.OPEN_READONLY);
    } catch (Exception e) {
        try {
            InputStream is = this.getAssets().open(DBNAME);
            OutputStream os = new FileOutputStream(outfilename);

            byte[] buffer = new byte[32768];
            int length;
            while ((length = is.read(buffer)) > 0) {
                os.write(buffer);
            }
            is.close();
            os.flush();
            os.close();

        } catch (IOException io) {
            io.printStackTrace();
        }
        try {
            booksdb = SQLiteDatabase.openDatabase(outfilename, null, SQLiteDatabase.OPEN_READONLY);
        } catch (Exception e2) {
            e2.printStackTrace();
            return;
        }
    }
    Cursor csr = booksdb.query(TBNAME, null, null, null, null, null, null);

Noting that in the above this.getAssets().open(DBNAME); which gets the path.

In the above the database is copied from the assets to the standard/default database location before being used, but only if the attempt to open the database fails (very likely indicating that it doesn’t exist).

Edit

As you are having problems here’s some full working code:-

First the DBHelper :-

public class IntDataBaseHelper extends SQLiteOpenHelper {
    private static String DB_PATH ="C:\Users\joelg\AndroidStudioProjects\CLAPP\app\build\intermediates\assets";
    private static String DB_NAME = "JobList";
    private static String DB_COLUMN = "JobNM";
    private static String DB_TABLE = "Job";
    private static String DB_JOB_IS_DONE = "JobComplete";
    private SQLiteDatabase JobListDatabase;
    private final Context jobContext;

    /**
     * constructor t
     */
    public IntDataBaseHelper (Context context) {

        super (context, DB_NAME,null, 1);
        this.jobContext = context;
        DB_PATH = jobContext.getDatabasePath(DB_NAME).getPath();
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if(dbExist){
            //do nothing database already exists
        }else{
            // calling this method will create an empty database
            // which will hopefully be overidden, if not then
            // empty database will exist ?????????
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e){
                throw new Error("Error copying database");
            }
        }
    }

    // check if database exists to avoid recopying it
    private boolean checkDataBase (){
        SQLiteDatabase checkDB = null;
        try{
            String JobListPath = DB_PATH;
            checkDB = SQLiteDatabase.openDatabase(JobListPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch(SQLiteException e){
            // database doesnt exist yet
        }

        if(checkDB !=null){
            checkDB.close();
        }
        return checkDB !=null ? true : false;
    }
    // copies db from local assets file, were it can be accessed and handled
    private void copyDataBase() throws IOException {

        InputStream dbfromassets;
        OutputStream actualdb;
        Boolean copyok = true;
        /*
        try {
            dbfromassets = jobContext.getAssets().open(DB_NAME);
        } catch (IOException e) {
            Log.d("COPYDB","IO Error trying to open the Database in assets folder");
            e.printStackTrace();
            copyok = false;
            return;
        }

        try {
            actualdb = new FileOutputStream(DB_PATH);
        } catch (IOException e) {
            Log.d("COPYDB","IO Error trying to get get output file.");
            e.printStackTrace();
            copyok = false;
            return;
        }
        if (dbfromassets != null && copyok) {
            byte[] buffer = new byte[1024];
            int length;
            int copied = 0;
            while ((length = dbfromassets.read(buffer)) > 0) {
                actualdb.write(buffer);
                copied = copied + length;
            }
            actualdb.flush();
            actualdb.close();
            dbfromassets.close();
            Log.d("COPYDB","Bytes copied " + Integer.toString(copied));
        }
        */


        // open local database as the input stream
        try {
            InputStream JobInput = jobContext.getAssets().open(DB_NAME);

            // path to the just created empty database
            String OutFileName = DB_PATH;

            // open the empty db as the output stra,
            OutputStream myOutPut = new FileOutputStream(OutFileName);

            // transfer bytes from the input file to the output file
            byte[] buffer = new byte[1024];
            int length;
            while ((length = JobInput.read(buffer)) > 0) {
                myOutPut.write(buffer, 0, length);
            }
            myOutPut.flush();
            myOutPut.close();
            JobInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public void openDataBase() throws SQLiteException {

        // open the database
        String JobListPath = DB_PATH;
        JobListDatabase =
                SQLiteDatabase.openDatabase(JobListPath,null,SQLiteDatabase.OPEN_READONLY);
    }

    // Getting Job Count
    public ArrayList<String> getJobList() {
        ArrayList<String> JobList = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor =  db.query(DB_TABLE,new String[]
                {DB_COLUMN},null,null,null,null,null);
        while(cursor.moveToNext()){
            int index = cursor.getColumnIndex(DB_COLUMN);
            JobList.add(cursor.getString(index));
        }
        cursor.close();
        db.close();
        return JobList;
    }


    @Override
    public synchronized void close(){

        if(JobListDatabase !=null){
            JobListDatabase.close();

            super.close();
        }
    }
    @Override
    public  void onCreate(SQLiteDatabase db) {

    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

To test the above I have the following :-
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    IntDataBaseHelper myhelper = new IntDataBaseHelper(this);

    // List assets
    try {
        for (String s: this.getAssets().list("")) {
            Log.d("ASSETS","Found asset (Directory or File) " + s);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        myhelper.createDataBase();
    } catch (IOException e) {
    }

    ArrayList<String> jobs = myhelper.getJobList();
    for (String s: jobs) {
        Log.d("TESTDB","Found Job " + s);
    }
}

}

Results from run when there is no DB (stackTrace from the checkDatabase, but note below this the 4 rows extracted, es expected) :-

10-24 09:13:22.527 5991-5991/? E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
10-24 09:13:22.527 5991-5991/? E/SQLiteLog: (14) os_unix.c:30046: (2) open(/data/data/mjt.joblist/databases/JobList) - 
10-24 09:13:22.530 5991-5991/? E/SQLiteDatabase: Failed to open database '/data/data/mjt.joblist/databases/JobList'.
                                                 android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
                                                     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
                                                     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
                                                     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
                                                     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
                                                     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
                                                     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
                                                     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
                                                     at mjt.joblist.IntDataBaseHelper.checkDataBase(IntDataBaseHelper.java:60)
                                                     at mjt.joblist.IntDataBaseHelper.createDataBase(IntDataBaseHelper.java:39)
                                                     at mjt.joblist.MainActivity.onCreate(MainActivity.java:21)
                                                     at android.app.Activity.performCreate(Activity.java:5990)
                                                     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
                                                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                     at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                     at android.os.Looper.loop(Looper.java:135)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-24 09:13:22.561 5991-5991/? E/SQLiteLog: (1) no such table: Job
10-24 09:13:22.563 5991-5991/? D/TESTDB: Found Job Job001
10-24 09:13:22.563 5991-5991/? D/TESTDB: Found Job Job002
10-24 09:13:22.563 5991-5991/? D/TESTDB: Found Job Job003
10-24 09:13:22.563 5991-5991/? D/TESTDB: Found Job Job004

And from a subsequent run (DB already exists) :-

10-24 09:16:04.884 7433-7433/? D/TESTDB: Found Job Job001
10-24 09:16:04.884 7433-7433/? D/TESTDB: Found Job Job002
10-24 09:16:04.884 7433-7433/? D/TESTDB: Found Job Job003
10-24 09:16:04.884 7433-7433/? D/TESTDB: Found Job Job004

The database with the 4 rows was created outside of the App (I used SQlite Mnaager), the file was then copied into the assets folder (had to create it) in the App/src/main/ directory of the App’s project (using windows explorer).

In SQlite Manager :-

enter image description here