如何在ListActivity中正确填充SQLite中的记录?

时间:2010-06-07 08:59:50

标签: android sqlite

有人可以告诉我如何在ListActivity选项卡中轻松显示sqllite中的每条记录?我有点困惑。我是否必须在TabActivity或ListActivity中的helper类中创建db或两者?我的db helper类如下:

package tabs.app;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBAdapter 
{

 private static String DB_PATH = "/data/data/tabs.app/databases/";

    public static final String KEY_ROWID = "_id";
    public static final String KEY_LATITUDE = "latitude";
    public static final String KEY_LONGITUDE = "longitude";
    private static final String TAG = "DBAdapter";

    private static final String DATABASE_NAME = "coords";
    private static final String DATABASE_TABLE = "coordsStorages";
    private static final int DATABASE_VERSION = 2;

   /* private static final String DATABASE_CREATE =
        "create table coordsStorage (_id integer primary key autoincrement, latitude integer not null, longitude integer not null)";
     */   
    public Context context; 

    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    public DBAdapter(Context ctx) 
    {
        this.context = ctx;
        DBHelper = new DatabaseHelper(context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper 
    {
        DatabaseHelper(Context context) 
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) 
        {
            db.execSQL("create table coordsStorages (_id integer primary key autoincrement, latitude integer not null, longitude integer not null)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, 
        int newVersion) 
        {
            Log.w(TAG, "Upgrading database from version " + oldVersion 
                    + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS titles");
            onCreate(db);
        }
    }    

    //---opens the database---
    public DBAdapter open() throws SQLException 
    {
        db = DBHelper.getWritableDatabase();
        return this;
    }

    //---closes the database---    
    public void close() 
    {
        DBHelper.close();
    }

    //---insert a title into the database---
    public long insertCoords(int latitude, int longitude) 
    {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_LATITUDE, latitude);
        initialValues.put(KEY_LONGITUDE, longitude);
        return db.insert(DATABASE_TABLE, null, initialValues);
    }

    public void openDataBase() throws SQLException{

        //Open the database
        String myPath = DB_PATH + DATABASE_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }


    //---deletes a particular title---
    public boolean deleteTitle(long rowId) 
    {
        return db.delete(DATABASE_TABLE, KEY_ROWID + 
          "=" + rowId, null) > 0;
    }

    //---retrieves all the titles---
    public Cursor getAllTitles() 
    {
        return db.query(DATABASE_TABLE, new String[] {
          KEY_ROWID, 
          KEY_LATITUDE,
          KEY_LONGITUDE}, 
                null, 
                null, 
                null, 
                null, 
                null);
    }

    //---retrieves a particular title---
    public Cursor getTitle(long rowId) throws SQLException 
    {
        Cursor mCursor =
                db.query(true, DATABASE_TABLE, new String[] {
                  KEY_ROWID,
                  KEY_LATITUDE, 
                  KEY_LONGITUDE}, 
                  KEY_ROWID + "=" + rowId, 
                  null,
                  null, 
                  null, 
                  null, 
                  null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }

    //---updates a title---
    /*public boolean updateTitle(long rowId, int latitude, 
    int longitude) 
    {
        ContentValues args = new ContentValues();
        args.put(KEY_LATITUDE, latitude);
        args.put(KEY_LONGITUDE, longitude);
        return db.update(DATABASE_TABLE, args, 
                         KEY_ROWID + "=" + rowId, null) > 0;
    }*/
}

And Im trying to retrieve the records in TabActivity like this:

public class Areas extends ListActivity {

 DBAdapter db;
 SimpleCursorAdapter mAdapter;

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

          db = new DBAdapter(this);
          db.open();
          Cursor c = db.getAllTitles();
          startManagingCursor(c);

          String[] display = new String[] { db.KEY_LATITUDE };      
          int[] to = new int[] { R.id.row_latitude};
        /*
          String[] display2 = new String[] { db.KEY_LONGITUDE };      
          int[] to2 = new int[] { R.id.row_longitude};*/

          mAdapter = new SimpleCursorAdapter(this, R.layout.areas_layout, c, display, to);
          setListAdapter(mAdapter);

       /*   mAdapter2 = new SimpleCursorAdapter(this, R.layout.areas_layout, c, display2, to2);
          setListAdapter(mAdapter2);*/

          db.close();



 }
/*
 private void fillData() {

     // Get all of the rows from the database and create the item list
     Cursor c = db.getAllTitles();
     startManagingCursor(c);


 }*/

}

每当我尝试这样做时,错误日志都会输出:

06-07 09:51:56.529:
ERROR/AndroidRuntime(2034): Uncaught
handler: thread main exiting due to
uncaught exception

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):
java.lang.RuntimeException: Unable to
start activity
ComponentInfo{tabs.app/tabs.app.Areas}:
java.lang.RuntimeException: Your
content must have a ListView whose id
attribute is 'android.R.id.list'

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.ActivityThread.startActivityNow(ActivityThread.java:2242)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:631)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.widget.TabHost.setCurrentTab(TabHost.java:317)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:127)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:346)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.View.performClick(View.java:2344)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.View.onTouchEvent(View.java:4133)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.View.dispatchTouchEvent(View.java:3672)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:850)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:882)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(    oneWindow.java:1712)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1202)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.Activity.dispatchTouchEvent(Activity.java:1987)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(    oneWindow.java:1696)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.view.ViewRoot.handleMessage(ViewRoot.java:1658)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.os.Handler.dispatchMessage(Handler.java:99)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.os.Looper.loop(Looper.java:123)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.ActivityThread.main(ActivityThread.java:4203)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
java.lang.reflect.Method.invokeNative(Native
Method)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
java.lang.reflect.Method.invoke(Method.java:521)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
dalvik.system.NativeStart.main(Native
Method)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034): Caused by:
java.lang.RuntimeException: Your
content must have a ListView whose id
attribute is 'android.R.id.list'

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.ListActivity.onContentChanged(ListActivity.java:236)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:316)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.Activity.setContentView(Activity.java:1620)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
tabs.app.Areas.onCreate(Areas.java:18)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)

06-07 09:51:56.559:
ERROR/AndroidRuntime(2034):     ... 30
more

06-07 09:51:56.619: INFO/Process(51):
Sending signal. PID: 2034 SIG: 3

06-07 09:51:56.619:
INFO/dalvikvm(2034): threadid=7:
reacting to signal 3

06-07 09:51:56.619:
ERROR/dalvikvm(2034): Unable to open
stack trace file
'/data/anr/traces.txt': Permission
denied

有人可以告诉我我做错了什么吗?非常感谢!

2 个答案:

答案 0 :(得分:1)

java.lang.RuntimeException: Your
content must have a ListView whose id
attribute is 'android.R.id.list'

此错误表示您的视图文件(R.layout.areas_layout)中的ListView未被赋予正确的ID。您的ListView XML必须如下所示:

<ListView
  android:id="@android:id/list"…

尝试这样做,看看它是否解决了您的问题:

****************编辑****************************** ********

感谢您分享您的布局代码,问题似乎是您的列表行xml布局与主内容视图位于同一布局文件中。你需要让他们分开。

在您的R.layout.areas_layout文件中,只需要您的linearlayout,然后您的列表视图就会为您的行创建一个单独的xml文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  >
  <TextView 
    android:id="@+id/row_latitude" 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    />
</LinearLayout>

然后,您将列表行传递给SimpleCursorAdapter:

mAdapter = new SimpleCursorAdapter(this, R.layout.my_list_row, c, display, to);

答案 1 :(得分:1)

好的我已经解决了我添加了listview的问题,布局看起来像这样:

<TextView android:id="@+id/row_latitude" android:layout_width="wrap_content" android:layout_height="fill_parent" />

<ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="wrap_content"></ListView>

所以基本上textView在listview之上。谢谢你的帮助伴侣!