Android Studio - 使用SQLite添加,编辑和删除记录

时间:2017-09-10 10:40:26

标签: javascript xml sqlite android-sqlite

我是 Android Studio 的极端初学者并且使用 JavaScript ,所以仍然在学习并尝试掌握整个android studio的新概念。

我正在尝试创建一个数据库,用于添加,编辑和删除用户手动输入的记录

当我到达 friends.xml 页面( friends.java )并填写字段以添加用户并按" ADD"当我点击" VIEW DATA" (链接到 view_data.xml listdata.java ))似乎没有显示条目

如果答案尽可能简单,我仍然是初学者,那将是很棒的!任何帮助将不胜感激!谢谢!

friends.java

    package com.example.chris.mobileappsassignment;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class friends extends AppCompatActivity {

    EditText firstnameinput, lastnameinput, ageinput, addressinput;
    Button addbutton, viewbutton;
    DatabaseHelper dbhlpr;
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_friends);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        firstnameinput = (EditText) findViewById(R.id.firstnameinput);
        lastnameinput = (EditText) findViewById(R.id.lastnameinput);
        ageinput = (EditText) findViewById(R.id.ageinput);
        addressinput = (EditText) findViewById(R.id.addressinput);
        addbutton = (Button) findViewById(R.id.addbutton);
        viewbutton = (Button) findViewById(R.id.viewbutton);




        dbhlpr = new DatabaseHelper(this);

        addbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                boolean addOK = true;
                int age_as_int = -1;

                String firstName = firstnameinput.getText().toString();
                String lastName = lastnameinput.getText().toString();
                String age = ageinput.getText().toString();
                String address = addressinput.getText().toString();

                if (firstName.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    firstnameinput.requestFocus();
                    addOK = false;
                }
                if (lastName.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    lastnameinput.requestFocus();
                    addOK = false;
                }
                if (age.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    ageinput.requestFocus();
                    addOK = false;
                }
                if (address.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    addressinput.requestFocus();
                    addOK = false;
                }
                try {
                    age_as_int = Integer.parseInt(age);
                } catch (NumberFormatException e) {
                    toastMessage("You must enter a valid Number in this field!");
                    ageinput.requestFocus();
                    addOK = false;
                }

                if (addOK) {
                    dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
                    toastMessage("Friend Added!");
                }

            }
        });





        viewbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,listdata.class);
                startActivity(intent);
            }
        });









    } //END ON CREATE CLASS











    //TOAST MSSG

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









    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_friends, 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();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }





}

listdata.java

package com.example.chris.mobileappsassignment;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

import static com.example.chris.mobileappsassignment.R.layout.view_data;

public class listdata extends AppCompatActivity {

    private static final String TAG = "listdata";

    DatabaseHelper mDatabaseHelper;

    private ListView mListView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(view_data);
        mListView = (ListView) findViewById(R.id.ListView);
        mDatabaseHelper = new DatabaseHelper(this);

        populateListView();

    } //END ONCREATE

    private void populateListView() {
        Log.d(TAG, "populate ListView: Displaying Data in the ListView");

        //get data and append to list
        Cursor data = mDatabaseHelper.getData();
        Log.d("CURSORCOUNT", "Number of rows in Cursor =");
        Integer.toString(data.getCount());
        ArrayList<String> listData = new ArrayList<>();
        while(data.moveToNext()){
            //GET VALUE FROM DB IN COL1
            //then add to ArrayList
            listData.add(data.getString(1));
            listData.add(data.getString(2));
            listData.add(data.getString(3));
            listData.add(data.getString(4));
            listData.add(data.getString(5)); // NUMBERS REFER TO COL'S. (coloumns)

        }
        //create LIST ADAPTER AND SET ADAPTER
        ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
        mListView.setAdapter(adapter);

        //set on onclick listener to list view
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                String name = adapterView.getItemAtPosition(position).toString(); // will grab object and convert to string
                Log.d(TAG, "onItemClick: You clicked on " + name);

                Cursor data = mDatabaseHelper.getItemID(name); // get ID associated with that name

                int itemID = 1;                 // WHEN SEARCHING // RETURN SOMETHING THAT EXISTS
                while (data.moveToNext()){
                    itemID = data.getInt(0);  // if data is returned
                }
                if (itemID > -1) {
                    Log.d(TAG, "onItemClick: The ID is: " + itemID);
                    Intent editScreenIntent = new Intent(listdata.this, EditDataActivity.class ); // VID2, 2.49
                    editScreenIntent.putExtra("id", itemID);
                    editScreenIntent.putExtra("name", name);
                    startActivity(editScreenIntent);
                }
                else {
                    toastMessage("No ID is associated with that name");
                }
            }
        });
    }

    /**
     * customizable toast
     */
    private void toastMessage(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
} //END CLASS
按&#34; ADD&#34;

logcat中的错误

    --------- beginning of crash
09-12 02:40:00.329 26615-26615/com.example.chris.mobileappsassignment E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                        Process: com.example.chris.mobileappsassignment, PID: 26615
                                                                                        java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                                                            at android.content.ComponentName.<init>(ComponentName.java:128)
                                                                                            at android.content.Intent.<init>(Intent.java:4449)
                                                                                            at com.example.chris.mobileappsassignment.friends$2.onClick(friends.java:99)
                                                                                            at android.view.View.performClick(View.java:5198)
                                                                                            at android.view.View$PerformClick.run(View.java:21147)
                                                                                            at android.os.Handler.handleCallback(Handler.java:739)
                                                                                            at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                            at android.os.Looper.loop(Looper.java:148)
                                                                                            at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

1 个答案:

答案 0 :(得分:0)

此处的问题是,在名为 friends_table 的表格中找不到名为地址的列,具体如下: -

09-10 20:38:48.892 10003-10003/com.example.chris.mobileappsassignment E/SQLiteDatabase: Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike
                                                                                            android.database.sqlite.SQLiteException: table friends_table has no column named address (code 1): , while compiling: INSERT INTO friends_table(address,lastname,firstname,age,malefemale) VALUES (?,?,?,?,?)

用于创建表的定义可能需要更改,或者定义已更改但已实现,因为数据库的onCreate方法尚未运行。

onCreate方法仅在创建数据库本身时自动运行,即在数据库文件的生命周期内运行一次。有3种简单的方法可以让onCreate运行,注意所有3将删除数据库中的任何现有数据

  • 卸载应用程序。
  • 清除应用程序的数据。
  • 如果onUpgrade方法删除了相应的一个或多个表,并且它调用onCreate,则可以增加数据库的版本号。

因此你需要

  • a)确保您的表格定义包含地址列(以及列姓氏名字年龄和 malefemale
  • b)让onCreate按上述三种方法中的一种运行(对于那些想要保留现有数据的人来说,还有其他解决方法)。

同样,从日志中,您可能会遇到如何在 addData 中准备数据的问题,因为您尝试将相同的数据插入到所有列中,例如Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike会导致姓氏,名字,年龄,男性女性都具有值 Mike sheesh我不知道我很受欢迎:)

查看您使用的朋友课程(例如): -

            if (firstnameinput.length() !=0) {
                AddData(firstName);
                firstnameinput.setText(""); .........

您正在将单个参数传递给AddData方法,因此可能会将此一个参数用作填充所有列的数据。

因此,您可能希望将AddData方法更改为接受5个参数(地址,姓氏,名字,年龄和男性女性),然后使用相应数据填充列。

此外,您随后会为每个数据项(男性女性除外)多次({1}}调用AddData。这将导致每次单击添加按钮添加4行。我相信你真正想要的是添加一行,你应该只用{5}或4(也许你还没有到男性女性)数据项来调用AddData一次。因此,您最终会得到一行包含所有相应的数据。

添加数据后编辑报告为正常工作。

由于您遇到了很多问题,其中许多似乎来自预先存在的代码。因此,似乎大部分代码都未经过测试。我建议采用不同的方法。基本上集中精力让事情发挥作用,然后加入其中。

因为这里的工作代码(非常基本)可以工作,并且允许你a)添加朋友(因为你可能想要选择这个来调整性别)和b)通过视图按钮列出它们。

首先 AndroidManifest.xml 注意!仅在需要时将其用于比较

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mjt.so46145559friendsdb">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".friends">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".listdata"></activity>
    </application>
</manifest>

activity_friends.xml 朋友活动的布局(非常基本没有微调器): -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="mjt.so46145559friendsdb.friends">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />
    <EditText
        android:id="@+id/firstnameinput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="firstname"
        android:inputType="text"/>
    <EditText
        android:id="@+id/lastnameinput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="lastname"
        android:inputType="text"/>
    <EditText
        android:id="@+id/ageinput"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxLength="3"
        android:inputType="number"/>
    <EditText
        android:id="@+id/addressinput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="address"
        android:inputType="text"/>
    <Button
        android:id="@+id/addbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ADD"/>
    <Button
        android:id="@+id/viewbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="VIEW"/>
</LinearLayout>

请注意!你可能现有的布局很有效。

activity_listdata.xml 单击VIEW按钮时调用 listdata 活动的布局(非常基本)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/friendslist_heading"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <ListView
        android:id="@+id/friendlist"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </ListView>
</LinearLayout>

listdataitem.xml ListView在 listdata 活动中显示的每个项目(行)使用的布局。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/firstnamedisplay"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="match_parent" />
    <TextView
        android:id="@+id/lastnamedisplay"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="match_parent" />
    <TextView
        android:id="@+id/agedisplay"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent" />
    <TextView
        android:id="@+id/addressdisplay"
        android:layout_width="0dp"
        android:layout_weight="4"
        android:layout_height="match_parent" />
</LinearLayout>

DatabaseHelper.java SQLiteOpenHelper子类,请注意已经进行了一些更改(可用于发现它们的布朗尼点):)

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String TAG = "DatabaseHelper";

    public static final String TABLE_NAME = "friends_table";
    public static final String IDCOL = "_id";
    public static final String COL1 = "firstname";
    public static final String COL2 = "lastname";
    public static final String COL3 = "malefemale";
    public static final String COL4 = "age";
    public static final String COL5 = "address";


    public DatabaseHelper (Context context) {
        super(context, TABLE_NAME, null, 1);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "CREATE TABLE " + TABLE_NAME + " (" + IDCOL+ " TEXT PRIMARY KEY, " +
                COL1 + " TEXT, " +
                COL2 + " TEXT, " +
                COL3 + " TEXT, " +
                COL4 + " INTEGER, " +
                COL5 + " TEXT " +
                ")";
        db.execSQL(createTable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP IF TABLE EXISTS" + TABLE_NAME);
        onCreate(db);
    }

    public boolean addData(String firstname, String lastname, String gender, int age, String address) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL1, firstname);
        contentValues.put(COL2, lastname);
        contentValues.put(COL3, gender);
        contentValues.put(COL4, age);
        contentValues.put(COL5, address);

        long result = db.insert(TABLE_NAME, null, contentValues);

        //if data as inserted inorrectly it will return -1
        if (result == 1)
            return false;
        else {
            return true;
        }
    }

    /**
     * Returns all data from DB
     */
    public Cursor getData() {
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME;
        return db.query(TABLE_NAME,null,null,null,null,null,null);
    }

    /**
     * Returns ID that matches the name
     * searches the DB and returns the ID associated with that name
     */
    public Cursor getItemID(String name) {
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT " + COL1 + " FROM " + TABLE_NAME +  // SELECT ID FROM DB
                " WHERE " + COL2 + " = '" + name + "'";             // WHERE THE LAST NAME = NAME SELECTED

        Cursor data = db.rawQuery(query, null);
        return data;
    }

    /**
     * Alternative means of getting ID return it as a long rather in a cursor
     */
    public long getID(String firstname) {
        long rv = 0;
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor csr = db.query(TABLE_NAME,null,COL2 + "=?",new String[]{firstname},null,null,null);
        if (csr.moveToFirst()) {
            rv = csr.getLong(csr.getColumnIndex(IDCOL));
        }
        csr.close();
        return rv;
    }

    /**
     * UPDATES THE NAME
     *
     * UPDATE TABLE > SET LASTNNAME(COL2) = newName = WHERE id = id in Question = AND LASTNAME(COL2) = oldName (was previously) >
     */
    public void updateName (String newName, int id, String oldName) {
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "UPDATE " + TABLE_NAME + " SET " + COL2 +
                " = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" +
                " AND " + COL2 + " = '" + oldName + "'";

        //LOGS THE NEW NAME
        Log.d(TAG, "updateName: query: " + query);
        Log.d(TAG, "updateName: Setting name to " + newName); // NEW NAME CHANGING IT TO
        db.execSQL(query); // EXECUTE QUERY
    }

    /**
     * DELETE FROM DATABASE
     * >>> DELETE FROM TABLE WHERE id = id passed AND name = name passed
     *
     */
    public void deleteName(int id, String name){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "DELETE FROM " + TABLE_NAME + " WHERE "
                + COL1 + " = '" + id + "'" +
                " AND " + COL2 + " = '" + name + "'";

        Log.d(TAG, "deleteName: query: " + query);
        Log.d(TAG, "deleteName: Deleting " + name + " from database.");
        db.execSQL(query); // EXECUTE QUERY
    }
}

friends.java (裸骨但它有效,美化取决于你:))

public class friends extends AppCompatActivity {
    EditText firstnameinput, lastnameinput, ageinput, addressinput;
    Button addbutton, viewbutton;
    DatabaseHelper dbhlpr;
    Context context;   //############### FIX_001

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_friends);
        context = this; //########## FIX_001

        firstnameinput = (EditText) findViewById(R.id.firstnameinput);
        lastnameinput = (EditText) findViewById(R.id.lastnameinput);
        ageinput = (EditText) findViewById(R.id.ageinput);
        addressinput = (EditText) findViewById(R.id.addressinput);
        addbutton = (Button) findViewById(R.id.addbutton);
        viewbutton = (Button) findViewById(R.id.viewbutton);

        dbhlpr = new DatabaseHelper(this);

        addbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                boolean addOK = true;
                int age_as_int = -1;

                String firstName = firstnameinput.getText().toString();
                String lastName = lastnameinput.getText().toString();
                String age = ageinput.getText().toString();
                String address = addressinput.getText().toString();

                if (firstName.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    firstnameinput.requestFocus();
                    addOK = false;
                }
                if (lastName.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    lastnameinput.requestFocus();
                    addOK = false;
                }
                if (age.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    ageinput.requestFocus();
                    addOK = false;
                }
                if (address.length() < 1) {
                    toastMessage("You must enter something in this field!");
                    addressinput.requestFocus();
                    addOK = false;
                }
                try {
                    age_as_int = Integer.parseInt(age);
                } catch (NumberFormatException e) {
                    toastMessage("You must enter a valid Number in this field!");
                    ageinput.requestFocus();
                    addOK = false;
                }

                if (addOK) {
                    dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
                    toastMessage("Friend Added!");
                }

            }
        });
        viewbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,listdata.class); //########## FIX_001
                startActivity(intent);
            }
        });

    }

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

最后是一个便宜又开朗的 listdata.java

public class listdata extends AppCompatActivity {

    ListView mListView;
    TextView firstname, lastname, age, address;
    DatabaseHelper dbhlpr;
    Cursor friendlist;
    SimpleCursorAdapter sca;

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

        mListView = (ListView) findViewById(R.id.friendlist);
        firstname = (TextView) findViewById(R.id.firstnamedisplay);
        lastname = (TextView) findViewById(R.id.lastnamedisplay);
        age = (TextView) findViewById(R.id.agedisplay);
        address = (TextView) findViewById(R.id.addressdisplay);
        dbhlpr = new DatabaseHelper(this);
        friendlist = dbhlpr.getData();
        Log.d("CURSORCOUNT","Rows in Cursor is " + friendlist.getCount());

        // make a list of the columns from which the data is to be extracted
        String[] dbcolums = {
                DatabaseHelper.COL1,
                DatabaseHelper.COL2,
                DatabaseHelper.COL4,
                DatabaseHelper.COL5
        };

        // make a list of the view's id where the data is to be placed
        //Note each column will have a respective view
        int[] listviewids = {R.id.firstnamedisplay, R.id.lastnamedisplay, R.id.agedisplay, R.id.addressdisplay};

        // Setup the Adapter
        sca = new SimpleCursorAdapter(
                this,                           // The context
                R.layout.listdataitem,          // the lasyout for an item
                friendlist,                     // cursor with data
                dbcolums,                       // the list of DB columns to get data from
                listviewids,                    // the views in the layout where to place the data
                0                               // don't worry
        );

        // Finally tie the adapter to the ListView
        mListView.setAdapter(sca);
    }
}

拿这些,甚至可能开始一个新项目, AS THEY ARE ,让它工作,然后一次添加一小部分。遇到问题时创建新问题。请不要修改问题,删除你添加的东西基本上只添加到问题。 (非常混淆比特)。也总是非常清楚已添加的内容。

按照以下方式运作: -

a)刚开始时: -

enter image description here

b)添加数据: -

enter image description here

c)查看: -

enter image description here