尝试制作一个 sqlite 数据库搜索应用程序

Trying to make a sqlite database search app

我是 Android 的新手,开发此应用已有一段时间了。我几乎是将初始值加载到包含 3 列的 sqlite 数据库中:_id、产品和成分。我有一个 EditText 框供用户搜索产品以查看它们是否含有某种成分。然后打印出一个列表视图,显示包含这些成分的产品。我在使用这段代码时遇到了一些总体问题,特别是当我 运行 它时,它显示 "Could not read row 0 col 1" 来自 logcat。

更新:多亏了托德,我解决了原来的 "Could not read row 0 and col 1" 问题,但现在当我点击带有编辑文本输入 "Apple" 的搜索按钮(应该输出一个产品)时,应用程序不会更新并保持静态。如有任何帮助,我们将不胜感激!

MySQLiteHelper.java

package com.lapetit;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class MySQLiteHelper extends SQLiteOpenHelper {

  public static final String TABLE_PRODUCTS = "products";
  public static final String COLUMN_ID = "_id";
  public static final String COLUMN_PRODUCT = "product";
  public static final String COLUMN_INGREDIENTS = "ingredients";
  private SQLiteDatabase database;

  private static final String DATABASE_NAME = "products.db";
  private static final int DATABASE_VERSION = 1;

  // Database creation sql statement
  private static final String DATABASE_CREATE = "create table "
      + TABLE_PRODUCTS + "(" + COLUMN_ID
      + " integer primary key autoincrement, " + COLUMN_PRODUCT
      + " text not null, " + COLUMN_INGREDIENTS + " text not null);";

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

  @Override
  public void onCreate(SQLiteDatabase database) {
    database.execSQL(DATABASE_CREATE);

    Cursor check = database.rawQuery("select * from products",null);

    //First Time we open Database, add default Values
    if ( check.getCount() < 1 )
    {

        database.execSQL("insert into " + TABLE_PRODUCTS + "(" + COLUMN_ID + ","
                + COLUMN_PRODUCT + "," + COLUMN_INGREDIENTS + ")" + "values(1,'Le Mieux Retinol Serum', 'Apples,Bananas,Carrots')");

        database.execSQL("insert into " + TABLE_PRODUCTS + "(" + COLUMN_ID + ","
                + COLUMN_PRODUCT + "," + COLUMN_INGREDIENTS + ")" + "values(2,'Le Mieux Essence Toner', 'Apricots, Beets, Cats')");

        database.execSQL("insert into " + TABLE_PRODUCTS + "(" + COLUMN_ID + ","
                + COLUMN_PRODUCT + "," + COLUMN_INGREDIENTS + ")" + "values(3,'Le Mieux Body Wash', 'Alcohol, Marijuana, Meth')");

    }
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.w(MySQLiteHelper.class.getName(),
        "Upgrading database from version " + oldVersion + " to "
            + newVersion + ", which will destroy all old data");
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
    onCreate(db);
  }


}

Products.java

package com.lapetit;

public class Products {
      private long id;
      private String product;
      private String ingredient;

      public long getId() {
        return id;
      }

      public void setId(long id) {
        this.id = id;
      }

      public String getProduct() {
        return product;
      }

      public void setProduct(String product) {
        this.product = product;
      }

      public String getIngredients() {
            return product;
      }

      public void setIngredients(String ingredient) {
          this.ingredient = ingredient;
      }

      // Will be used by the ArrayAdapter in the ListView
      @Override
      public String toString() {
        return product;
      }

    } 

ProductsDataSource.java

    package com.lapetit;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class ProductsDataSource {

  // Database fields
  private SQLiteDatabase database;
  private MySQLiteHelper dbHelper;
  private String[] allColumns = { MySQLiteHelper.COLUMN_ID,
      MySQLiteHelper.COLUMN_PRODUCT,
      MySQLiteHelper.COLUMN_INGREDIENTS};

  public ProductsDataSource(Context context) {
    dbHelper = new MySQLiteHelper(context);
  }

  public void open() throws SQLException {
    database = dbHelper.getWritableDatabase();
  }

  public void close() {
    dbHelper.close();
  }


  public List<Products> getAllProducts() {
    List<Products> products = new ArrayList<Products>();

    Cursor cursor = database.query(MySQLiteHelper.TABLE_PRODUCTS,
        allColumns, null, null, null, null, null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
      Products product = cursorToProduct(cursor);
      products.add(product);
      cursor.moveToNext();
    }
    // make sure to close the cursor
    cursor.close();
    return products;
  }



  //Search queries
  public List<Products> getSearchedProducts(String search) {
      List<Products> products = new ArrayList<Products>();

      String[] args = new String[1];
      args[0] = "%"+search+"%";
      Cursor cursor = database.rawQuery("SELECT product FROM products, _id WHERE ingredients like ?", args);

      cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
          Products product = cursorToProduct(cursor);
          products.add(product);
          cursor.moveToNext();
        }

      cursor.close();
      return products;
  }


  private Products cursorToProduct(Cursor cursor) {
    Products product = new Products();
    product.setId(cursor.getLong(0));
    product.setProduct(cursor.getString(1));
    return product;
  }


} 

WithActivity.java

package com.lapetit;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.EditText;
import android.view.View.OnClickListener;
import android.widget.ImageView;


public class WithActivity extends ListActivity {
      private ProductsDataSource datasource;
      private ArrayAdapter adapter;

      List<Products> values = new ArrayList<Products>();

      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.with);


        EditText inputSearch = (EditText) findViewById(R.id.text);

        datasource = new ProductsDataSource(this);
        datasource.open();




        ArrayAdapter<Products> adapter = new ArrayAdapter<Products>(this,
                android.R.layout.simple_list_item_1, values);
        setListAdapter(adapter);

      }

      public void onClick(View view) {

            ArrayAdapter<Products> adapter = (ArrayAdapter<Products>) getListAdapter();
            Products product = null;

            switch (view.getId()) {
            case R.id.search:

                EditText inputSearch = (EditText) findViewById(R.id.text);

                String stringinput = (String)inputSearch.getText().toString();
                List<Products> values = datasource.getSearchedProducts(stringinput);


              break;
            }

            adapter.notifyDataSetChanged();
          }


      @Override
      protected void onResume() {
        datasource.open();
        super.onResume();
      }

      @Override
      protected void onPause() {
        datasource.close();
        super.onPause();
      }

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

with.xml

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


    <EditText
        android:id="@+id/text"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:hint="Search products.."
        android:inputType="text" />

    <Button
            android:id="@+id/search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Search" 
            android:onClick="onClick"/>


  <ListView
      android:id="@android:id/list"
      android:layout_width="fill_parent"
      android:layout_height="400dp" />

</LinearLayout>

Failed to read row 0, column 1 from a CursorWindow which has 3 rows, 1 columns.

我认为您的查询需要 return 更多列...

getSearchedProducts()你select只有产品栏:

// Select a single column.
Cursor cursor = database.rawQuery("SELECT product FROM products WHERE ingredients like ?", args);

但在 cursorToProduct() 中您阅读了两列(ID 和 Product):

product.setId(cursor.getLong(0));
product.setProduct(cursor.getString(1));

您似乎需要将 Id 添加到查询中。

Cursor cursor = database.rawQuery("SELECT id, product FROM products WHERE ingredients like ?", args);