AndreaF
AndreaF

Reputation: 12385

StringIndexOutOfBoundsException when I try to get SQLite data

When I try to get data from a database SQLite in my Activity with

DataBaseAdapterCars mDbHelper = new DataBaseAdapterCars(this);
        mDbHelper.createDatabase();
        mDbHelper.open();

        Car[] carsList= mDbHelper.getDataDBCarsArray(uso, eta,
        category, class);

I get this error

12-10 17:14:47.069: E/AndroidRuntime(17936): FATAL EXCEPTION: main
12-10 17:14:47.069: E/AndroidRuntime(17936): java.lang.StringIndexOutOfBoundsException
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ContextImpl.validateFilePath(ContextImpl.java:1649)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:555)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.db.DataBaseHelper.createDataBase(DataBaseHelper.java:36)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.db.DataBaseAdapterCars.createDatabase(DataBaseAdapterCars.java:42)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.Cars.initializeData(Cars.java:111)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.Cars$MyAsync$1.run(Cars.java:156)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Handler.handleCallback(Handler.java:587)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Looper.loop(Looper.java:130)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ActivityThread.main(ActivityThread.java:3687)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at java.lang.reflect.Method.invokeNative(Native Method)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at java.lang.reflect.Method.invoke(Method.java:507)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at dalvik.system.NativeStart.main(Native Method)

My DataBaseAdapterCars class is

public class DataBaseAdapterCars {

    protected static final String TAG = "DataAdapter";

    private final Context mContext;
    private SQLiteDatabase mDb;
    private DataBaseHelper mDbHelper;
    static String currentDBName;

    String language;

    public DataBaseAdapterCars(Context context) {
        this.mContext = context;
        currentDBName = "CarInfo";
        mDbHelper = new DataBaseHelper(mContext, currentDBName);
        String lang = Locale.getDefault().getLanguage();
        if (lang.equals("es_ES")) {
            language = "ES";
        } else {
            language = "EN";
        }
    }

    public DataBaseAdapterCars createDatabase() throws SQLException {
        try {
            mDbHelper.createDataBase();
        } catch (IOException mIOException) {
            Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
            throw new Error("UnableToCreateDatabase");
        }
        return this;
    }

    public DataBaseAdapterCars open() throws SQLException {
        try {
            mDbHelper.openDataBase();
            mDbHelper.close();
            mDb = mDbHelper.getReadableDatabase();
        } catch (SQLException mSQLException) {
            Log.e(TAG, "open >>" + mSQLException.toString());
            throw mSQLException;
        }
        return this;
    }

    public void close() {
        mDbHelper.close();
    }

    public Cursor getData(String uso, String eta, String category,
            String class) {
        try {
            Cursor c;
            if (class.equals(null) && category.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else if (class.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Tipo LIKE \"" + category
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else if (category.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Certification LIKE \"" + class
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Tipo LIKE \"" + category
                        + "\" AND Certification LIKE \"" + class
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            }
            if (c != null) {
                c.moveToNext();
            }
            return c;
        } catch (SQLException mSQLException) {
            Log.e(TAG, "getDataCar >>" + mSQLException.toString());
            throw mSQLException;
        }

    }

    public Car[] getDataDBCarsArray(String uso, String eta,
            String category, String class) {
        ArrayList<Car> list = new ArrayList<Car>();
        Cursor c = getData(uso, eta, category, class);
        try {
            if (c.moveToFirst()) {
                do {
                    Car n = new Car(c.getString(0), c.getString(1),
                            c.getString(2), c.getString(3), c.getString(4),
                            c.getString(5), c.getString(6), c.getString(7),
                            c.getString(8), c.getString(9), c.getString(10),
                            c.getString(11), c.getString(12), c.getString(13));
                    list.add(n);
                } while (c.moveToNext());
            }
        } catch (SQLiteException e) {
            Log.d("SQL Error", e.getMessage());
            return null;
        } finally {
            c.close();
            mDb.close();
        }

        Car[] listArray = list.toArray(new Car[list.size()]);
        return listArray;
    }


}

The DB table has 14 columns and the Object Car has 14 String parameters.

What is wrong?

The DataBaseHelper class is

public class DataBaseHelper extends SQLiteOpenHelper {
    private static String TAG = "DataBaseHelper"; // Tag just for the LogCat
                                                    // window
    // destination path (location) of our database on device
    private static String DB_PATH = "";
    private static String DB_NAME = "";// Database name
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context, String nomeDB) {
        super(context, DB_NAME, null, 1);// 1? its Database Version
        DB_NAME = nomeDB;
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;
    }

    public void createDataBase() throws IOException {
        // If database not exists copy it from the assets

        boolean mDataBaseExist = checkDataBase();
        if (!mDataBaseExist) {
            this.getReadableDatabase();
            this.close();
            try {
                // Copia il database dalla cartella assests
                copyDataBase();
                Log.e(TAG, "createDatabase database created");
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    // Controlla Che il database esista
    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        // Log.v("dbFile", dbFile + "   "+ dbFile.exists());
        return dbFile.exists();
    }

    // Copia il database dalla cartella assests
    private void copyDataBase() throws IOException {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream mOutput = new FileOutputStream(outFileName);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0) {
            mOutput.write(mBuffer, 0, mLength);
        }
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    // Apre il database, cosi da poter eseguire le query
    public boolean openDataBase() throws SQLException {
        String mPath = DB_PATH + DB_NAME;
        // Log.v("mPath", mPath);
        mDataBase = SQLiteDatabase.openDatabase(mPath, null,
                SQLiteDatabase.CREATE_IF_NECESSARY);
        // mDataBase = SQLiteDatabase.openDatabase(mPath, null,
        // SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

Upvotes: 0

Views: 1233

Answers (1)

user
user

Reputation: 87064

The exception comes from the way you instantiate the DataBaseHelper class, most exactly, in its constructor you do:

//...
private static String DB_NAME = "";// Database name
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context, String nomeDB) {
        super(context, DB_NAME, null, 1);// 1? its Database Version
        DB_NAME = nomeDB;
//...

As you see when you call the super constructor you pass DB_NAME which is an empty String at that moment. At some point you call the createDatabase() database of the DataBaseHelper class in which you call: this.getReadableDatabase();. This will trigger some initialization regarding the database which will fail with that exception because you pass an empty String as the database name.

Even so, your code is kind of messy, using the SQliteOpenHelper and also copying the database from assets. If you plan to bundle a database with your app(in the assets) then maybe you would want to consider this library which will make your life much easier.

Upvotes: 6

Related Questions