尝试制作一个 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);
我是 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);