安卓系统:使用带有游标的sqlite数据库崩溃



我是android开发的新手,我正试图使用sqlite创建一个联系人管理器列表,但我在使用光标访问sqlite数据库时遇到了问题。我有两个活动,一个用于向数据库添加新联系人,另一个用于为数据库读取联系人。

这是我的主要活动:

package com.example.contactmanager;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
private SQLiteDatabase sdb;
private TestDBOpenHelper tdb;
private ArrayList<String> al_strings;
private ArrayAdapter<String> aa_strings;
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tdb = new TestDBOpenHelper(this, "test.db", null, 1);
    sdb = tdb.getReadableDatabase();
    lv = (ListView) findViewById(R.id.lv);
    al_strings = new ArrayList<String>();
    aa_strings = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, al_strings);
    lv.setAdapter(aa_strings);
    String[] columns = { "ID", "NAME", "PHONE_NUMBER", "EMAIL" };
    Cursor c = sdb.rawQuery("test", columns);
    c.moveToFirst();        
    while (c.isAfterLast() == false) {
        al_strings.add(c.getString(c.getColumnIndex("NAME")));
        al_strings.add(c.getString(c.getColumnIndex("PHONE_NUMBER")));
        al_strings.add(c.getString(c.getColumnIndex("EMAIL")));
        c.moveToNext();
    }
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent nextScreen = new Intent(getApplicationContext(),
                    AddContact.class);
            startActivity(nextScreen);
        }
    });
}
public boolean listUpdate(Integer id, String name, String phone, String mail) {
    SQLiteDatabase db = tdb.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put("NAME", name);
    cv.put("PHONE_NUMBER", phone);
    cv.put("EMAIL", mail);
    db.update("test", cv, "id = ? ", new String[] { Integer.toString(id) });
    return true;
}
public Cursor getList() {
    SQLiteDatabase sdb = tdb.getReadableDatabase();
    // the columns that we wish to retrieve from the tables
    String[] columns = { "ID", "NAME", "PHONE_NUMBER", "EMAIL" };
    Cursor c = sdb.rawQuery("test.db", columns);
    return c;
}
// overridden method that will clear out the contents of the database
/*@Override
protected void onDestroy() {
    super.onDestroy();
    // run a query that will delete all the rows in our database
    String table = "test";
    String where = null;
    String where_args[] = null;
    sdb.delete(table, where, where_args);
}*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
  }
}

TestDBOpenHelper是我初始化数据库的类:

public class TestDBOpenHelper extends SQLiteOpenHelper {
// constructor for the class here we just map onto the constructor of the
// super class
public TestDBOpenHelper(Context context, String name,
        CursorFactory factory, int version) {
    super(context, name, factory, version);
}
// overridden method that is called when the database is to be created
public void onCreate(SQLiteDatabase db) {
    // create the database
    db.execSQL(create_table);
}
// overridden method that is called when the database is to be upgraded
// note in this example we simply reconstruct the database not caring for
// data loss
// ideally you should have a method for storing the data while
// you are reconstructing the database
public void onUpgrade(SQLiteDatabase db, int version_old, int version_new) {
    // drop the tables and recreate them
    db.execSQL(drop_table);
    db.execSQL(create_table);
}
// a bunch of constant strings that will be needed to create and drop
// databases
private static final String create_table = "create table test ("
        + "ID integer primary key autoincrement, " + "NAME string,"
        + "PHONE_NUMBER string, " + "EMAIL string" + ");";
private static final String drop_table = "drop table test";
}    

这是我的第二个活动,用于添加联系人:

public class AddContact extends Activity {
EditText inputName;
EditText inputPhone;
EditText inputMail;
private TestDBOpenHelper tdb;
private MainActivity ma;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.second_activity);
    tdb = new TestDBOpenHelper(this, "test.db", null, 1);
    inputName = (EditText) findViewById(R.id.name);
    inputPhone = (EditText) findViewById(R.id.ed_pho);
    inputMail = (EditText) findViewById(R.id.ed_ema);
    Button btnPrevScreen = (Button) findViewById(R.id.btn_add);
    btnPrevScreen.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bundle extras = getIntent().getExtras();
            if(extras != null) {
                int Value = extras.getInt("ID");
                if(Value>0) {
                    if(ma.listUpdate(0, inputName.getText().toString(), 
                            inputPhone.getText().toString(),
                            inputMail.getText().toString())) {
                        Toast.makeText(getApplicationContext(), "Updated",
                                Toast.LENGTH_SHORT).show();
                    }
                    else
                        Toast.makeText(getApplicationContext(), "Not updated",
                                Toast.LENGTH_SHORT).show();
                }
                else {
                    if(addContact(inputName.getText().toString(), 
                            inputPhone.getText().toString(),
                            inputMail.getText().toString())) {
                        Toast.makeText(getApplicationContext(), "Contact Added",
                                Toast.LENGTH_SHORT).show();
                    }
                    else
                        Toast.makeText(getApplicationContext(), "Error",
                                Toast.LENGTH_SHORT).show();
                }
                Intent prevScreen = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(prevScreen);
            }
        }
    });
}
public boolean addContact(String name, String phone, String mail) {
    SQLiteDatabase sdb = tdb.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put("NAME", name);
    cv.put("PHONE_NUMBER", phone);
    cv.put("EMAIL", mail);
    sdb.insert("test", null, cv);
    return true;
  }
}

问题就在这里,在我的MainActivity:上

Cursor c = sdb.rawQuery("test", columns);

当我把这句话写进评论中时,我的应用程序"工作"了(我可以从我的nexus 5启动它),我通过调试模式发现,正是这一行导致了它崩溃(我认为)。

这是LogCat:

02-27 17:59:04.408: E/SQLiteLog(28845): (1) near "test": syntax error
02-27 17:59:04.414: D/AndroidRuntime(28845): Shutting down VM
02-27 17:59:04.418: E/AndroidRuntime(28845): FATAL EXCEPTION: main
02-27 17:59:04.418: E/AndroidRuntime(28845): Process: com.example.contactmanager, PID: 28845
02-27 17:59:04.418: E/AndroidRuntime(28845): java.lang.RuntimeException: Unable to start activity

组件信息{com.example.contactmanager/com.example.cottactmanager.MainActivity}:android.database.sqlite.SQLiteException:靠近"test":语法错误(代码1):,编译时:测试02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread.performLaunchActivity(ActivityThreads.java:2298)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread.handleLaunchActivity(ActivityThreads.java:2360)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread.access$800(ActivityThreads.java:144)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.os.Handler.dispatchMessage(Handler.java:102)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.os.Looper.loop(Looper.java:135)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread.main(ActivityThreads.java:5221)02-27 17:59:04.441:E/AndroidRuntime(28845):在java.lang.reflect.Method.ioke(Native Method)02-27 17:59:04.441:E/AndroidRuntime(28845):在java.lang.reflect.Method.ioke(Method.java:372)02-27 17:59:04.441:E/AndroidRuntime(28845):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteIndit.java:899)02-27 17:59:04.441:E/AndroidRuntime(28845):在com.android.internal.os.ZygoteInit.main(ZygoteNit.java:694)02-27 17:59:04.441:E/AndroidRuntime(28845):由以下原因引起:android.database.sqlite.SQLiteException:靠近"test":语法错误(代码1):,编译时:测试02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.naturePrepareStatement(Native方法)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.acquisitePreparedStatement(SQLiteConnection.java:889)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteSession.reprepare(SQLiteSession.java:588)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCurcursorDriver.java:44)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)02-27 17:59:04.441:E/AndroidRuntime(28845):在com.example.contactmanager.MainActivity.onCreate(MainActivity.java:44)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.Activity.performCreate(Activity.java:55933)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)02-27 17:59:04.441:E/AndroidRuntime(28845):在android.app.ActivityThread.performLaunchActivity(ActivityThreads.java:2251)02-27 17:59:04.441:E/AndroidRuntime(28845):。。。再增加10个

我花了几个小时试图解决这个问题,但我找不到方法,任何帮助都是幸运的。这可能是我犯的一个愚蠢的错误,请提前原谅我。

您需要编写完整的SQL命令。Cursor cursor = database.rawQuery("select * from exectable", null); 

最新更新