如何从ListView Android中的SQLCipher数据库加载数据

时间:2018-03-07 17:46:39

标签: java sqlite listview android-studio sqlcipher

我在将表从SQLCipher数据库显示到ListView时遇到了一些麻烦。

我的程序,现在,只允许用户添加"秘密"到数据库。当我的数据库是SQLite时,我能够查看数据,但在转移到SQLCipher后,我遇到了一些错误。

以下是我遇到的一些错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.matc.secretkeeper/edu.matc.secretkeeper.ListData}: java.lang.IllegalStateException: get field slot from row 0 col 1 failed

和此:

Finalizing a Cursor that has not been deactivated or closed. database = /data/user/0/edu.matc.secretkeeper/databases/secrets1.db, table = null, query = SELECT * FROM secretTable net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here

这是我的代码,可以帮助您排查问题。

这是我的ListData.java类:

public class ListData extends AppCompatActivity {

private static final String TAG = "activity_list_data" ;
MyDBHandler myDB;
private ListView myListView;
Button refreshList, goHome;

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

    myListView = (ListView) findViewById(R.id.listView);
    myDB = new MyDBHandler(this);

    populateListView();

    refreshList = (Button) findViewById(R.id.refreshListBtn); //refresh button
    refreshList.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent myIntent = new Intent(ListData.this,
                    ListData.class);
            startActivity(myIntent);
        }
    });

    goHome = (Button) findViewById(R.id.homeBtn); //gohome button
    goHome.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent myIntent = new Intent(ListData.this,
                    MainActivity.class);
            startActivity(myIntent);
        }
    });


}

//this doesnt seem to be populating the list view
private void populateListView() {
    Log.d(TAG, "populateListView: Displaying data in the ListView.");

    //get the data and append to a list
    Cursor data = myDB.getData();
    ArrayList<String> listData = new ArrayList<>();
    while(data.moveToNext()){
        //get the value from the database in column 1
        //then add it to the ArrayList
        listData.add(data.getString(1));


        data.close(); //close cursor
    }

    Log.d(TAG, "array list while loop completed");


    //create the list adapter and set the adapter
    ListAdapter adapter = new ArrayAdapter<>(this, 
 android.R.layout.simple_list_item_1, listData);
    myListView.setAdapter(adapter);

    //set an onItemClickListener to the ListView
    myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
{
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int 
i, long l) {
            String secret = adapterView.getItemAtPosition(i).toString();
            Log.d(TAG, "onItemClick: You Clicked on " + secret);

            Cursor data = myDB.getItemID(secret); //get the id associated 
with that secret
            int itemID = -1;
            while(data.moveToNext()){
                itemID = data.getInt(0);
            }
            if(itemID > -1){
                Log.d(TAG, "onItemClick: The ID is: " + itemID);
                Intent editScreenIntent = new Intent(ListData.this, 
EditData.class);
                editScreenIntent.putExtra("id",itemID);
                editScreenIntent.putExtra("secret",secret);
                startActivity(editScreenIntent);
            }
            else{
                toastMessage("No ID associated with that secret");
            }
        }
    });
}

private void toastMessage(String message){
    Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}


}

MyDBHelper类中的getData方法:

 public Cursor getData(){ 
    SQLiteDatabase db = this.getWritableDatabase("temp123");
    String query = "SELECT * FROM " + TABLE_SECRET;
    Cursor data = db.rawQuery(query,null);
    Log.d("Cursor Object", DatabaseUtils.dumpCursorToString(data));
    db.close();
    return data;

}

如果我需要添加任何细节以便描绘更好的图片,请告诉我。

热烈的问候,

Ĵ

1 个答案:

答案 0 :(得分:0)

在我的populateListView()方法中,我关闭了while循环内的光标。在while循环之外移动data.close()之后,一切正常。