Android 插入到数据库并自动更新listview

Android 插入到数据库并自动更新listview,android,database,android-activity,android-listview,simplecursoradapter,Android,Database,Android Activity,Android Listview,Simplecursoradapter,我已经在android中创建了一个包含单个活动的项目,我想通过按“插入按钮”将新记录添加到数据库中,如图所示,但我希望新记录保存到数据库后,ListView会立即更新,并将添加的记录显示到最后位置的列表中 当我运行此代码时,发生意外错误并将其关闭 错误或任何建议在哪里 我把所有的代码和布局都放在这里 MainActivity.java package com.example.db; import java.util.ArrayList; import android.app.Activit

我已经在android中创建了一个包含单个活动的项目,我想通过按“插入按钮”将新记录添加到数据库中,如图所示,但我希望新记录保存到数据库后,ListView会立即更新,并将添加的记录显示到最后位置的列表中

当我运行此代码时,发生意外错误并将其关闭 错误或任何建议在哪里

我把所有的代码和布局都放在这里

MainActivity.java

package com.example.db;

import java.util.ArrayList;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

Button Btninser;
SQLiteDatabase db;
EditText etName, etPhone;
ListView lv;

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

    etName = (EditText) findViewById(R.id.etName);
    etPhone = (EditText) findViewById(R.id.etPhone);
    Btninsert = (Button) findViewById(R.id.btnInsert);
    lv = (ListView) findViewById(R.id.listView1);
    Btninsert.setOnClickListener(this);
    Open_Create();

}

    public void Open_Create() {
    db = openOrCreateDatabase("MyDB1", MODE_PRIVATE, null);
    db.execSQL("CREATE TABLE IF NOT EXISTS MyTable (_id INTEGER PRIMARY KEY AUTOINCREMENT, LastName VARCHAR,Phone VARCHAR);");

}

public void Insert_Info() {
    db.execSQL("INSERT INTO MyTable (LastName,Phone) VALUES('" + etName.getText().toString()
            + "','" + etPhone.getText().toString() + "');");

    Populate_ListView();

    // db.close();
    Toast.makeText(this, "Data has been saved!", Toast.LENGTH_LONG).show();

}

public void Populate_ListView() {
    Cursor cursor = db.rawQuery("SELECT LastName,Phone FROM MyTable", null);
    startManagingCursor(cursor);

    String[] from = new String[] { "LastName", "Phone" };
    int[] to = new int[] { R.id.tvItemListName, R.id.tvItemListPhone };

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            R.layout.item_list, cursor, from, to);

    lv.setAdapter(adapter);
}
这是XML文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

         <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:text="Name" />

        <EditText
            android:id="@+id/etName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/textView1"
            android:ems="10" >

            <requestFocus />
        </EditText>

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:text="Phone" />

        <EditText
            android:id="@+id/etPhone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/textView1"
            android:ems="10" >
        </EditText>

        <Button
            android:id="@+id/btnInsert"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:text="Insert" />

    <ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="21dp" >
    </ListView>

</RelativeLayout>

我还添加了来自DDMS的错误 正如您在错误页面中看到的,它提到了一个字段“\u id,而我从未拥有过它:( 太让我困惑了


<> p> < /p> < p>您是否尝试从<代码> OnCLCK()/代码>方法中删除<代码> OpenGCREATE()/CULL?您有两次连续调用到“代码> OpenReCaleDATABASE())/<代码>中没有任何代码>关闭()/代码>中间。不要忘记<代码>尝试{…} catch(SqLeLeExt){…}。您可以进行测试。

如果您想使用光标,Android会自动假定您的表中有一个名为
\u id
的列,该列充当行的唯一主标识符,有关该列的更多详细信息,请参阅的“类概述”部分,其中说明:

将数据从游标公开到ListView小部件的适配器。游标必须包含名为“\u id”的列,否则此类将无法工作

基本上,您只需将
CREATE TABLE
调用替换为:

db.execSQL("CREATE TABLE IF NOT EXISTS MyTable (_id INTEGER PRIMARY KEY AUTOINCREMENT, LastName VARCHAR,Phone VARCHAR);");
这将修复您的崩溃。要使其自动刷新列表,请参阅我的注释重新分级
notifyDatasetChanged()

作为旁注:我强烈建议使用实例来处理表的打开和创建,而不是像现在这样,重复调用
CREATE TABLE(如果不存在)
,在知道需要调用它的时候只能调用一次,这是一种不好的方式

编辑:根据您上次编辑的代码:您仍然没有请求您创建的
\u id
字段。如果SELECT语句中没有该字段,光标将无法访问它


Populate_ListView
中的
rawQuery
替换为
SELECT*FROM MyTable
,以便
\u id
字段也由光标返回。

用“意外错误”表示崩溃吗?如果是,请发布崩溃日志。在任何情况下,只需执行
notifyDatasetChanged()
插入新条目后,应通知listview进行自我更新。@kasra Rahjerdi我如您所说添加了错误,现在问题出在哪里?该列可能不存在控制台建议的内容。但是我不建议您使用“startManagingCursor(Cursor c)”。请阅读以下内容:“此方法在API级别11中被弃用。请改为将新的CursorLoader类与LoaderManager一起使用;这也可以通过Android兼容包在较旧的平台上使用。"此类以查询游标的标准方式实现加载程序协议,以AsyncTaskLoader为基础在后台线程上执行游标查询,这样就不会阻塞应用程序的UI。如果我再次使用这行代码,则会出现与以前相同的错误,_id不存在!!!!您尚未卸载应用程序并重新安装它由于您修改了代码,因此不会再次重新创建您的表,因为您正在使用
创建表(如果不存在)
,并且您的数据库已经存在。请卸载应用程序,然后重试。