I wanna create a recyclerview which can retrieve data from database, and followed this video step by step. The application "has stopped" when I tried to run it.I I have no idea where I got it wrong. Please help.
activity_main.xml
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:padding="16dp">
<EditText
android:id="#+id/edittext_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textviewamount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/edittext_name"
android:layout_centerHorizontal="true"
android:text="0"
android:textSize="50sp"
android:layout_marginTop="8dp"
/>
<Button
android:id="#+id/button_decrease"
android:layout_width="50dp"
android:layout_height="72dp"
android:layout_alignTop="#+id/textviewamount"
android:layout_toStartOf="#+id/textviewamount"
android:layout_toLeftOf="#+id/textviewamount"
android:text="-" />
<Button
android:id="#+id/button_increase"
android:layout_width="50dp"
android:layout_height="72dp"
android:layout_alignTop="#+id/textviewamount"
android:layout_toEndOf="#+id/textviewamount"
android:layout_toRightOf="#+id/textviewamount"
android:text="+" />
<Button
android:id="#+id/button_add"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:layout_alignEnd="#+id/edittext_name"
android:layout_alignRight="#+id/edittext_name"
android:layout_alignTop="#+id/textviewamount" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/button_decrease"
android:layout_centerHorizontal="true">
</android.support.v7.widget.RecyclerView>
grocery_item.xml
android:layout_margin="8dp"
>
<TextView
android:id="#+id/textview_amount_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="30sp"
/>
<TextView
android:id="#+id/textview_name_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty Item"
android:textSize="30sp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
/>
MainActivity.java
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private SQLiteDatabase mDatabase;
private GroceryAdapter mAdapter;
private EditText mEditTextName;
private TextView mTextViewAmount;
private int mAmount = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GroceryDBHelper dbHelper = new GroceryDBHelper(this);
mDatabase = dbHelper.getWritableDatabase();
//能往database里写数据的必须语句
RecyclerView recyclerView = findViewById(R.id.recyclerview);
//MainActivit.xml里的recyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new GroceryAdapter(this,getAllItems());
//cursor的位置放getAllItems方法来传指针
recyclerView.setAdapter(mAdapter);
mEditTextName = findViewById(R.id.edittext_name);
mTextViewAmount = findViewById(R.id.textview_amount_item);
Button buttonIncrease = findViewById(R.id.button_increase);
Button buttonDecrease = findViewById(R.id.button_decrease);
Button buttonAdd = findViewById(R.id.button_add);
buttonIncrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
increase();
}
});
buttonDecrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
decrease();
}
});
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItem();
}
});
}
private void increase()
{
mAmount++;
mTextViewAmount.setText(String.valueOf(mAmount));
}
private void decrease() {
if (mAmount > 0) {
mAmount--;
mTextViewAmount.setText(String.valueOf(mAmount));
}
}
private void addItem()
//往database里加item的方法
{
if (mEditTextName.getText().toString().trim().length() == 0 || mAmount == 0)
//trim:删除句首和句尾的空格
{
return;
//如果每输入或输入数量为0,就不添加item,直接返回additem方法
}
String name = mEditTextName.getText().toString();
ContentValues cv = new ContentValues();
cv.put(GroceryContract.GroceryEntry.COLUMN_NAME, name);
//将name放入database的name column里
cv.put(GroceryContract.GroceryEntry.COLUMN_AMOUNT, mAmount);
//将数量放入database的amount column里
//无需手动添加id和stamp,会自动添加
mDatabase.insert(GroceryContract.GroceryEntry.TABLE_NAME,null, cv);
//将cv放入database的table里
mAdapter.swapCursor(getAllItems());
//添加新item后转换指针
mEditTextName.getText().clear();
//清空输入栏
}
private Cursor getAllItems()
{
return mDatabase.query(
GroceryContract.GroceryEntry.TABLE_NAME,
null,
null,
null,
null,
null,
GroceryContract.GroceryEntry.COLUMN_TIMESTAMP + " DESC"
//decending order
);
}
}
GroceryDBHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.playah.recyclerdatabase.GroceryContract.*;
public class GroceryDBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "grocerylist.db";
public static final int DATABASE_VERSION = 1;
//这个数字是database的scheme
public GroceryDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_GROCERYLIST_TABLE = "CREATE TABLE "+
GroceryEntry.TABLE_NAME + " (" +
GroceryEntry._ID + "INTEGER PRIMARY KEY AUTOINCREMENT, "+
//ID没创建,但是已经GroceryContract.java里通过BaseColumn引入
//primary key:unique identify of the row
//autoincrement: 每往table加一行就添加一次
GroceryEntry.COLUMN_NAME + "TEXT NOT NULL," +
//not null: we have to provide a value
GroceryEntry.COLUMN_AMOUNT + "INTEGER NOT NULL," +
GroceryEntry.COLUMN_TIMESTAMP +"TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
//每往table加一行就在当前位置创建一次time stamp
");";
db.execSQL(SQL_CREATE_GROCERYLIST_TABLE);
//执行创建database
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + GroceryEntry.TABLE_NAME);
//如果database已存在,drop并重建
onCreate(db);
}
}
**GroceryContract**
import android.provider.BaseColumns;
public class GroceryContract
{ private GroceryContract() {}
//引入interface
public static final class GroceryEntry implements BaseColumns {
//展示table的id columns
public static final String TABLE_NAME = "groceryList";
//table name
public static final String COLUMN_NAME = "name";
//first column of the table
public static final String COLUMN_AMOUNT = "amount";
//amount of the item
public static final String COLUMN_TIMESTAMP = "timestemp";
}
}
GroceryContract.java
import android.provider.BaseColumns;
public class GroceryContract
//为table定义字符实体和行数
{ private GroceryContract() {}
//用的是下面的方法,用不到这个方法来构造函数
//引入interface
public static final class GroceryEntry implements BaseColumns {
//展示table的id columns
public static final String TABLE_NAME = "groceryList";
//table name
public static final String COLUMN_NAME = "name";
//first column of the table
public static final String COLUMN_AMOUNT = "amount";
//amount of the item
public static final String COLUMN_TIMESTAMP = "timestemp";
//改变item的数量
}
}
GroceryAdapter.java
import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class GroceryAdapter extends RecyclerView.Adapter<GroceryAdapter.GroceryViewHolder> {
private Context mContext;
private Cursor mCursor;
public GroceryAdapter(Context context, Cursor cursor)
//cursor使能够从database取出数据
{
mContext = context;
mCursor = cursor;
}
public class GroceryViewHolder extends RecyclerView.ViewHolder
{
public TextView nameText;
public TextView countText;
public GroceryViewHolder(#NonNull View itemView) {
super(itemView);
nameText = itemView.findViewById(R.id.textview_name_item);
countText = itemView.findViewById(R.id.textview_amount_item);
}
}
#NonNull
#Override
public GroceryViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.grocery_item, parent, false);
//使用recyclervew的layout
return new GroceryViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull GroceryViewHolder holder, int position) {
if (!mCursor.moveToPosition(position)){
//判断cursor是否存在
return;
}
String name = mCursor.getString(mCursor.getColumnIndex(GroceryContract.GroceryEntry.COLUMN_NAME));
int amount = mCursor.getInt(mCursor.getColumnIndex(GroceryContract.GroceryEntry.COLUMN_AMOUNT));
//从database中取得上面两种数据
holder.nameText.setText(name);
holder.countText.setText(String.valueOf(amount));
}
#Override
public int getItemCount() {
return mCursor.getCount();
}
public void swapCursor(Cursor newCursor)
//转换cursor,为了使数据库更新后cursor在正确的位置
{
if (mCursor !=null){
mCursor.close();
}
mCursor = newCursor;
if(newCursor != null){
notifyDataSetChanged();
}
}
Here is the logcat
--------- beginning of crash
08-13 15:51:49.125 5572-5572/com.playah.recyclerdatabase E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.playah.recyclerdatabase, PID: 5572
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.playah.recyclerdatabase/com.playah.recyclerdatabase.MainActivity}: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY (code 1): , while compiling: CREATE TABLE groceryList (_idINTEGER PRIMARY KEY AUTOINCREMENT, nameTEXT NOT NULL,amountINTEGER NOT NULL,timestempTIMESTAMP DEFAULT CURRENT_TIMESTAMP);
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY (code 1): , while compiling: CREATE TABLE groceryList (_idINTEGER PRIMARY KEY AUTOINCREMENT, nameTEXT NOT NULL,amountINTEGER NOT NULL,timestempTIMESTAMP DEFAULT CURRENT_TIMESTAMP);
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1677)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1608)
at com.playah.recyclerdatabase.GroceryDBHelper.onCreate(GroceryDBHelper.java:33)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:294)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194)
at com.playah.recyclerdatabase.MainActivity.onCreate(MainActivity.java:35)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Add space before INTEGER in double qots
GroceryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
It looks like your CREATE clause misses spaces between the column names and their types.
Try to add a blank space after the column ids, like this :
GroceryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
Right before the keyword "INTEGER". Do the same for the other lines.
Related
hoping someone can help me figure this issue out. I'm trying to build an app in Android Studio for school and am running into an issue when trying to get it to load results from a database using a cursor. I keep getting the error message that the cursor is initialized at -1 and it can't access column 0. Any ideas what might be causing it? Code is below along with error message:
Main Activity:
package com.example.lab2;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.the_button);
EditText input = findViewById(R.id.edittext);
Switch urgent = findViewById(R.id.the_switch);
dbOpener dbOpener = new dbOpener(MainActivity.this);
Cursor cursor;
ListView thisList = (ListView) findViewById(R.id.listview);
AlertDialog.Builder alertDIalogBuilder = new AlertDialog.Builder(this);
ArrayList<toDoItem> arrayList = new ArrayList<toDoItem>();
class MyAdapter extends BaseAdapter {
private Context context;
private ArrayList<toDoItem> items;
public MyAdapter(Context context, ArrayList<toDoItem> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View mainView = LayoutInflater.from(context).inflate(R.layout.activity_main_todolayout, parent, false);
LayoutInflater inflater = getLayoutInflater();
if(mainView == null) {
mainView = inflater.inflate(R.layout.activity_main_todolayout, parent, false);
}
TextView itemView = mainView.findViewById(R.id.to_do_items);
itemView.setText((arrayList.get(position).getToDoName().toString()));
if(arrayList.get(position).geturgent() == true) {
mainView.setBackgroundColor(Color.RED);
itemView.setTextColor(Color.WHITE);
}
return mainView;}
};
MyAdapter adapter = new MyAdapter(this, arrayList);
thisList.setAdapter(adapter);
urgent.setChecked(false);
urgent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View V) {
urgent.setChecked(true);
}
});
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String holder = input.getText().toString();
arrayList.add (new toDoItem(holder, urgent.isChecked()));
input.getText().clear();
adapter.notifyDataSetChanged();
int urgentStatus = 0;
if(urgent.isChecked() == true) {
urgentStatus = 1;
} else {
urgentStatus = 0;
}
dbOpener.addItem(holder, urgentStatus);
urgent.setChecked(false);
}
});
thisList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
String title = getString(R.string.alert_dialogue_title);
String message = getString(R.string.alert_dialogue_message);
String pos_button = getString(R.string.pos_button);
String neg_button = getString(R.string.neg_button);
alertDIalogBuilder.setTitle(title);
alertDIalogBuilder.setMessage(message + " " + position);
alertDIalogBuilder.setPositiveButton(pos_button, (click, arg) -> {
arrayList.remove(position);
adapter.notifyDataSetChanged();
});
alertDIalogBuilder.setNegativeButton(neg_button, (click, arg) -> {
});
alertDIalogBuilder.create();
alertDIalogBuilder.show();
return false;
}
});
cursor = dbOpener.readData();
int nameColIndex = cursor.getColumnIndex("COL_ITEM_NAME");
int urgentColIndex = cursor.getColumnIndex("COL_URGENT");
int idColIndex = cursor.getColumnIndex("COL_ID");
for(int i = 0; i < cursor.getCount(); i++) {
String name = cursor.getString(nameColIndex);
int urgentHolder = cursor.getInt(urgentColIndex);
long id = cursor.getLong(idColIndex);
boolean converter = false;
if(urgentHolder == 1) {
converter = true;
} else {
converter = false;
}
arrayList.add(new toDoItem(name, converter));
}
}
}
Database Opener:
package com.example.lab2;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class dbOpener extends SQLiteOpenHelper {
protected final static String DATABASE_NAME = "toDoListDB";
protected final static int VERSION_NUM = 1;
public final static String TABLE_NAME = "TO_DO_ITEMS";
public final static String COL_ITEM_NAME = "ITEM";
public final static String COL_URGENT = "URGENT";
public final static String COL_ID = "_id";
private Context ctx;
String [] columns = {dbOpener.COL_ITEM_NAME, dbOpener.COL_ITEM_NAME, dbOpener.COL_URGENT};
public dbOpener(Context ctx) {super(ctx, DATABASE_NAME, null, VERSION_NUM);
this.ctx = ctx;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_ITEM_NAME
+ " TEXT," + COL_URGENT + " INTEGER)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addItem(String itemName, int urgent) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cnt = new ContentValues();
cnt.put(COL_ITEM_NAME, itemName);
cnt.put(COL_URGENT, urgent);
long result = db.insert(TABLE_NAME, null, cnt);
if(result == -1) {
Toast.makeText(ctx, "Failure", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx, "Success", Toast.LENGTH_SHORT).show();
}
}
Cursor readData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor results = db.rawQuery("SELECT * from " + TABLE_NAME, null);
return results;
}
}
Error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lab2, PID: 15645
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lab2/com.example.lab2.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.lab2.MainActivity.onCreate(MainActivity.java:152)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 15645 SIG: 9
Disconnected from the target VM, address: 'localhost:49568', transport: 'socket'
You've defined your schema with these constants:
public final static String TABLE_NAME = "TO_DO_ITEMS";
public final static String COL_ITEM_NAME = "ITEM";
public final static String COL_URGENT = "URGENT";
public final static String COL_ID = "_id";
But you're using the names of the constants here rather than their values:
int nameColIndex = cursor.getColumnIndex("COL_ITEM_NAME");
int urgentColIndex = cursor.getColumnIndex("COL_URGENT");
int idColIndex = cursor.getColumnIndex("COL_ID");
In other words, in MainActivity, do this:
int nameColIndex = cursor.getColumnIndex(dbOpener.COL_ITEM_NAME);
int urgentColIndex = cursor.getColumnIndex(dbOpener.COL_URGENT);
int idColIndex = cursor.getColumnIndex(dbOpener.COL_ID);
Also, classes start with capital letters. You should rename dbOpener to DbOpener.
In your cursor-reading for loop, you need to move the cursor in order to iterate over the result set. An easy fix there would be to change
for(int i = 0; i < cursor.getCount(); i++) {
to
while(cursor.moveToNext()) {
There are other issues in your code such as the one pointed out by Gavin Wright in his answer. Missing moveTo...() is the reason for the crash you've reported.
My app has a registration screen for blood donors and the blood type field is a spinner. I save all the donor information in an SQLite database. Now I need to retrieve it and show it for a list showing all the registered blood donors with their blood types.
How can I do that?
I've attached all my code below. The main problems appear in RegisterActivity.java and DonorList.java.
RegisterActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity {
EditText edtname, edtnumber;
Spinner spblood;
Button btnregister, btnlist;
public static SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
Spinner spinner = findViewById(R.id.blood_selector);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
sqLiteHelper = new SQLiteHelper(this, "Donors.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)");
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
DonorList.java
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
public class DonorList extends AppCompatActivity {
ListView listView;
ArrayList<Donor> list;
DonorListAdapter adapter = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.activity_main, list);
listView.setAdapter(adapter);
Cursor cursor = RegisterActivity.sqLiteHelper.getData("SELECT * FROM DONORS");
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
Donor.java
import android.widget.Spinner;
public class Donor {
private String name;
private String number;
private Spinner blood;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Spinner getBlood() {
return blood;
}
public void setBlood(Spinner blood) {
this.blood = blood;
}
public Donor(String name, String number, Spinner blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
SQLiteHelper.java
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.Spinner;
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql) {
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String name, String number, Spinner blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood.getSelectedItem().toString());
statement.executeInsert();
}
public Cursor getData(String sql) {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
DonorListAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class DonorListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
row = inflater.inflate(layout, null);
}
if (row != null) {
holder.txtname = row.findViewById(R.id.name_input);
}
if (row != null) {
holder.txtnumber = row.findViewById(R.id.numberinput);
}
if (row != null) {
holder.txtblood = (TextView) row.findViewById(R.id.blood_selector);
}
if (row != null) {
row.setTag(holder);
}
}
else {
holder = (ViewHolder) row.getTag();
}
Donor donor = donorList.get(position);
holder.txtname.setText(donor.getName());
holder.txtnumber.setText(donor.getNumber());
holder.txtblood.setText(donor.getBlood().toString());
return row;
}
}
activity_main.xml
<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="com.lumen.dayem.blooddonor.MainActivity">
<ListView
android:id="#+id/contacts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
activity_register.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">
<EditText
android:id="#+id/name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/person_name"
android:ems="10"
android:inputType="textCapWords"
android:layout_marginBottom="5sp" />
<EditText
android:id="#+id/numberinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint"
android:ems="10"
android:inputType="phone"
android:layout_marginBottom="5sp" />
<TextView
android:id="#+id/blood"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/blood_type"
android:layout_marginBottom="10sp"/>
<Spinner
android:id="#+id/blood_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/blood_type"
android:prompt="#string/blood_select"
android:layout_marginBottom="5sp"/>
<Button
android:id="#+id/register_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/register" />
<Button
android:id="#+id/list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/show_donors" />
</LinearLayout>
contact_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/contact_name"
android:textSize="22sp"/>
<TextView
android:id="#+id/contact_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceSmall"
android:text="#string/contact_number"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="29sp"
android:layout_marginStart="29sp"
android:layout_marginTop="31sp" />
<TextView
android:id="#+id/contact_blood"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceMedium"
android:text="#string/blood_type"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="300sp"
android:layout_marginStart="300sp"
android:layout_marginTop="30sp"/>
</RelativeLayout>
Your class Donor seems to have a field blood of type Spinner. I changed the type to String because a data class should not contain any Views:
public class Donor
{
private String name;
private String number;
private String blood;
// Getters and Setters here...
public Donor(String name, String number, String blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
The SQLiteHelper should have a static getInstance() method so you can avoid having it as a static field in RegisterActivity. Also, I think that the database setup should be encapsulated. The Activity does not need to know anything about the database implementation. So I moved the DDL to the SQLiteHelper's onCreate() and dropped queryData(). For the same reason, I changed getData(String sql) to getDonors(). Lastly, insertData() should take data as parameters not Views. So one should not pass the Spinner but the selected item's value.
My version of SQLiteHelper.java:
public class SQLiteHelper extends SQLiteOpenHelper{
private static SQLiteHelper sqliteHelper;
private static String dbName = "Donors.sqlite";
private static int version = 1;
private static final String CREATE_TABLE_DONORS = "CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)";
/**
* We use the application Context under the hood because this helps to avoid Exceptions
* #param ctx
*/
private SQLiteHelper(Context ctx){
super(ctx.getApplicationContext(), dbName, null, version);
}
/**
* SQLiteHelper as a Singleton
* #param ctx any Context
* #return x
*/
public static SQLiteHelper getInstance(Context ctx)
{
if(sqliteHelper == null){
sqliteHelper = new SQLiteHelper(ctx);
}
return sqliteHelper;
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_DONORS);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// necessary if you have a new database version
}
public void insertData(String name, String number, String blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood);
statement.executeInsert();
}
public Cursor getDonors() {
String sql = "SELECT * FROM DONORS";
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
The updated RegisterActivity.java (note that I got rid of the local variable spinner and only used spblood):
public class RegisterActivity extends AppCompatActivity
{
private EditText edtname, edtnumber;
private Spinner spblood;
private Button btnregister, btnlist;
private SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spblood.setAdapter(adapter);
sqLiteHelper = SQLiteHelper.getInstance(this);
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood.getSelectedItem().toString()
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
The changes to DonorList and the Adapter are due to the changes I made to SQLiteHelper and Donor. In addition to that, you need to pass the resource id of the list row to the Adapter's Constructor not the resource id of the Activity's layout. Similarly, the R.id.... values for the TextViews in the list row have to match those in contact_item.xml
DonorList.java
public class DonorList extends AppCompatActivity
{
private ListView listView;
private ArrayList<Donor> list;
private DonorListAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.contact_item, list);
listView.setAdapter(adapter);
Cursor cursor = SQLiteHelper.getInstance(this).getDonors();
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
And finally, the Adapter:
public class DonorListAdapter extends BaseAdapter
{
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
ViewHolder holder = new ViewHolder();
row = LayoutInflater.from(context).inflate(layout, null);
holder.txtname = (TextView)row.findViewById(R.id.contact_name);
holder.txtnumber = (TextView)row.findViewById(R.id.contact_number);
holder.txtblood = (TextView) row.findViewById(R.id.contact_blood);
row.setTag(holder);
}
ViewHolder viewHolder = (ViewHolder) row.getTag();
Donor donor = donorList.get(position);
viewHolder.txtname.setText(donor.getName());
viewHolder.txtnumber.setText(donor.getNumber());
viewHolder.txtblood.setText(donor.getBlood());
return row;
}
}
Enjoy!
I am new to android , I creating an app for sql , its a simple app where user enters a name and the name appears on the display using a textview but unfortunately text is not displaying
Here is the code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.ashis.mmm.MainActivity">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/editText"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="52dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
</RelativeLayout>
MainActivity.java
package com.example.ashis.mmm;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editText;
Button button;
TextView textView;
Database db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText=(EditText) findViewById(R.id.editText);
button=(Button) findViewById(R.id.button);
textView=(TextView) findViewById(R.id.textView);
db = new Database(getApplicationContext(),null,null,1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String input = editText.getText().toString() ;
Person person = new Person(input);
db.add_row(person);
editText.setText("");
printDatabse();
}
});
}
private void printDatabse() {
String dbString = db.printData();
textView.setText(dbString);
}
}
Person.java
package com.example.ashis.mmm;
/**
* Created by ashis on 8/27/2016.
*/
public class Person {
private int _id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DataBase.java
package com.example.ashis.mmm;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by ashis on 8/27/2016.
*/
public class Database extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "persons.db";
private static final String TABLE_NAME = "Persons";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "Name";
public Database(Context context, String DATABASE_NAME, SQLiteDatabase.CursorFactory factory, int DATABASE_VERSION) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String onCreate = "CREATE TABLE " + TABLE_NAME + "( " +
COLUMN_ID + " INTEGER ," +
COLUMN_NAME + " TEXT );";
db.execSQL(onCreate);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
public void add_row(Person person)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, person.getName());
db.insert(TABLE_NAME, null, values);
db.close();
}
public String printData()
{
String dbqry = "";
SQLiteDatabase db = getReadableDatabase();
String printqry = "SELECT * FROM " + TABLE_NAME;
Cursor cursor = db.rawQuery(printqry,null);
cursor.moveToFirst();
while (!cursor.isAfterLast())
{
if (cursor.getString(cursor.getColumnIndex("Name")) != null)
{
dbqry += cursor.getString(1);
dbqry +="\n";
}
}
db.close();
cursor.close();
return dbqry;
}
}
the best way to see why the text is not appearing inside your TextView is to debug, but it seems that you are not so good to do it. In this case you can use Log.d(); method. I will suggest to you the places where you may have problems, just put some logs on those places and check what is happening with your variable and values.
Check does your TextView is visible on the screen and does some other view is not cover it. You can do that for example by setting some background colour of the textview and some fixed width and height (50dp), this will show you the TextView.
Inside printData() method put some logs to see what is coming from the DB, just to print your string values;
Check the Cursor inside printData() just to be sure that it contains some records , maybe your DB name is wrong or DB table is wrong or something else.
If your view is visible on the screen and printData() method is working you will not have any other problems to see the text!
Good Day everyone. I have this code and i face problem in deleting. For example, my list of names are Junko, Gemina and Fukar. If i view each, they show same details. Now, if I delete any of them, ex. I delete Fukar, it will be deleted successfully but when I click on Gemina, the detail that appears is of Junko. If i click Junko, it says "Unfortunately the app stopped working". If I add new Name, ex. Nimrod, It will add successfully, but when i view Nimrod, the detail of Gemina will appear. And if i add another name, Vourin, the data of Gemina will appear its like their ids are interchanged and I think the error is in the delete part. I appreciate any comment. Thanks.
Below is my DBHelper.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.HashMap;
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "contactdb.sqlite";
public static final String CONTACTS_TABLE_NAME = "mycontacts";
public static final String CONTACTS_COLUMN_ID = "id";
public static final String CONTACTS_COLUMN_STUNAME = "name";
public static final String CONTACTS_COLUMN_STUPHONE = "phone";
public static final String CONTACTS_COLUMN_STUSTREET = "street";
public static final String CONTACTS_COLUMN_STUEMAIL = "email";
public static final String CONTACTS_COLUMN_STUCITY = "place";
private HashMap hp;
public DBHelper(Context context)
{
super(context, DATABASE_NAME , null, 3);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"create table mycontacts " +
"(id integer primary key autoincrement, name text,phone text,email text, street text,place text)"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS mycontacts");
onCreate(db);
}
public boolean addStudentContact(String contactname,String contactphone,String contactstreet,String contactemail, String contactplace){
/*,*/
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contantValues = new ContentValues();
contantValues.put("name",contactname);
contantValues.put("phone", contactphone);
contantValues.put("street",contactstreet);
contantValues.put("email",contactemail);
contantValues.put("place",contactplace);
db.insert("mycontacts", null, contantValues);
db.close();
return true;
}
public boolean updateStudentContact(Integer contactid,String contactname,String contactphone,String contactstreet,String contactemail, String contactplace)
{
/*,String contactname,*/
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contantValues = new ContentValues();
contantValues.put("name",contactname);
contantValues.put("phone", contactphone);
contantValues.put("street",contactstreet);
contantValues.put("email",contactemail);
contantValues.put("place",contactplace);
db.update("mycontacts", contantValues, "id = ?", new String[]{Integer.toString(contactid)});
db.close();
return true;
}
public Integer deleteContact(Integer id){
SQLiteDatabase db=this.getWritableDatabase();
return db.delete("mycontacts","id = ?",new String[]{Integer.toString(id)});
}
public Cursor getData(int contactid){
SQLiteDatabase db=this.getWritableDatabase();
Cursor res=db.rawQuery("Select * from mycontacts where id = " + contactid + "", null);
return res;
}
public int numberOfRows(){
SQLiteDatabase db=this.getWritableDatabase();
int numRows=(int) DatabaseUtils.queryNumEntries(db,CONTACTS_TABLE_NAME);
return numRows;
}
public ArrayList<Person> getAllStudentContacts(){
ArrayList<Person> arraylist= new ArrayList<>();
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery("Select * from mycontacts",null);
if (cursor.moveToFirst()) {
do {
Person person = new Person();
person.name = cursor.getString(cursor.getColumnIndex(CONTACTS_COLUMN_STUNAME));
person.ID = cursor.getInt(cursor.getColumnIndex(CONTACTS_COLUMN_ID));
arraylist.add(person);
} while (cursor.moveToNext());
}
return arraylist;
}
}
DisplayContact.java
package com.test.ppandey.contactapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class DisplayContact extends AppCompatActivity {
int from_Where_I_Am_Coming = 0;
private DBHelper mydb;
TextView name;
TextView phone;
TextView email;
TextView street;
TextView place;
int id_To_Update = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_contact);
name = (TextView) findViewById(R.id.editTextName);
phone = (TextView) findViewById(R.id.editTextPhone);
email = (TextView) findViewById(R.id.editTextStreet);
street = (TextView) findViewById(R.id.editTextEmail);
place = (TextView) findViewById(R.id.editTextCity);
mydb = new DBHelper(this);
Bundle extras = getIntent().getExtras();
{
int Value = extras.getInt("id");
if (Value > 0) {
//means this is the view part not the add contact part.
Cursor rs = mydb.getData(Value);
id_To_Update = Value;
rs.moveToFirst();
String stuname = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUNAME));
String stuphone = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUPHONE));
String stuemail = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUEMAIL));
String stustreet = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUSTREET));
String stuplace = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUCITY));
if (!rs.isClosed()) {
rs.close();
}
Button b = (Button) findViewById(R.id.button1);
b.setVisibility(View.INVISIBLE);
name.setText((CharSequence) stuname);
name.setFocusable(false);
name.setClickable(false);
phone.setText((CharSequence) stuphone);
phone.setFocusable(false);
phone.setClickable(false);
email.setText((CharSequence) stuemail);
email.setFocusable(false);
email.setClickable(false);
street.setText((CharSequence) stustreet);
street.setFocusable(false);
street.setClickable(false);
place.setText((CharSequence) stuplace);
place.setFocusable(false);
place.setClickable(false);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
Bundle extras = getIntent().getExtras();
if (extras != null) {
int Value = extras.getInt("id");
if (Value > 0) {
getMenuInflater().inflate(R.menu.menu_display_contact, menu);
} else {
getMenuInflater().inflate(R.menu.menu_main, 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.
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.Edit_Contact:
Button b = (Button) findViewById(R.id.button1);
b.setVisibility(View.VISIBLE);
name.setEnabled(true);
name.setFocusableInTouchMode(true);
name.setClickable(true);
phone.setEnabled(true);
phone.setFocusableInTouchMode(true);
phone.setClickable(true);
email.setEnabled(true);
email.setFocusableInTouchMode(true);
email.setClickable(true);
street.setEnabled(true);
street.setFocusableInTouchMode(true);
street.setClickable(true);
place.setEnabled(true);
place.setFocusableInTouchMode(true);
place.setClickable(true);
return true;
case R.id.Delete_Contact:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.deleteContact)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mydb.deleteContact(id_To_Update);
Toast.makeText(getApplicationContext(), "Deleted Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog d = builder.create();
d.setTitle("Are you sure ?");
d.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void saveData(View view) {
/*, */
/* mydb.addContact(name.getText().toString(),email.getText().toString(), street.getText().toString(), place.getText().toString(), phone.getText().toString());
finish();*/
Bundle extras = getIntent().getExtras();
if (extras != null) {
int Value = extras.getInt("id");
if (Value > 0) {
if (mydb.updateStudentContact(id_To_Update, name.getText().toString(), phone.getText().toString(), street.getText().toString(),email.getText().toString(), place.getText().toString())) {
Toast.makeText(getApplicationContext(), "Successfully Updated", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "Record not updated", Toast.LENGTH_SHORT).show();
}
} else {
if (mydb.addStudentContact(name.getText().toString(), phone.getText().toString(),street.getText().toString(), email.getText().toString(), place.getText().toString())) {
Toast.makeText(getApplicationContext(), "Successfully Added", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Record not added", Toast.LENGTH_SHORT).show();
}
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
}
}
}
MainActivity.java
package com.test.ppandey.contactapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE="MESSAGE";
private ListView objListView;
DBHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db=new DBHelper(this);
ArrayList<Person> arrayList=db.getAllStudentContacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
objListView=(ListView)findViewById(R.id.listView1);
objListView.setAdapter(arrayAdapter);
objListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long id_to_search = id;
Bundle dataBundle = new Bundle();
dataBundle.putLong("id", id_to_search);
Intent intent = new Intent(getApplicationContext(), DisplayContact.class);
intent.putExtras(dataBundle);
startActivity(intent);
}
});
}
#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_main, 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);*/
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case R.id.item1:Bundle dataBundle = new Bundle();
dataBundle.putInt("id", 0);
Intent intent = new Intent(getApplicationContext(),DisplayContact.class);
intent.putExtras(dataBundle);
startActivityForResult(intent, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
db=new DBHelper(this);
ArrayList<Person> arrayList=db.getAllStudentContacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
objListView=(ListView)findViewById(R.id.listView1);
objListView.setAdapter(arrayAdapter);
}
}
activity_display_contact.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView1"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="350dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.test.ppandey.contactapp.DisplayContact">
<EditText
android:id="#+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="5dp"
android:layout_marginLeft="82dp"
android:ems="10"
android:inputType="text" >
</EditText>
<EditText
android:id="#+id/editTextEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextStreet"
android:layout_below="#+id/editTextStreet"
android:layout_marginTop="22dp"
android:ems="10"
android:inputType="textEmailAddress" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextName"
android:layout_alignParentLeft="true"
android:text="#string/name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextCity"
android:layout_alignParentBottom="true"
android:layout_marginBottom="28dp"
android:onClick="saveData"
android:text="#string/save" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextEmail"
android:layout_alignLeft="#+id/textView1"
android:text="#string/email"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextPhone"
android:layout_alignLeft="#+id/textView1"
android:text="#string/phone"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/editTextEmail"
android:layout_alignLeft="#+id/textView5"
android:text="#string/street"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editTextCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/editTextName"
android:layout_below="#+id/editTextEmail"
android:layout_marginTop="30dp"
android:ems="10"
android:inputType="text" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/editTextCity"
android:layout_alignBottom="#+id/editTextCity"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/editTextEmail"
android:text="#string/country"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editTextStreet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextName"
android:layout_below="#+id/editTextPhone"
android:ems="10"
android:inputType="text" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editTextPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextStreet"
android:layout_below="#+id/editTextName"
android:ems="10"
android:inputType="phone|text" />
</RelativeLayout>
</ScrollView>
Person.java
package com.test.ppandey.contactapp;
/**
* Created by Ariel on 08/03/2016.
*/
public class Person {
public String name;
public long ID;
private Person person; {
name = new String(name);
}
private Person id; {
ID = new long(id);
}
}
I added Person.java and edited MainActivity.java and DBHelper.java
This is your problem:
int id_to_search = position + 1;
You are assuming that the IDs and the positions are in sync. This is only true as long as you do not remove any entries. Instead of using the position to reference an entry, you have to use the ID, as that's immutable.
When you pull the entries from your database, you need to pull the name and the ID, and keep that data in your adapter, so you can reference an entry by its ID.
Some code below (just a skeleton):
1) Create a model for your data
public class Person {
// consider making private and adding accessors
public String name;
public long id;
}
2) when you pull your data, pull the name and the ID (you may expand the Person class and this function to pull additional data):
public List<Person> getAllStudentContacts(){
List<Person> arraylist= new ArrayList<>();
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery("Select * from mycontacts",null);
if (cursor.moveToFirst()) {
do {
Person person = new Person();
person.name = cursor.getString(cursor.getColumnIndex(CONTACTS_COLUMN_STUNAME));
person.id = cursor.getInt(cursor.getColumIndex(CONTACTS_COLUMN_ID));
arraylist.add(prson);
} while (cursor.moveToNext());
}
return arraylist;
}
Then in your adapter you use the ID in the Person object to reference it, instead of the position.
Are you refreshing your "List of Names" from your android App afer every insert/delete?
Maybe by calling getAllStudentContacts() from your code after every insert/delete to refill your List of names of your android app?
Good Luck
I'm pretty new to Java and Android apps, just started several weeks ago, everything went pretty well until now, when I stuck for several hours with a problem I cannot resolve, even with checking dozens of threads here.
I'm working on pretty simple android app that is supposed to show movies and years from a database, with a possibility to add record, show them all, search by a year or title. I stopped on a problem with
no such column _id (code 1): , while compiling SELECT _id, title, year FROM movies
I will be grateful for any help.
There are my files :
MainActivity
package com.example.imdbproject;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MainActivity extends Activity {
ListView moviesList;
Button searchYear;
Button searchTitle;
Button showAll;
Button addbtn;
Cursor cursor;
adapter adapter_ob;
MySQLiteHelper helper_ob;
SQLiteDatabase db_ob;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitDataBase();
moviesList = (ListView)findViewById(R.id.listView1);
searchYear = (Button)findViewById(R.id.buttonYear);
searchTitle =(Button)findViewById(R.id.buttonTitle);
addbtn = (Button)findViewById(R.id.buttonAdd);
showAll = (Button)findViewById(R.id.buttonShowAll);
adapter_ob = new adapter(this);
String[] from = { helper_ob.KEY_TITLE, helper_ob.KEY_YEAR };
int[] to = { R.id.tv_title, R.id.tv_year };
//PROBLEM
//cursor = adapter_ob.queryName();
//PROBLEM
//SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.row, cursor, from, to, 1);
/*
moviesList.setAdapter(cursorAdapter);
moviesList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
Bundle passdata = new Bundle();
Cursor listCursor = (Cursor) arg0.getItemAtPosition(arg2);
int nameId = listCursor.getInt(listCursor.getColumnIndex(helper_ob.KEY_ID));
passdata.putInt("keyid", nameId);
Intent passIntent = new Intent(MainActivity.this,EditActivity.class);
passIntent.putExtras(passdata);
startActivity(passIntent);
}
});
*/
addbtn.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
Intent addsomemoviesIntent = new Intent(MainActivity.this, AddSomeMovies.class);
startActivity(addsomemoviesIntent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void InitDataBase() {
MySQLiteHelper sqh = new MySQLiteHelper(this);
SQLiteDatabase sqdb = sqh.getWritableDatabase();
long result = sqh.addMovie("movietitle", "year");
}
}
adapter.java
package com.example.imdbproject;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.content.ContentValues;
import android.database.Cursor;
public class adapter {
SQLiteDatabase database_ob;
MySQLiteHelper openHelper_ob;
Context context;
public adapter(Context c)
{
context = c;
}
public adapter openToRead()
{
openHelper_ob = new MySQLiteHelper(context,
MySQLiteHelper.DATABASE_NAME, null, MySQLiteHelper.DATABASE_VERSION);
database_ob = openHelper_ob.getWritableDatabase();
return this;
}
public adapter openToWrite()
{
openHelper_ob = new MySQLiteHelper(context,
MySQLiteHelper.DATABASE_NAME, null, MySQLiteHelper.DATABASE_VERSION);
database_ob = openHelper_ob.getWritableDatabase();
return this;
}
public void Close()
{
database_ob.close();
}
public long insertDetails(String title, String year)
{
ContentValues cv = new ContentValues();
cv.put(MySQLiteHelper.KEY_TITLE, title);
cv.put(MySQLiteHelper.KEY_YEAR, year);
openToWrite();
long val = database_ob.insert(MySQLiteHelper.TABLE_NAME, null, cv);
Close();
return val;
}
public Cursor queryName()
{
String[] cols = { MySQLiteHelper.KEY_ID, MySQLiteHelper.KEY_TITLE,
MySQLiteHelper.KEY_YEAR };
openToWrite();
Cursor c = database_ob.query(MySQLiteHelper.TABLE_NAME, cols, null, null, null, null, null);
return c;
}
public Cursor queryAll(int nameId)
{
String[] cols = { MySQLiteHelper.KEY_ID, MySQLiteHelper.KEY_TITLE, MySQLiteHelper.KEY_YEAR };
openToWrite();
Cursor c = database_ob.query(MySQLiteHelper.TABLE_NAME, cols, MySQLiteHelper.KEY_ID + "=" + nameId, null,null,null,null);
return c;
}
}
MySQLiteHelper
package com.example.imdbproject;
import java.util.LinkedList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "movie_data.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "movies";
public static final String KEY_ID = "_id";
public static final String KEY_TITLE = "title";
public static final String KEY_YEAR = "year";
public static final String SCRIPT = "Create table " + TABLE_NAME + " ("
+ KEY_ID + " integer primary key autoincrement, " + KEY_TITLE
+ " text, " + KEY_YEAR + " text);";
public MySQLiteHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public MySQLiteHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
#Override public void onCreate(SQLiteDatabase db)
{
db.execSQL(SCRIPT);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE " + TABLE_NAME);
onCreate(db);
}
public long addMovie(String movietitle, String year){
ContentValues cv = new ContentValues();
cv.put(KEY_TITLE, movietitle);
cv.put(KEY_YEAR, year);
SQLiteDatabase sd = getWritableDatabase();
long result = sd.insert(TABLE_NAME, KEY_TITLE, cv);
return result;
}
}
AddSomeMovies
package com.example.imdbproject;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class AddSomeMovies extends Activity {
adapter adapter;
MySQLiteHelper helper;
EditText titleEdit, yearEdit;
Button addButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_some_movies);
titleEdit = (EditText)findViewById(R.id.etTitle);
yearEdit = (EditText)findViewById(R.id.etYear);
addButton = (Button)findViewById(R.id.button1);
adapter = new adapter(this);
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0)
{
String titleValue = titleEdit.getText().toString();
String yearValue = yearEdit.getText().toString();
long val = adapter.insertDetails(titleValue, yearValue);
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_some_movies, menu);
return true;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/buttonShowAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/buttonTitle"
android:layout_below="#+id/buttonTitle"
android:text="#string/showall"
/>
<Button
android:id="#+id/buttonYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/buttonTitle"
android:layout_alignBottom="#+id/buttonTitle"
android:layout_alignParentRight="true"
android:text="#string/yearsearch"
/>
<Button
android:id="#+id/buttonTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/titlesearch"
/>
<Button
android:id="#+id/buttonAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/buttonShowAll"
android:layout_alignBottom="#+id/buttonShowAll"
android:layout_toRightOf="#+id/buttonShowAll"
android:text="#string/add"
android:onClick="add" />
<Button
android:id="#+id/buttonOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/buttonYear"
android:layout_below="#+id/buttonYear"
android:enabled="false"
android:onClick="ok"
android:text="#string/ok"
android:visibility="invisible" />
<EditText
android:id="#+id/edittext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/buttonShowAll"
android:layout_centerHorizontal="true"
android:ems="10"
android:hint="#string/searcheditview" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/buttonShowAll"
android:layout_below="#+id/edittext" >
</ListView>
</RelativeLayout>
row.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="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tv_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp" />
</LinearLayout>
SORTED!
At least I think so. Problem disappeared when I changed database version to 2 from 1. So I can guess that it needs more attention now.
try following
public static final String KEY_ID = BaseColumns._ID;
instead of
public static final String KEY_ID = "_id";