0

アクティビティでデータベース SQLite からデータを取得しようとすると、

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

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

このエラーが発生します

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)

私のDataBaseAdapterCarsクラスは

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


}

DB テーブルには 14 の列があり、Object Car には 14 の文字列パラメーターがあります。

なにが問題ですか?

DataBaseHelper クラスは

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

    }

}
4

1 に答える 1

6

例外は、DataBaseHelperクラスをインスタンス化する方法から発生します。最も正確には、そのコンストラクターで行います。

//...
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_NAMEでは空Stringです。ある時点で、呼び出すクラスのcreateDatabase()データベースを呼び出します: . これにより、データベースに関するいくつかの初期化がトリガーされますが、データベース名として空の文字列を渡すため、その例外で失敗します。DataBaseHelperthis.getReadableDatabase();

それでも、 を使用し、SQliteOpenHelperアセットからデータベースをコピーすることで、コードはややこしいものになります。データベースをアプリ (アセット内) にバンドルすることを計画している場合は、このライブラリを検討することをお勧めします。これにより、作業がはるかに簡単になります。

于 2012-12-10T18:04:25.433 に答える