I am trying to save the chat history in SQLite database. When I write to database, the app returns non-zero value so it is almost write to database correctly, But when I try to read the database data, the cursor returns 0 and no data retrieved form database.
here is the code for creating database:
public class ChatDatabaseHelp extends SQLiteOpenHelper {
static String DATABASE_NAME;
static int VERSION_NUM=1;
public static String KEY_ID="key_id",KEY_MESSAGE="message";
public static String TABLE_NAME="messages";
public ChatDatabaseHelp(Context ctx)
{
super(ctx,DATABASE_NAME,null,VERSION_NUM);
}
#Override
public void onCreate(SQLiteDatabase db) {
String SQL="CREATE TABLE messages(key_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,message TEXT NOT NULL)";
db.execSQL(SQL);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
here is the code where I write and read from database:
public class ChatWindow extends AppCompatActivity {
EditText t_send;
Button send;
ChatAdapter messageAdapter;
ListView listView;
private SQLiteDatabase db;
ArrayList<String> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_window);
t_send=(EditText)findViewById(R.id.editText);
list= new ArrayList<String>();
send=(Button)findViewById(R.id.button3);
listView=(ListView)findViewById(R.id.listview);
messageAdapter=new ChatAdapter(this);
listView.setAdapter(messageAdapter);
final ChatDatabaseHelp helper=new ChatDatabaseHelp(this);
db=helper.getWritableDatabase();
System.out.println("hiiii"+helper.TABLE_NAME);
Cursor cursor=db.rawQuery("select * from messages " , null);
while (cursor.moveToNext()) {
list.add(cursor.getString(1));
messageAdapter.notifyDataSetChanged();
}
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ContentValues cv=new ContentValues();
cv.put(helper.KEY_MESSAGE,t_send.getText().toString());
db.insert(helper.TABLE_NAME,null,cv);
list.add(t_send.getText().toString());
t_send.setText("");
messageAdapter.notifyDataSetChanged();
}
});
}
private class ChatAdapter extends ArrayAdapter<String> {
public ChatAdapter(Context ctx){
super(ctx,0);
}
public int getCount()
{
return list.size();
}
public String getItem(int position)
{
return list.get(position);
}
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater=ChatWindow.this.getLayoutInflater();
View result=null;
if(position%2==0){
result=inflater.inflate(R.layout.chat_row_ingoing,null);
TextView message=(TextView)result.findViewById(R.id.message_text_in);
message.setText(getItem(position));}
else{
result=inflater.inflate(R.layout.chat_row_outgoing,null);
TextView message=(TextView)result.findViewById(R.id.message_text_out);
message.setText(getItem(position));}
return result;
}
}
#Override
protected void onDestroy() {
db.close();
super.onDestroy();
}
}
you have first write data into db then after read data if table is empty cursor give 0 value. above your code first read data into table that time is not found any data there for cursor give 0 value.
you used two button read and write into db.
first write data into db that code in below.
write.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db=helper.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(helper.KEY_MESSAGE,t_send.getText().toString());
db.insert(helper.TABLE_NAME,null,cv);
list.add(t_send.getText().toString());
t_send.setText("");
messageAdapter.notifyDataSetChanged();
}
});
then after read the data into db below code..
read.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db=helper.getReadableDatabase();
Cursor cursor=db.rawQuery("select * from messages " , null);
if (cursor != null) {
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
list.add(cursor.getString(cursor.getColumnIndex("message"));
messageAdapter.notifyDataSetChanged();
cursor.moveToNext();
}
}
}
});
Related
I am just trying to make a list by using RecyclerView where each of the list Item will contain a checkbox button. So when user will click on checkbox, it will replace the value of a Table column such as column country get value "A", on the other hand, uncheck will replace the country column value from "A" to "B" or anything.
Can anyone please help me with this? any suggestion regarding this and other similar ways to add data in SQLite database by using Recyclable will be highly a lot helpful.
Below I have added my code for your reference and Thanks in advance.
My DatabaseHelper Class
package com.hfad.ressql;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.hfad.ressql.DatabaseContractor.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "workers.db";
private static final int DATABASE_VERSION =7;
SQLiteDatabase db;
public DatabaseHelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
this.db=db;
final String SQL_CREATE_TBALE="CREATE TABLE " + EmployeeDetails.TABLE_NAME + "(" + EmployeeDetails._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
EmployeeDetails.COLUMN_FIRSTNAME+" TEXT, "+EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+EmployeeDetails.COLUMN_COUNTRY+" TEXT)";
db.execSQL(SQL_CREATE_TBALE);
fillquestion();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + EmployeeDetails.TABLE_NAME);
onCreate(db);
}
public void fillquestion(){
DataModel o4 = new DataModel("Earth","Soil","B");
IntertData(o4);
DataModel o5 = new DataModel("Sun","Light","B");
IntertData(o5);
DataModel o6 = new DataModel("Moon","Rock","B");
IntertData(o6);
}
public void IntertData (DataModel data){
ContentValues contentValues = new ContentValues();
contentValues.put(EmployeeDetails.COLUMN_FIRSTNAME, data.getFirstName());
contentValues.put(EmployeeDetails.COLUMN_LASTNAME, data.getLastName());
contentValues.put(EmployeeDetails.COLUMN_COUNTRY, data.country);
db.insert(EmployeeDetails.TABLE_NAME,null,contentValues);
}
public List<DataModel> object1() {
ArrayList<DataModel> details = new ArrayList<DataModel>();
db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + EmployeeDetails.TABLE_NAME, null );
if (cursor.moveToFirst()) {
do {
DataModel object2 = new DataModel();
object2.setFirstName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_FIRSTNAME)));
object2.setLastName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_LASTNAME)));
object2.setCountry(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_COUNTRY)));
details.add(object2);
} while (cursor.moveToNext());
}
cursor.close();
return details;
}
}
Here is my DataModel Class
package com.hfad.ressql;
public class DataModel {
public String FirstName;
public String LastName;
public String country;
public DataModel() {
}
public DataModel(String firstName, String lastName, String country) {
this.FirstName = firstName;
this.LastName = lastName;
this.country = country;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Database Constructor
public final class DatabaseContractor {
private DatabaseContractor (){}
public static class EmployeeDetails implements BaseColumns {
public static final String TABLE_NAME="employy";
public static final String COLUMN_FIRSTNAME="First_Name";
public static final String COLUMN_LASTNAME="Last_Name";
public static final String COLUMN_COUNTRY="Country";
public static final String COLUMN_FAVO="mfav";
}
}
Recycler Adapter
Here I am struggling hard to sort it out. All I need is, if I click on check box, one pre-given value will be updated in the database, at the same time check box will be checked until user uncheck it. And when user will uncheck it, database will replace previous value with a new value. Actually, I have just trying to have values in a table column, so that I can use it as a favorite or bookmark list.
public class RecycAdapter extends
RecyclerView.Adapter<RecycAdapter.ViewHolder> {
List<DataModel> dotamodeldataArraylist;
Context context;
SQLiteDatabase db;
DatabaseHelper helper;
ContentValues contentValues;
Cursor cursor;
public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
this.dotamodeldataArraylist=dotamodeldataArraylist;
this.context=context;
}
#Override
public ViewHolder onCreateViewHolder( ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {
DataModel obj3= dotamodeldataArraylist.get(position);
holder.Fnam.setText(obj3.getFirstName());
holder.Lname.setText(obj3.getLastName());
holder.Country.setText(obj3.getCountry());
holder.fav.();
holder.fav.setChecked(fav);
final int currentPosition = position;
final boolean fav = 0==0;
holder.fav.setChecked(fav);
final int currentPosition = position;
holder.fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.fav.isChecked()){
try {
contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, "B");
db.update("DRINK", contentValues, "id_=?", new String[]{Integer.toString(currentPosition)});
} catch (SQLException e){
Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
}
Toast.makeText(context,"checked " + position , Toast.LENGTH_LONG).show();
} if(!holder.fav.isChecked()){
Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return dotamodeldataArraylist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView Fnam,Lname,Country;
CheckBox fav;
RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
Fnam = itemView.findViewById(R.id.name1);
Lname = itemView.findViewById(R.id.city1);
Country = itemView.findViewById(R.id.country1);
fav=itemView.findViewById(R.id.chk);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.layout);
}
}
}
View Class
view all class
public class Viewall extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseHelper databaseHelper;
RecycAdapter recycAdapter;
List<DataModel> dotamodeldataArraylist;
Context context;
Button show;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewall);
show = findViewById(R.id.view);
recyclerView=findViewById(R.id.recycle);
databaseHelper =new DatabaseHelper(this);
dotamodeldataArraylist = new ArrayList<DataModel>();
dotamodeldataArraylist=databaseHelper.object1();
recycAdapter =new RecycAdapter(dotamodeldataArraylist,this);
RecyclerView.LayoutManager reLayoutManager =new
LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(reLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(recycAdapter);
I believe the following will do as you wish.
The were quite a few issues with code. One of the major issues is that you expected the position to correlate with the id (aka your _id column).
The position of the first item in the list is 0, unless you force/specifically set the value of 0, an alias of the rowid column (your _id column is an alias of the rowid column), the first value assigned will be 1, then likely 2, then likely 3 ...........
So at best position will be 1 less than the id.
If a row is deleted, other than the last row then position will be one less except up until the deleted row is passed and then position will be 2 less than the rowid. More deletions and an even more complex correlation between position and id. I guess somebody could come up with a fool proof conversion BUT the simpe way is to ensure that the DataModel has the vale of the respective _id column.
As such DataModel.java should be changed to include a member/variable for the id therefore the following was used :-
public class DataModel {
public String FirstName;
public String LastName;
public String country;
public long id; //<<<<<<<<<< ADDED also added gettter and setter
public DataModel() {
}
public DataModel(String firstName, String lastName, String country) {
this(firstName,lastName,country,-1);
}
//<<<<<<<<<< ADDED so ID can be set
public DataModel(String firstName, String lastName, String country, long id) {
this.FirstName = firstName;
this.LastName = lastName;
this.country = country;
this.id = id;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
}
see comments for changes
As you need to extract the id from the database, the object1 method was changed in DatabaseHelper.java (a few other changes have also been made) the following was used :-
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "workers.db";
private static final int DATABASE_VERSION =7;
SQLiteDatabase db;
public DatabaseHelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
this.db=db; //<<<<<<< WRONG PLACE as onCreate only ever runs when there is no database
final String SQL_CREATE_TBALE="CREATE TABLE " + DatabaseContractor.EmployeeDetails.TABLE_NAME + "(" + DatabaseContractor.EmployeeDetails._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY+" TEXT)";
db.execSQL(SQL_CREATE_TBALE);
fillquestion();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DatabaseContractor.EmployeeDetails.TABLE_NAME);
onCreate(db);
}
public void fillquestion(){
IntertData(new DataModel("Earth","Soil","B"));
IntertData(new DataModel("Sun","Light","B"));
IntertData(new DataModel("Moon","Rock","B"));
}
public void IntertData (DataModel data){
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME,data.getFirstName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME,data.getLastName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY,data.country);
db.insert(DatabaseContractor.EmployeeDetails.TABLE_NAME,null,contentValues);
}
public List<DataModel> object1() {
ArrayList<DataModel> details = new ArrayList<>();
//db = getReadableDatabase(); db has already been set when database was instantiated/constructed
Cursor cursor = db.rawQuery("SELECT * FROM " + DatabaseContractor.EmployeeDetails.TABLE_NAME, null );
while (cursor.moveToNext()) {
details.add(new DataModel(
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY)),
cursor.getLong(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails._ID)) //<<<<<<<<< Added so id is available
));
}
cursor.close();
return details;
}
}
Pretty extensive changes were made to RecycAdapter.java, the following was used :-
public class RecycAdapter extends RecyclerView.Adapter<RecycAdapter.ViewHolder> {
List<DataModel> dotamodeldataArraylist;
Context context;
SQLiteDatabase db;
DatabaseHelper helper;
ContentValues contentValues;
public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
this.dotamodeldataArraylist=dotamodeldataArraylist;
this.context=context;
helper = new DatabaseHelper(context);
db = helper.getWritableDatabase();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {
//DataModel obj3= dotamodeldataArraylist.get(position); //<<<<<<<<<< NOT NEEDED
holder.Fnam.setText(dotamodeldataArraylist.get(position).getFirstName());
holder.Lname.setText(dotamodeldataArraylist.get(position).getLastName());
holder.Country.setText(dotamodeldataArraylist.get(position).getCountry());
holder.fav.setChecked(false); //<<<<<<<<< not stored so initially set to false
holder.fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newcountry = "B";
if(holder.fav.isChecked()){
if (dotamodeldataArraylist.get(position).getCountry().equals("B")) {
newcountry = "A";
}
contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, newcountry);
if (db.update(
DatabaseContractor.EmployeeDetails.TABLE_NAME,
contentValues,
DatabaseContractor.EmployeeDetails._ID +"=?",
new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())}
) > 0) {
dotamodeldataArraylist.get(position).setCountry(newcountry);
notifyItemChanged(position);
Toast.makeText(context,
"checked and updated " +
position+ dotamodeldataArraylist.get(position).getFirstName() +
" ID is " + String.valueOf(dotamodeldataArraylist.get(position).getId()),
Toast.LENGTH_LONG
).show();
} else {
Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return dotamodeldataArraylist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView Fnam,Lname,Country;
CheckBox fav;
public ViewHolder(View itemView) {
super(itemView);
Fnam = itemView.findViewById(R.id.name1);
Lname = itemView.findViewById(R.id.city1);
Country = itemView.findViewById(R.id.country1);
fav = itemView.findViewById(R.id.chk);
}
}
}
lastly a few minor changes were made to Viewall.java, the following was used :-
public class Viewall extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseHelper databaseHelper;
RecycAdapter recycAdapter;
List<DataModel> dotamodeldataArraylist;
Button show;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewall);
show = findViewById(R.id.view);
recyclerView = findViewById(R.id.recycle);
databaseHelper = new DatabaseHelper(this);
dotamodeldataArraylist = databaseHelper.object1();
recycAdapter = new RecycAdapter(dotamodeldataArraylist, this);
RecyclerView.LayoutManager reLayoutManager = new
LinearLayoutManager(this);
recyclerView.setLayoutManager(reLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(recycAdapter);
}
}
Result
Note the layout(s) may be different, but your's should probably work and alter the presentation accordingly
When first run :-
After clicking the checkbox for Sun
Click again and back to Country B and so on.
Note the check box isn't flipped, that's a bit of an issue as to correctly display the changed data (country) notifyItemChanged is used, which will reprocess the list and thus set the checkbox to false. You'd need to store the checkbox value somewhere (in short you should really use checkboxes in this way).
Closing the app and restarting maintains the changes made, thus confirming that the changes to the database have been made.
On top of #MiKe's code, i have just made some changes in my RecyclerAdapter inside onClickListener to save checkbox Status and added isChecked as a boolean value inside dataModel class. now its working perfectly.
holder.chkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Values = new ContentValues();
Values.put(DatabaseContractor.EmployeeDetails.COLUMN_FAVORITE,holder.chkbox.isChecked());
try{ db.update(DatabaseContractor.EmployeeDetails.TABLE_NAME,
Values,
DatabaseContractor.EmployeeDetails._ID + "=?",
new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())});
} catch (SQLException e){
Toast.makeText(context,"Error"+position,Toast.LENGTH_LONG).show();
}
}
});
Thanks again mike for your awesome guideline. Now, i can directly save checkbox status in sqlite Database.
I am facing this problem whenever i run the app 1st time data in database remain single time but when i close the App and restart again data goes twice(means two same row in table).Similarly for 3rd, 4th time and so on. How do i get rid of this problem? I even put datas.clear in DataList.java but don't whether i have add the datas.clear() line in correct place or not.
PLz help if there is any other problem in my code.
MainActivity.java code
public class MainActivity extends AppCompatActivity {
Button listButton, addButton;
DatabaseHelper df;
private final static String TAG = "TestActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
df = new DatabaseHelper(this);
addButton = (Button) findViewById(R.id.addbutton);
uploadList();
}
public void uploadList(){
DatabaseHelper df=new DatabaseHelper(this);
df.open();
try{
InputStream im=getResources().getAssets().open("testdata.csv");
BufferedReader br=new BufferedReader(new InputStreamReader(im));
String data=br.readLine();
while(data != null){
String t[]=data.split(",");
Product p=new Product();
p.setFirst(t[0]);
p.setSec(t[1]);
p.setThird(t[2]);
df.insert(p);
data=br.readLine();
}
}catch(Exception e){
}
}
}
DatabaseHelper.java code
public class DatabaseHelper extends SQLiteOpenHelper{
private static final String FIRST="Name";
private static final String SECOND="Issn";
private static final String THIRD="ImpactFactor";
private static final String DATABASE="journal2016";
private static final String TABLENAME="journal";
private static final int VERSION=1;
SQLiteDatabase sd;
public void open(){
sd=getWritableDatabase();
}
public void close(){
sd.close();
}
public DatabaseHelper(Context context) {
super(context, DATABASE, null, VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLENAME );
sqLiteDatabase.execSQL("CREATE TABLE " + TABLENAME + " ( NAME TEXT, ISSN TEXT, IMPACTFACTOR REAL)");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLENAME );
}
public long insert(Product p){
ContentValues cv=new ContentValues();
cv.put(FIRST, p.getFirst());
cv.put(SECOND, p.getSec());
cv.put(THIRD, p.getThird());
return sd.insertWithOnConflict(TABLENAME, null, cv,SQLiteDatabase.CONFLICT_REPLACE);
}
public List<Product> getAllProduct(){
ArrayList<Product> list=new ArrayList<Product>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c=db.rawQuery("SELECT * FROM " + TABLENAME, null);
while(c.moveToNext()){
Product p=new Product();
p.setFirst(c.getString(0));
p.setSec(c.getString(1));
p.setThird(c.getString(2));
list.add(p);
}
db.close();
return list;
}
}
DataList.java code
public class DataList extends Activity{
List<Product> datas = new ArrayList<Product>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
datas.clear();
DatabaseHelper d=new DatabaseHelper(this);
d.open();
datas = d.getAllProduct();
ListView lv=(ListView)findViewById(R.id.listView1);
lv.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, datas));
}
}
Product.java
public class Product {
private String first;
private String second;
private String third;
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getSec() {
return second;
}
public void setSec(String sec) {
this.second = sec;
}
public String getThird() {
return third;
}
public void setThird(String third) {
this.third = third;
}
#Override
public String toString() {
return first + second + third;
}
}
Remove this line from your onCreate() method:
df = new DatabaseHelper(this);
as no need of it because you are create object of your DatabaseHelper class inside uploadList() method.
And also you are calling uploadList() method inside onCreate() thats why every time you launch the app, the onCreate() method executes and you uploadList() also execute. Try to put its calling statement in an onClickListener so it happens when you click a button or your choice of stuff.
I made an android application which saves notes. The notes are indeed saved. However when the app is opened only the example note Akhilesh Chobey is shown. All other notes are shown on pressing the back button in the Main2Activity(Activity for editing note)
MainActivity:
public class MainActivity extends AppCompatActivity {
ListView notesListView;
static ArrayList<String> notesArrayList;
static ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notesListView = (ListView) findViewById(R.id.notesListView);
notesArrayList = new ArrayList<String>();
if(Main2Activity.myDb != null) {
notesArrayList.clear();
Cursor res = Main2Activity.myDb.getData();
if (res.getCount() == 0) {
Log.i("Error", "error");
return;
}
while (res.moveToNext()) {
notesArrayList.add(res.getString(res.getColumnIndex("text")));
}
}
notesArrayList.add("Akhilesh Chobey");
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, notesArrayList);
notesListView.setAdapter(adapter);
notesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("notePosition", i);
startActivity(intent);
}
});
}
}
Main2Activity:
public class Main2Activity extends AppCompatActivity implements TextWatcher {
static DatabaseOperations myDb;
EditText editNote;
int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
editNote = (EditText) findViewById(R.id.noteEditText);
myDb = new DatabaseOperations(Main2Activity.this);
Intent intent = getIntent();
position = intent.getIntExtra("notePosition", -1);
if(position != -1){
editNote.setText(MainActivity.notesArrayList.get(position));
}
editNote.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (myDb != null) {
boolean isInserted = myDb.insertData(editNote.getText().toString());
MainActivity.notesArrayList.set(position, String.valueOf(charSequence));
MainActivity.adapter.notifyDataSetChanged();
}
}
Database Helper Class:
public class DatabaseOperations extends SQLiteOpenHelper {
public static final String DatabaseName = "notes.db";
public static final String TableName = "notes";
public static final String Col1 = "text";
public DatabaseOperations(Context context) {
super(context, DatabaseName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TableName + " (text TEXT) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TableName);
onCreate(db);
}
public boolean insertData(String note){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(Col1, note);
long result = db.insert(TableName, null, contentValues);
if(result == -1){
return false;
}else {
return true;
}
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery("select * from " + TableName, null);
return result;
}
}
in your Main2Activity class(Terrible naming BTW) the
static DatabaseOperations myDb;
variable is not assigned with anything at the start of the program, so DatabaseOperations== null, so the if condition
if(Main2Activity.myDb != null) {
notesArrayList.clear();
Cursor res = Main2Activity.myDb.getData();
if (res.getCount() == 0) {
Log.i("Error", "error");
return;
}
while (res.moveToNext()) {
notesArrayList.add(res.getString(res.getColumnIndex("text")));
}
}
will not be executed thus no data will be loaded in to the app.
BUT when you come back from the M2A class by pressing back
onCreate is called once again but this time DatabaseOperations myDb != NULL ,because myDb is assigned a value by this,
myDb = new DatabaseOperations(Main2Activity.this);
so the if condition in MainActivity class becomes true.
WHAT YOU HAVE TO DO: find a way to make that myDb variable not null at the start of the program.
I have a spinner. I want to load data from sqlite. I have try to load data with Activity class, it work but i want to load it in Fragment class and i got the method is undefined. There is any wrong ? What should i do ??
Sorry for my bad english..
This is Fragment class
public class InfoJadwal extends Fragment {
private DatabaseHandler dbhelper;
private SQLiteDatabase db = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dbhelper = new DatabaseHandler(getActivity());
db = dbhelper.getWritableDatabase();
dbhelper.delAllData(db);
dbhelper.generateData(db);
View rootView = inflater.inflate(R.layout.info_jadwal, container,
false);
loadDataSpinner();
return rootView;
}
private void loadDataSpinner() {
Cursor wisataCursor;
Spinner colourSpinner = (Spinner) getView().findViewById(
R.id.spin_tujuan);
wisataCursor = dbhelper.fetchAllWisata(db);
startManagingCursor(wisataCursor);
String[] from = new String[] { dbhelper.TUJUAN };
int[] to = new int[] { R.id.tvDBViewRow };
SimpleCursorAdapter wisataAdapter = new SimpleCursorAdapter(this,
R.layout.db_view_row, wisataCursor, from, to);
colourSpinner.setAdapter(wisataAdapter);
}
#Override
public void onDestroy() {
super.onDestroy();
try {
db.close();
} catch (Exception e) {
}
}
}
And this is class for DatabaseHandler.
public class DatabaseHandler extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "medantrain";
public static final String TUJUAN = "tujuan";
public static final String KEY_ID = "_id";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, 1);
}
// method createTable untuk membuat table WISATA
public void createTable(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS KOTA");
db.execSQL("CREATE TABLE if not exists KOTA (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "TUJUAN TEXT);");
}
// method generateData untuk mengisikan data ke table Wisata.
public void generateData(SQLiteDatabase db) {
ContentValues cv = new ContentValues();
cv.put(TUJUAN, "Binjai");
db.insert("KOTA", TUJUAN, cv);
cv.put(TUJUAN, "Rantau Prapat");
db.insert("KOTA", TUJUAN, cv);
cv.put(TUJUAN, "Tebing Tinggi");
db.insert("KOTA", TUJUAN, cv);
}
// method delAllAdata untuk menghapus data di table Wisata.
public void delAllData(SQLiteDatabase db) {
db.delete("KOTA", null, null);
}
public Cursor fetchAllWisata(SQLiteDatabase db) {
return db.query("KOTA", new String[] { KEY_ID, TUJUAN }, null, null,
null, null, null);
}
#Override
public void onCreate(SQLiteDatabase db) {
createTable(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
replace
SimpleCursorAdapter wisataAdapter = new SimpleCursorAdapter(this,R.layout.db_view_row, wisataCursor, from, to);
with
SimpleCursorAdapter wisataAdapter = new SimpleCursorAdapter(getActivity(),R.layout.db_view_row, wisataCursor, from, to);
and replace
startManagingCursor(wisataCursor);
with
getActivity().startManagingCursor(wisataCursor);
but startManagingCursor(Cursor) in Activity is deprecated. see docs for more info http://developer.android.com/reference/android/app/Activity.html#startManagingCursor%28android.database.Cursor%29
SimpleCursorAdapter requires a Context reference but you are passing this which means a Fragment reference.
I'm trying to create table in the sqlite, but it is showing error that table cannot be created. I have a same code but the database and table name are different. the fields are same. Also one doubt. Can't i create the different table in the same database containing the same fields.
DbAdapter.java
the code is as below.
public class DbAdapter {
private static final String DATABASE_NAME="bible1";
private static final String DATABASE_TABLE="test1";
private static final int DATABASE_VERSION=1;
public static final String KEY_ID="_id";
public static final String UNITS="units";
public static final String CHAPTERS="chapters";
private static final String CREATE_DATABASE="create table test1 (_id integer primary key autoincrement, units text not null, chapters text not null);";
private SQLiteHelper sqLiteHelper;
private static SQLiteDatabase sqLiteDatabase;
private Context context;
//constructor
public DbAdapter(Context c){
context = c;
}
private static class SQLiteHelper extends SQLiteOpenHelper{
public SQLiteHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_DATABASE);
MakeUnits();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
public DbAdapter open() throws SQLException{
try{
sqLiteHelper = new SQLiteHelper(context);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
}catch(NullPointerException ne){
Log.e("error in creating the table", "bye");
}
return this;
}
public void close(){
sqLiteHelper.close();
}
public static long MakeUnits()
{
ContentValues insert1 = new ContentValues();
insert1.put(UNITS, "Unit1");
insert1.put(CHAPTERS, "CHAPTER1");
return sqLiteDatabase.insert(DATABASE_TABLE,null,insert1);
}
public Cursor fetchAllNotes(){
return sqLiteDatabase.query(DATABASE_TABLE, new String[]{KEY_ID,UNITS,CHAPTERS}, null, null, null, null, null);
}
}
MainActivity.java
public class MainActivity extends ListActivity {
private DbAdapter Database;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listContent = (ListView) findViewById(android.R.id.list);
Database= new DbAdapter(this);
Database.open();
Cursor c = Database.fetchAllNotes();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
It is giving error when the open() method is called. Couldn't figure it out.
in the logcat the error in the tag is that "error in creating the table"
You're trying to call sqLiteDatabase.insert inside MakeUnits, but this sqLiteDatabase variable is null until after you call getWritableDatabase. You should pass db to MakeUnits and call insert on db, not on sqLiteDatabase.
database will be created only when you make a call to
getWritableDatabase()/getReadableDatabase()
If you do not have permissions for a writable db, you will get a readable
db.
public SQLiteDatabase getWritableDB() {
try {
return helper.getWritableDatabase();
} catch (Exception e) {
return getReadableDB();
}
}
public SQLiteDatabase getReadableDB() {
return helper.getReadableDatabase();
}