Android:使用带游标的sqlite数据库崩溃

时间:2015-02-27 18:11:54

标签: android ios

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

这是我的主要活动:

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

当我把它放到评论中时,我的应用程序&#34;工作&#34; (我可以从我的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
     

ComponentInfo {com.example.contactmanager / com.example.contactmanager.MainActivity}:   android.database.sqlite.SQLiteException:near&#34; test&#34;:语法错误   (代码1):,编译时:test       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread.access $ 800(ActivityThread.java:144)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1278)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.os.Handler.dispatchMessage(Handler.java:102)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.os.Looper.loop(Looper.java:135)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread.main(ActivityThread.java:5221)       02-27 17:59:04.418:E / AndroidRuntime(28845):at java.lang.reflect.Method.invoke(Native Method)       02-27 17:59:04.418:E / AndroidRuntime(28845):at java.lang.reflect.Method.invoke(Method.java:372)       02-27 17:59:04.418:E / AndroidRuntime(28845):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:899)       02-27 17:59:04.418:E / AndroidRuntime(28845):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)       02-27 17:59:04.418:E / AndroidRuntime(28845):引起:android.database.sqlite.SQLiteException:near&#34; test&#34;:语法错误   (代码1):,编译时:test       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native)   方法)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteProgram。(SQLiteProgram.java:58)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteQuery。(SQLiteQuery.java:37)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1255)       02-27 17:59:04.418:E / AndroidRuntime(28845):at com.example.contactmanager.MainActivity.onCreate(MainActivity.java:44)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.Activity.performCreate(Activity.java:5933)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)       02-27 17:59:04.418:E / AndroidRuntime(28845):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)       02-27 17:59:04.418:E / AndroidRuntime(28845):... 10 more

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

1 个答案:

答案 0 :(得分:0)

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