Возникли проблемы с доступом к базе данных - PullRequest
1 голос
/ 04 августа 2011

Я (пере) пишу приложение для Android, которое использует базу данных SQLite для хранения различных элементов, в данный момент я пытаюсь открыть базу данных, но получаю следующую ошибку logcat:

08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.os.Looper.loop(Looper.java:123)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread.main(ActivityThread.java:3691)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at java.lang.reflect.Method.invokeNative(Native Method)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at java.lang.reflect.Method.invoke(Method.java:507)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at dalvik.system.NativeStart.main(Native Method)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793): Caused by: android.database.sqlite.SQLiteException: unable to open database file
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1960)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:887)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at myApps.ShoppingList.Database.openDatabase(Database.java:83)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at myApps.ShoppingList.RoomList.onCreate(RoomList.java:25)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
08-04 13:05:52.735: ERROR/AndroidRuntime(7793):     ... 11 more

Код, который у меня есть на данный момент, довольно неполный, я просто добавляю к нему фрагменты и пытаюсь заставить их работать должным образом, пока ошибки, которые я получаю, не связаны с отсутствующим кодом. (убедитесь, что код, который у меня есть в приложении, работает до того, как я добавлю множество кода и потеряюсь)

Я проверил, что я обращаюсь к правильному пути и что имя базы данных является правильным, я также попытался заставить новое приложение открыть старый файл базы данных (который все еще работает в старом приложении), но я получаю то же самое Ошибки LogCat, так что я считаю, что это как-то связано с другим кодом. Я действительно не уверен, куда идти отсюда. Если вам нужна дополнительная информация или код, я опубликую его по запросу. Спасибо за любую помощь, которую вы, ребята, можете оказать:)

Вот два класса, которые вызывают проблему atm:

Это класс списка, в конечном итоге это будет список всех элементов в базе данных с флажком в правой части элемента списка, если установлен этот флажок, он удалит элемент из списка и поместит его в другой элемент. список (не важный на данный момент)

public class RoomList extends ListActivity{
public String Room = MainMenu.room;
protected Database listdb;
MyAdapter adapterList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.room);

    listdb = new Database(this, Room, null, 0);
    listdb.openDatabase();

    fillList();
}

private void fillList(){
    Cursor cursor = null;
    cursor = listdb.getRoom(Room);

    //not entirely sure how the managing cursor works, i think it just keeps everything synchronised
    startManagingCursor(cursor);

    //takes string values from the database, will eventually be displayed in the list views
    String [] names = new String []{Database.KEY_NAME, Database.KEY_SIZE, Database.KEY_BRAND, Database.KEY_TYPE, Database.KEY_DESCRIPTION};

    //sets what xml variables get modified with the taken strings
    int [] holder = new int []{R.id.additem, R.id.listDescription};

    //again not entirely sure how this method works, from what i can gather it basically defines which
    //layout to access when filing the xml variables in "holder" with the strings in "names"
    adapterList = new MyAdapter(RoomList.this, cursor);

            //seems to send whatever changes made with the last line of 
    //code to become a ListAdapter in order to be displayed as a list
}

private class MyAdapter extends ResourceCursorAdapter {

    public MyAdapter(Context context, Cursor cur) {
        super(context, R.layout.room, cur);
    }

    @Override
    public View newView(Context context, Cursor cur, ViewGroup parent) {
        LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        return li.inflate(R.layout.room, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cur) {
        TextView tvListText = (TextView)view.findViewById(R.id.listButton);
        CheckBox cbListCheck = (CheckBox)view.findViewById(R.id.checkbox1);

        tvListText.setText(cur.getString(cur.getColumnIndex(listdb.KEY_NAME)));
        cbListCheck.setChecked((cur.getInt(cur.getColumnIndex(listdb.KEY_ONLIST))==0? false:true));
    }
}
}

вот класс, который обращается к базе данных:

public class Database extends SQLiteOpenHelper{

private static final String DATABASE_DIRECTORY = "data/data/myApps.ShoppingList/database/";
private static final String DATABASE_NAME = "listdb.sqlite";
private static final String DATABASE_PATH = DATABASE_DIRECTORY + DATABASE_NAME;
private static final String DATABASE_ITEMS_TABLE = "items";
private static final String DATABASE_CATEGORY_TABLE = "categorys";
public static final String KEY_NAME = "name";
public static final String KEY_DESCRIPTION = "description";
public static final String KEY_BRAND = "brand";
public static final String KEY_SIZE = "size";
public static final String KEY_TYPE = "type";
public static final String KEY_ROOM = "room";
public static final String KEY_ONLIST = "onList";
public static final String KEY_ROWID = "_id";
static SQLiteDatabase listdb;
private Context m_context;

public Database(Context context, String name, CursorFactory factory, int version) {
    super(context, DATABASE_NAME, null, 1);
    m_context = context;
}

public void onCreate(SQLiteDatabase db) {}

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

public void createDatabase() throws IOException{
    boolean exists = checkDatabase();       
    if(!exists){
        this.getWritableDatabase();  
        try{
            copyDatabase();
        } catch(IOException e){
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDatabase(){
    SQLiteDatabase check = null;        
    try{
        check = SQLiteDatabase.openDatabase(DATABASE_PATH, null, SQLiteDatabase.OPEN_READWRITE);
    } catch (SQLiteException e){}

    if(check != null){
        check.close();
        return true;
    }
    else return false;
}
private void copyDatabase() throws IOException{
    InputStream in = m_context.getAssets().open(DATABASE_NAME);
    OutputStream out = new FileOutputStream(DATABASE_PATH);
    byte[] buffer = new byte[1024];
    int length;

    while((length = in.read(buffer)) > 0){
        out.write(buffer, 0, length);
    }       
    out.flush();
    out.close();
    in.close();
}


public void openDatabase() throws SQLException{
    listdb = SQLiteDatabase.openDatabase(DATABASE_PATH, null, SQLiteDatabase.OPEN_READWRITE);
}

public synchronized void close(){
    if(listdb != null){
        listdb.close();
    }
    super.close();
}

public Cursor getRoom(String roomId){
    if (roomId=="1"){
        Cursor cursor = listdb.query(DATABASE_ITEMS_TABLE, new String[]{KEY_ROWID, KEY_NAME, KEY_BRAND, KEY_DESCRIPTION, KEY_SIZE, KEY_TYPE, KEY_ROOM, KEY_ONLIST},KEY_ROOM + " = 1 " + "AND " + KEY_ONLIST + " != 1 ", null, null, null, null, null);
        return cursor;
    }
    else if (roomId=="2"){
        Cursor cursor = listdb.query(DATABASE_ITEMS_TABLE, new String[]{KEY_ROWID, KEY_NAME, KEY_BRAND, KEY_DESCRIPTION, KEY_SIZE, KEY_TYPE, KEY_ROOM, KEY_ONLIST},KEY_ROOM + " = 2 " + "AND " + KEY_ONLIST + " != 1 ", null, null, null, null, null);
        return cursor;
    }
    else if (roomId=="3"){
        Cursor cursor = listdb.query(DATABASE_ITEMS_TABLE, new String[]{KEY_ROWID, KEY_NAME, KEY_BRAND, KEY_DESCRIPTION, KEY_SIZE, KEY_TYPE, KEY_ROOM, KEY_ONLIST},KEY_ROOM + " = 3 " + "AND " + KEY_ONLIST + " != 1 ", null, null, null, null, null);
        return cursor;
    }
    else if (roomId=="4"){
        Cursor cursor = listdb.query(DATABASE_ITEMS_TABLE, new String[]{KEY_ROWID, KEY_NAME, KEY_BRAND, KEY_DESCRIPTION, KEY_SIZE, KEY_TYPE, KEY_ROOM, KEY_ONLIST},KEY_ROOM + " = 4 " + "AND " + KEY_ONLIST + " != 1 ", null, null, null, null, null);
        return cursor;
    }
    else{
        Cursor cursor = listdb.query(DATABASE_ITEMS_TABLE, new String[]{KEY_ROWID, KEY_NAME, KEY_BRAND, KEY_DESCRIPTION, KEY_SIZE, KEY_TYPE, KEY_ROOM, KEY_ONLIST},KEY_ONLIST + "= 1" , null, null, null, null, null);
        return cursor;
    }
}
}

1 Ответ

1 голос
/ 04 августа 2011

Почему вы используете SQLiteOpenHelper вместо SQLiteDatabase.open?И почему вы жестко задаете путь к базе данных?

DATABASE_DIRECTORY = "data/data/myApps.ShoppingList/database/";

На многих устройствах я видел, что это на самом деле ... / database /, но в любом случае используйте getDatabasePath для его получения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...