尝试保存约会信息时,应用程序会不断崩溃?

时间:2018-04-18 15:22:13

标签: java android android-sqlite android-cursor

我正在为一家理发店建立一个应用程序,我现在正在创建一个约会并保存该约会的数据,但是当我去点击添加创建约会时,应用程序崩溃了我离开了这个错误;

Condition 1 - If at least one rate IN (0.01, 0.015, 0.05) for this ID THEN replace all 0 values by the most rate values (e.g. if for this ID, 0.01 appears more than 0.05 then replace 0 with 0.01. Only rates == 0 rows can be replaced)

Condition 2 - If rates NOT IN (0.01, 0.015, 0.05) then make no changes to the rows

这是 TableControllerAppointments.java

的课程
E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 2 rows, 3 columns.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: ie.app.barbershop, PID: 31270
                  java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
                      at android.database.CursorWindow.nativeGetString(Native Method)
                      at android.database.CursorWindow.getString(CursorWindow.java:438)
                      at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
                      at ie.app.barbershop.TableControllerAppointments.read(TableControllerAppointments.java:46)
                      at ie.app.barbershop.Landing.readRecords(Landing.java:47)
                      at ie.app.barbershop.OnClickListenerCreateAppointment$1.onClick(OnClickListenerCreateAppointment.java:38)
                      at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:135)
                      at android.app.ActivityThread.main(ActivityThread.java:5254)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:372)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I/Process: Sending signal. PID: 31270 SIG: 9
Application terminated.

这是我的 OnClickListenerCreateAppointment.java

的课程
package ie.app.barbershop;

import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;

public class TableControllerAppointments extends DatabaseHandler {

    public TableControllerAppointments(Context context) {
        super(context);
    }

    public boolean create(ObjectAppointment objectAppointments) {

        ContentValues values = new ContentValues();

        values.put("fullname", objectAppointments.fullName);
        values.put("contactno", objectAppointments.contactNumber);

        SQLiteDatabase db = this.getWritableDatabase();

        boolean createSuccessful = db.insert("appointments", null, values) > 0;
        db.close();

        return createSuccessful;
    }



    public List<ObjectAppointment> read() {

        List<ObjectAppointment> recordsList = new ArrayList<>();

        String sql = "SELECT * FROM Appointments ORDER BY id DESC";

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(sql, null);

        if (cursor.moveToFirst()) {
            do {

                String fullName = cursor.getString(cursor.getColumnIndex("firstname"));
                int contactNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex("contactno")));

                ObjectAppointment objectAppointment = new ObjectAppointment();
                objectAppointment.fullName = fullName;
                objectAppointment.contactNumber = contactNumber;

                recordsList.add(objectAppointment);

            } while (cursor.moveToNext());
        }

        cursor.close();
        db.close();

        return recordsList;
    }

    public int count() {

        SQLiteDatabase db = this.getWritableDatabase();

        String sql = "SELECT * FROM appointments";
        int recordCount = db.rawQuery(sql, null).getCount();
        db.close();

        return recordCount;
    }
}

这是我的 Landing.java类

package ie.app.barbershop;

import android.view.View;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.Toast;

public class OnClickListenerCreateAppointment implements View.OnClickListener {

    public ObjectAppointment objectAppointment;

    @Override
    public void onClick(View view){

        final Context context = view.getRootView().getContext();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        final View formElementsView = inflater.inflate(R.layout.appointment_input_form, null, false);
        final EditText editTextFullName = formElementsView.findViewById(R.id.editTextFullName);
        final EditText editTextContactNumber = formElementsView.findViewById(R.id.editTextContactNumber);

        ObjectAppointment objectAppointment = new ObjectAppointment();


        new AlertDialog.Builder(context)




                .setView(formElementsView)
                .setTitle("Create Appointment")
                .setPositiveButton("Add",
                        new DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog, int id) {


                                String fullname = editTextFullName.getText().toString();
                                String contactno = editTextContactNumber.getText().toString();

                                ((Landing) context).countRecords();
                                ((Landing) context).readRecords();

                                dialog.cancel();
                            }

                        }).show();

            boolean createSuccessful = new TableControllerAppointments(context).create(objectAppointment);

                if(createSuccessful){
                    Toast.makeText(context, "Appointment Information was saved.", Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(context, "Unable to save appointment information", Toast.LENGTH_SHORT).show();
        }


    }
}

数据库处理程序类

package ie.app.barbershop;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import java.util.List;


public class Landing extends AppCompatActivity{

    public Button buttonProducts;

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

        countRecords();

        buttonProducts = findViewById(R.id.buttonProducts);

        Button buttonCreateAppointment = findViewById(R.id.buttonCreateAppointment);
        buttonCreateAppointment.setOnClickListener(new OnClickListenerCreateAppointment());

        buttonProducts.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Landing.this, Products.class));
            }
        });


    }

    public void readRecords() {

        LinearLayout linearLayoutRecords = findViewById(R.id.linearLayoutRecords);
        linearLayoutRecords.removeAllViews();

        List<ObjectAppointment> appointments = new TableControllerAppointments(this).read();

        if (appointments.size() > 0) {

            for (ObjectAppointment obj : appointments) {


                String fullName = obj.fullName;
                int contactNumber = obj.contactNumber;

                String textViewContents = fullName + " - " + contactNumber;

                TextView textViewAppointmentItem= new TextView(this);
                textViewAppointmentItem.setPadding(0, 10, 0, 10);
                textViewAppointmentItem.setText(textViewContents);
                textViewAppointmentItem.setTag(Integer.toString(contactNumber));

                linearLayoutRecords.addView(textViewAppointmentItem);
            }

        }

        else {

            TextView locationItem = new TextView(this);
            locationItem.setPadding(8, 8, 8, 8);
            locationItem.setText("No records yet.");

            linearLayoutRecords.addView(locationItem);
        }

    }

    public void countRecords(){

        int recordCount = new TableControllerAppointments(this).count();

        TextView textViewRecordCount = findViewById(R.id.textViewRecordCount);
        textViewRecordCount.setText(recordCount + " records found.");

    }
}

1 个答案:

答案 0 :(得分:0)

从getColumnIndex返回-1意味着列 firstname 在下一行的光标中不存在。

 String fullName = cursor.getString(cursor.getColumnIndex("firstname"));

使用以下方法创建表: -

String sql = "CREATE TABLE appointments " +
                "( id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "fullname TEXT, " +
                "contactno NUMBER ) ";

其中列为id fullname和contactno。

-

修复

要修复此更改以使用: -

String fullName = cursor.getString(cursor.getColumnIndex("fullname"));

其他

最好还是将列和表名定义为常量,并始终引用它们。

e.g。

public class DatabaseHandler extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    protected static final String DATABASE_NAME = "AppointmentDatabase";

    public static final String TABLE_NAME = "appointments";
    public static final String COL_ID = "id";
    public static final String COl_FULLNAME = "fullname";
    public static final String COL_CONTACTNO = "contactno";

    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String sql = "CREATE TABLE " + TABLE_NAME +
                "( " + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_FULLNAME + " TEXT, " +
                COL_CONTACTNO + " NUMBER ) ";

        db.execSQL(sql);

    }
    .... and so on

以后作为一个例子: -

    String fullName = cursor.getString(cursor.getColumnIndex(DatabaseHandler.COL_FULLNAME));