I'm trying to display string on the textview. I'm succesfully able to print it on the console from database, but I'm not able to figure out how to print all the strings on different different textviews. Here is my code:
MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
EditText search;
Button insert;
TextView txt1, txt2, txt3, txt4, txt5;
DatabaseHandler db;
List<History> history;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DatabaseHandler(this);
search = (EditText) findViewById(R.id.search_word);
insert = (Button) findViewById(R.id.insert);
txt1 = (TextView) findViewById(R.id.txt1);
txt2 = (TextView) findViewById(R.id.txt2);
txt3 = (TextView) findViewById(R.id.txt3);
txt4 = (TextView) findViewById(R.id.txt4);
txt5 = (TextView) findViewById(R.id.txt5);
insert.setOnClickListener(this);
history = db.getAllHistory();
}
public void onClick(View v) {
db.addHistory(new History(search.getText().toString(), null));
Toast.makeText(getApplicationContext(),
"Inserted: " + search.getText().toString(), Toast.LENGTH_LONG)
.show();
}
#Override
protected void onStart() {
super.onStart();
List<History> history = db.getAllHistory();
for (History cn : history) {
String log = "Search Strings: " + cn.getName();
Log.d("Search Strings: ", log);
}
}
}
This is my activity in which I'm bringing my all database value on onStart() function. Now here I have to set all the data coming from database on the textview. Here is my DabaseHandler class in which I'm taking out each row.
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "historyManager";
private static final String TABLE_HISTORY = "histories";
private static final String KEY_NAME = "history";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_HISTORY_TABLE = "CREATE TABLE " + TABLE_HISTORY + "("
+ KEY_NAME + " TEXT" + ")";
db.execSQL(CREATE_HISTORY_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_HISTORY);
onCreate(db);
}
void addHistory(History history) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, history.getName());
db.insert(TABLE_HISTORY, null, values);
db.close();
}
History getHistory(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_HISTORY, new String[] { KEY_NAME },
"=?", new String[] { String.valueOf(id) }, null, null, null,
null);
if (cursor != null)
cursor.moveToFirst();
History history = new History(Integer.parseInt(cursor.getString(0)),
cursor.getString(1), cursor.getString(2));
return history;
}
public List<History> getAllHistory() {
List<History> historyList = new ArrayList<History>();
String selectQuery = "SELECT * FROM " + TABLE_HISTORY;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
History contact = new History();
contact.setName(cursor.getString(0));
historyList.add(contact);
} while (cursor.moveToNext());
}
return historyList;
}
public int updateHistory(History history) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, history.getName());
return db.update(TABLE_HISTORY, values, KEY_NAME + " = ?",
new String[] { String.valueOf(history.getName()) });
}
public void deleteHistory(History history) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_HISTORY, KEY_NAME + " = ?",
new String[] { String.valueOf(history.getName()) });
db.close();
}
public int getHistoryCount() {
String countQuery = "SELECT * FROM " + TABLE_HISTORY;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
cursor.close();
return cursor.getCount();
}
}
Please help in getting data printed on the textview. On the Log.d I can see all my data coming, one after another. But I'm not able to print all the data.
It's answer for "Thank You for that. Can you tell me how to set the data which I have printed in MainActivity on onStart() method (Log.d("")). If you can give me the code for that, that will be much easier for me."
try this:
List<String> listNames = new ArrayList<String>();//global variable
List<History> history = db.getAllHistory();
for (History cn : history) {
listNames.add(cn.getName());
}
or, if have in History field date try is, after easy will sort:
Map<String, Date> historyMap = new HashMap<String, Date>();
List<History> history = db.getAllHistory();
for (History cn : history) {
historyMap.put(cn.getName, cn.getDate);
}
You need make ListView in which will show your data from DB.Because you have many items datas getting from db.
I suggest to the next version:
In xml file you creat:
<ListView
android:id="#+id/list_names"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...>
You need create Adapter for your list with next xml resource:
<TextView
android:id="#+id/text_name"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
In java code:
in onCreate:
ListView list = (ListView) findViewById(R.id.list);
OurAdapter adapter = new OurAdapter(..., List<String> yourListWithName);
list.setAdapter(adapter);
if you want a more detailed description of the code tell me.
For add last item in top you need next, create spec. internal class :
class Holder implements Comparable<Holder> {
String key;
Double value;
public int compareTo(Holder another) {
return another.value.compareTo(value);
}
}
and use him how:
List<this.Holder> listSortforLastInTop = new ArrayList<this.Holder>();
and
for(...){
Holder holder = new Holder();
holder.key=...;
older.value=..;
listSortforLastInTop.add(holder);
}
Related
I am trying to save the button's state in a certain item of RecyclerView whenever a user clicks that button. At the time it was clicked, it's visibility will be gone and another button will be visible. How can I save the button's state so that whenever the app is entirely closed, when I open it again the state of the button is still there?
I tried making a database for the button's visibility state but I couldn't figure out where to put the right code to add the data and save it.
onBindViewHolder() inside RecyclerView class, this is where I put my button click listener.
#Override
public void onBindViewHolder(final MyViewHolder holder, int position){
MakerAdapter h = makerList.get(position);
final String macString = h.getHMac();
holder.rIcon.setImageResource(h.getHIcon());
holder.rDevice.setText(h.getHDevice());
holder.rBrand.setText(h.getHBrand());
holder.rIp.setText(h.getHIp());
holder.rMac.setText(h.getHMac());
holder.rDate.setText(h.getHDate());
holder.rWifi.setText(h.getHWifi());
holder.rMark.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSafeDB = new SafeDB(getApplicationContext(), null,null,1);
holder.rMark.setVisibility(GONE);
holder.rUnsafe.setVisibility(VISIBLE);
mSafeDB.addSafeMaker(macString, holder.rMark.getVisibility());
}
});
holder.rUnsafe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSafeDB = new SafeDB(getApplicationContext(), null,null,1);
holder.rUnsafe.setVisibility(GONE);
holder.rMark.setVisibility(VISIBLE);
mSafeDB.addSafeMaker(macString, holder.rUnsafe.getVisibility());
}
});
}
These are my imports specific to this(onBindViewHolder) method:
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.facebook.FacebookSdk.getApplicationContext;
This is my database
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class SafeDB extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
private static final String DB_NAME = "safedb.db";
private static final String TABLE_NAME = "marked_safe";
private static final String COL_ID = "id";
private static final String COL_MAC = "mac";
private static final String COL_MARK = "mark";
//////////Housekeeping START
public SafeDB(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){
super(context, DB_NAME, factory, DB_VERSION);
}
public SafeDB(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db){
String query = "CREATE TABLE " + TABLE_NAME + "(" +
COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_MAC + " TEXT, " +
COL_MARK + " INTEGER " +
");";
db.execSQL(query);
}
public void open() throws SQLException {
close();
this.getWritableDatabase();
}
public void closeDB() {
SQLiteDatabase db = this.getReadableDatabase();
if (db != null && db.isOpen())
db.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1){
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
//////////Housekeeping END
public void deleteTable(){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
//IF FIRST TIME. THIS WILL BE TRIGGERED
public void addSafeMaker(String mac, int mark){
ContentValues values = new ContentValues();
values.put(COL_MAC, mac);
values.put(COL_MARK, mark);
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_NAME, null, values);
}
//UPDATE THE Arp
public void updateMaker(String mac, int mark){
ContentValues values = new ContentValues();
values.put(COL_MAC, mac);
values.put(COL_MARK, mark);
SQLiteDatabase db = getWritableDatabase();
db.update(TABLE_NAME, values, "id = 1", null);
}
//GET THE MAC
public String getMac(String x) {
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM "+ TABLE_NAME+" WHERE "+ COL_ID+" = '" + x+"'" + " LIMIT 1;" ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
String mac = c.getString(c.getColumnIndex("mac"));
return mac;
}
//GET THE BUTTON VISIBILITY VALUE
public String getSafeValue(String x) {
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM "+ TABLE_NAME+" WHERE "+ COL_ID+" = '" + x+"'" + " LIMIT 1;" ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
String mark = c.getString(c.getColumnIndex("mark"));
return mark;
}
//CHECK IF EMPTY
public boolean isEmpty() {
boolean e = true;
SQLiteDatabase db = getWritableDatabase();
String count = "SELECT count(*) FROM " + TABLE_NAME;
Cursor c = db.rawQuery(count, null);
c.moveToFirst();
int icount = c.getInt(0);
e = icount <= 0;
return e;
}
public int getCount(){
int count = 0;
SQLiteDatabase db = getWritableDatabase();
String c = "SELECT count(*) FROM " + TABLE_NAME;
Cursor x = db.rawQuery(c, null);
x.moveToFirst();
count = x.getInt(0);
return count;
}
}
The following is a working example based upon your code, albeit that the Adapter is probably quite different. Some assumptions/guesswork were made. So the code is very much in-principle code and would need to be adapted.
The above adds a mac (assuming a mac is unique) when the adapter is instantiated, a specific mac will only be added once.
In the onBindView method the status/mark is retrieved from the db to determine which button is displayed.
When a button is clicked the displayed button is toggled and the respective mac (the button's tag is used to store the mac) is used to update the respective row according to the mac.
SafeDB.java
public class SafeDB extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
private static final String DB_NAME = "safedb.db";
private static final String TABLE_NAME = "marked_safe";
private static final String COL_ID = "id";
private static final String COL_MAC = "mac";
private static final String COL_MARK = "mark";
//////////Housekeeping START
public SafeDB(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){
super(context, DB_NAME, factory, DB_VERSION);
}
public SafeDB(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db){
String query = "CREATE TABLE " + TABLE_NAME + "(" +
COL_ID + " INTEGER PRIMARY KEY, " + // AUTOINCREMENT REMOVED NOT NECESSARY
COL_MAC + " TEXT UNIQUE, " + // Probably should be unique
COL_MARK + " INTEGER " +
");";
db.execSQL(query);
}
public void open() throws SQLException {
close();
this.getWritableDatabase();
}
public void closeDB() {
SQLiteDatabase db = this.getReadableDatabase();
if (db != null && db.isOpen())
db.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1){
deleteTable(); // might as well use the deleteTable method as it exists
onCreate(db);
}
//////////Housekeeping END
public void deleteTable(){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
//IF FIRST TIME. THIS WILL BE TRIGGERED
// wont hurt to return the id of the inserted row (-1 if no row inserted)
public long addSafeMaker(String mac, int mark){
ContentValues values = new ContentValues();
values.put(COL_MAC, mac);
values.put(COL_MARK, mark);
SQLiteDatabase db = getWritableDatabase();
return db.insert(TABLE_NAME, null, values);
}
//UPDATE THE Arp
public int updateMaker(String mac, int mark){
ContentValues values = new ContentValues();
values.put(COL_MARK, mark);
//values.put(COL_MARK, mark); // guess this wont change rather that it will be used to determine the row to be updated
SQLiteDatabase db = getWritableDatabase();
//db.update(TABLE_NAME, values, "id = 1", null); // Will only ever update 1 specific row
String whereclause = COL_MAC + "=?";
String[] whereargs = new String[]{mac};
return db.update(TABLE_NAME,values,whereclause,whereargs);
}
//GET THE MAC
public String getMac(String x) {
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM "+ TABLE_NAME+" WHERE "+ COL_ID+" = '" + x+"'" + " LIMIT 1;" ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
String mac = c.getString(c.getColumnIndex("mac"));
return mac;
}
public boolean getSafeValue(String mac) {
int mark = 0; // assume marked safe if row not found
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = COL_MAC + "=?";
String[] whereargs = new String[]{mac};
Cursor c = db.query(TABLE_NAME,null,whereclause,whereargs,null,null,null);
if (c.moveToFirst()) {
mark = c.getInt(c.getColumnIndex(COL_MARK));
}
return mark < 1;
}
//GET THE BUTTON VISIBILITY VALUE
/*
public String getSafeValue(String x) {
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM "+ TABLE_NAME+" WHERE "+ COL_ID+" = '" + x+"'" + " LIMIT 1;" ;
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
String mark = c.getString(c.getColumnIndex("mark"));
return mark;
}
*/
//CHECK IF EMPTY
/*
public boolean isEmpty() {
boolean e = true;
SQLiteDatabase db = getWritableDatabase();
String count = "SELECT count(*) FROM " + TABLE_NAME;
Cursor c = db.rawQuery(count, null);
c.moveToFirst(); // WARINING if no rows then next line will crash INDEX OUT OF BOUNDS
int icount = c.getInt(0);
e = icount <= 0;
return e;
}
*/
public long getCount(){
int count = 0;
SQLiteDatabase db = getWritableDatabase();
return DatabaseUtils.queryNumEntries(this.getWritableDatabase(),TABLE_NAME);
/*
quick form used as above
String c = "SELECT count(*) FROM " + TABLE_NAME;
Cursor x = db.rawQuery(c, null);
x.moveToFirst();
count = x.getInt(0);
return count;
*/
}
}
You should note the comments, there were some issues with your code.
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<String> mMacList;
SafeDB mDB;
Context mContext;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mMac;
public Button mSafe;
public Button mUnsafe;
public MyViewHolder(View view) {
super(view);
mMac = view.findViewById(R.id.name);
mSafe = view.findViewById(R.id.marksafe);
mUnsafe = view.findViewById(R.id.markunsafe);
}
}
public MyAdapter(Context context,ArrayList<String> maclist) {
mMacList = maclist;
mContext = context;
mDB = new SafeDB(context);
// Could add the mac's to the DB here (note DB changed so mac is unqiue so same mac won't be added)
for (String mac: maclist) {
mDB.addSafeMaker(mac,0);
}
}
#NonNull
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.mylist_item,viewGroup, false);
MyViewHolder vh = new MyViewHolder(v);
mContext = viewGroup.getContext();
return vh;
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder viewHolder, int i) {
viewHolder.mMac.setText(mMacList.get(i));
if (mDB == null) {
mDB = new SafeDB(viewHolder.mMac.getContext());
}
//Set the Tag for the buttons with the mac so it can be retrieved
viewHolder.mSafe.setTag(mMacList.get(i));
viewHolder.mUnsafe.setTag(mMacList.get(i));
// Display the buttons according to the database
if (mDB.getSafeValue(mMacList.get(i))) {
viewHolder.mSafe.setVisibility(View.GONE);
viewHolder.mUnsafe.setVisibility(View.VISIBLE);
} else {
viewHolder.mSafe.setVisibility(View.VISIBLE);
viewHolder.mUnsafe.setVisibility(View.GONE);
}
// Add the onCLickListeners
viewHolder.mSafe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.mSafe.setVisibility(View.GONE);
viewHolder.mUnsafe.setVisibility(View.VISIBLE);
String mac = (String) ((Button) viewHolder.mSafe).getTag();
changeSafeMark((String)viewHolder.mSafe.getTag(),0);
}
});
viewHolder.mUnsafe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.mSafe.setVisibility(View.VISIBLE);
viewHolder.mUnsafe.setVisibility(View.GONE);
changeSafeMark((String)viewHolder.mUnsafe.getTag(),1);
}
});
}
#Override
public int getItemCount() {
return mMacList.size();
}
public int changeSafeMark(String mac, int mark) {
int result = mDB.updateMaker(mac,mark);
return result;
}
}
This is probably quite different and only the simplest of layouts was used.
mylistitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/name"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:id="#+id/marksafe"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Make Safe"
/>
<Button
android:id="#+id/markunsafe"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Make Unsafe"
/>
</LinearLayout>
MainActivity.java
The invoking activity used to test :-
public class MainActivity extends AppCompatActivity {
RecyclerView mList;
RecyclerView.LayoutManager mLayoutManager;
MyAdapter mMyAdapter;
// The underlying data (just a list of strings for the macs)
ArrayList<String> mymacliist = new ArrayList<>(Arrays.asList("M1","M2","M3"));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mList = this.findViewById(R.id.mylist);
mLayoutManager = new LinearLayoutManager(this);
mList.setLayoutManager(mLayoutManager);
mMyAdapter = new MyAdapter(this,mymacliist);
mList.setAdapter(mMyAdapter);
}
}
Results
When First run :-
After M2 and M3 are clicked (buttons are changed to Make Safe when clicked), then the App is stopped and then started :-
database is your best option, you should put the code inside onclicklistiner.
if you want to "toggle" so save a boolean in the database that if it true than the user have been clicked on the item, and if its false, the user didn't clicked the item.
than in your onclicklistiner you do an if statement on the boolean.
I am quite new Android Development and figured I should start by trying to create a simple ToDo List App using SQLite. I have all of the basic functionality in place: adding, updating, and deleting tasks. However, I am adding, updating, and deleting by the title of the task, rather than by the ID. This creates problems with duplicate tasks (e.g. tasks of the same name are deleted simultaneously). After much internet search, I still cannot find a way to do this. I would appreciate any help offered!
Here's my code:
public class TaskDbHelper extends SQLiteOpenHelper {
public TaskDbHelper(Context context) {
super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String createTable = "CREATE TABLE " + TaskContract.TaskEntry.TABLE + " ( " +
TaskContract.TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TaskContract.TaskEntry.COL_TASK_TITLE + " TEXT NOT NULL, " +
TaskContract.TaskEntry.COL_TASK_DATE + " DATE);";
sqLiteDatabase.execSQL(createTable);
}
}
Activity where tasks are shown
public class ShowTaskActivity extends AppCompatActivity {
private TaskDbHelper mHelper;
private ListView mTaskListView;
private ArrayAdapter<String> mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task);
mHelper = new TaskDbHelper(this);
mTaskListView = (ListView) findViewById(R.id.list_todo);
updateUI();
}
private void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase sqLiteDatabase = mHelper.getReadableDatabase();
Cursor cursor = sqLiteDatabase.query(
TaskContract.TaskEntry.TABLE, // Name of the table to be queried
new String[]{ // Which columns are returned
TaskContract.TaskEntry._ID,
TaskContract.TaskEntry.COL_TASK_TITLE,
TaskContract.TaskEntry.COL_TASK_DATE},
null, null, null, null, null);
while (cursor.moveToNext()) {
int index = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(cursor.getString(index));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
task, // What view to use for the items
R.id.task_title, // Where to put the string of data
taskList); // Where to get the data
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
cursor.close();
sqLiteDatabase.close();
}
// TODO: Change to delete by ID, not name
public void deleteTask(View view) {
View parent = (View) view.getParent();
TextView taskTextView = (TextView) parent.findViewById(R.id.task_title);
String task = taskTextView.getText().toString();
SQLiteDatabase sqLiteDatabase = mHelper.getWritableDatabase();
sqLiteDatabase.delete(
TaskContract.TaskEntry.TABLE, // Where to delete
TaskContract.TaskEntry.COL_TASK_TITLE + " = ?", // Boolean check
new String[]{task}); // What to delete
sqLiteDatabase.close();
updateUI();
}
}
Task adding Code
public void addTask(String task, String date) {
SQLiteDatabase sqLiteDatabase = mHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TaskContract.TaskEntry.COL_TASK_TITLE, task);
contentValues.put(TaskContract.TaskEntry.COL_TASK_DATE, date);
sqLiteDatabase.insertWithOnConflict(
TaskContract.TaskEntry.TABLE,
null,
contentValues,
SQLiteDatabase.CONFLICT_REPLACE);
sqLiteDatabase.close();
}
String rowId; //Set your row id here
SQLiteDatabase sqLiteDatabase = mHelper.getWritableDatabase();
sqLiteDatabase.delete(
TaskContract.TaskEntry.TABLE, // Where to delete
KEY_ID+" = ?",
new String[]{rowId}); // What to delete
sqLiteDatabase.close();
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, KEY_ID + " = ?",new String[]{Long.toString(id)} );
db.close();
You can try this method to delete By id
public void deleteData(String tableName, Integer id) {
try {
if (mWritableDB != null) {
mWritableDB.execSQL("delete from " + tableName + " Where id = " + id);
}
} catch (Exception _exception) {
_exception.printStackTrace();
}
}
I am trying to add a top 10 high scores to my game. The high scores are made of only two things - the score and the difficulty, but so far I don't understand very much how this database works but after several tutorials I have this done
public class DBHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "highscores";
private static final String TABLE_DETAIL = "scores";
private static final String KEY_ID = "id";
private static final String KEY_TIME = "time";
private static final String KEY_DIFFICULTY = "difficutly";
public DBHandler(Context context){ super(context, DATABASE_NAME, null, DATABASE_VERSION);}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_HIGHSCORES_TABLE = "CREATE TABLE " + TABLE_DETAIL + "("
+ KEY_ID + " INTEGER PRIMARY KEY, "
+ KEY_TIME + " TEXT, "
+ KEY_DIFFICULTY + " TEXT)";
db.execSQL(CREATE_HIGHSCORES_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DETAIL);
onCreate(db);
}
// Adding new score
public void addScore(int score) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TIME, score); // score value
// Inserting Values
db.insert(TABLE_DETAIL, null, values);
db.close();
}
// Getting All Scores
public String[] getAllScores() {
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_DETAIL;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
int i = 0;
String[] data = new String[cursor.getCount()];
while (cursor.moveToNext()) {
data[i] = cursor.getString(1);
i = i++;
}
cursor.close();
db.close();
// return score array
return data;
}
}
And here is the class that I want to control the database from
public class highscores extends Activity {
private ListView scorebox;
#Override
protected void onCreate(Bundle savedInstanceState) {
DBHandler db = new DBHandler(this);
scorebox = (ListView) findViewById(R.id.scorebox);
super.onCreate(savedInstanceState);
setContentView(R.layout.highscores);
Log.d("Insert: ", "Inserting ..");
db.addScore(9000);
Log.d("Reading: ", "Reading all contacts..");
}
}
When I open the page with the high scores in the application - it is blank, how to make it display something, I tried with this command db.addScore(9000); but it doesn't work. Maybe I didn't told the database where to display that data ?
Edit the Highscore Class
public class highscores extends Activity {
private ListView scorebox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.highscores);
DBHandler db = new DBHandler(this);
scorebox = (ListView) findViewById(R.id.scorebox);
Log.d("Insert: ", "Inserting ..");
db.addScore(9000);
Log.d("Reading: ", "Reading all contacts..");
ArrayList<String>ar=new ArrayList<>();
ar=db.getAllScores();
ArrayAdapter<String>ar=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,s);
scorebox.setAdapter(ar);
}
}
Now in Your DBHandler class Edit getAllScores() method like this
public ArrayList getAllScores() {
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_DETAIL;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
ArrayList<String>data=new ArrayList<>();
while (cursor.moveToNext()) {
data.add(cursor.getString(1));
}
cursor.close();
db.close();
// return score array
return data;
}
if you are using emulator you can pull the db file and check if the table is created or not, if you are using a device you can use this command
cd /D D:\Android\SDK\platform-tools // android sdk path
adb -d shell
run-as com.pkg.pkgname
cat /data/data/com.pkg.pkgname/databases/highscores >/sdcard/highscores
it will copy your db file to device sd card. Using Sqlite browser you can open the db file and check the table is created or not.
Also uninstall the app and install it again
Use this to list your score in your listview
public class highscores extends Activity {
private ListView scorebox;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.highscores);
DBHandler db = new DBHandler(this);
scorebox = (ListView) findViewById(R.id.scorebox);
Log.d("Insert: ", "Inserting ..");
db.addScore(9000);
Log.d("Reading: ", "Reading all contacts..");
String []s=db.getAllScores();
ArrayAdapter<String>ar=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,s);
scorebox.setAdapter(ar);
}
}
I just started with my first App and I am trying to create a table settings, which should contain an entry PIN. after that I want to run the method getPIN() to get the value of this setting.
The problem is, that I get always the error "getDatabase called recursively". As I just started with this, I have no idea how to fix it. I've seen a lot of used to have the same problem, but the solutions doesn't work for me.
Could you please help me to understand what I'm doing wrong.
The contacts table was part of a tutorial I followed before, that´s the reason it's still in there.
Thank you.
This is my Database Helper
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION =3;
private static final String DATABASE_NAME = "contacts.db";
private static final String TABLE_NAME = " contacts";
private static final String COLUMN_ID = "id";
private static final String COLUMN_NAME = "name";
private static final String COLUMN_EMAIL = "email";
private static final String COLUMN_PASS = "pass";
SQLiteDatabase db;
private static final String TABLE_CREATE = "create table contacts (id integer primary key not null ," +
"name text not null, email text not null, pass text not null);";
private static final String TABLE_SETTINGS = "create table settings (id integer primary key not null ," +
"setting text not null, value integer not null);";
public DatabaseHelper(Context context){
super(context, DATABASE_NAME, null,DATABASE_VERSION );
}
#Override
public void onCreate(SQLiteDatabase db){
String ssetting = "PIN";
db.execSQL(TABLE_CREATE);
db.execSQL(TABLE_SETTINGS);
db=this.getWritableDatabase();
ContentValues values = new ContentValues();
String query = "Select * from settings";
Cursor cursor = db.rawQuery(query, null);
int count = cursor.getCount();
values.put("id",count);
values.put("setting", ssetting);
values.put("value", 0);
db.insert("settings", null, values);
db.close();
this.db=db;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
String query = "DROP TABLE IF EXISTS"+TABLE_NAME;
db.execSQL(query);
this.onCreate(db);
}
public int insertContact(Contact c){
db=this.getWritableDatabase();
ContentValues values = new ContentValues();
String query = "Select * from contacts";
Cursor cursor = db.rawQuery(query, null);
int count = cursor.getCount();
values.put(COLUMN_ID,count);
values.put(COLUMN_NAME, c.getName());
values.put(COLUMN_EMAIL, c.getEmail());
values.put(COLUMN_PASS, c.getPass());
db.insert(TABLE_NAME, null, values);
db.close();
return 0;
}
public String searchPass(String uname)
{
db = this.getReadableDatabase();
String query = "select name, pass from "+TABLE_NAME;
Cursor cursor = db.rawQuery(query, null);
String a,b;
b="not found";
if (cursor.moveToFirst()){
do {
a = cursor.getString(0);
b = cursor.getString(1);
if (a.equals(uname)) {
b = cursor.getString(1);
break;
}
}
while(cursor.moveToNext());
}
db.close();
return b;
}
public int getPIN()
{
db = this.getReadableDatabase();
int pin=1;
String query = "select id, setting, value from settings where setting='PIN'";
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()){
do {
pin = cursor.getInt(2);
break;
}
while(cursor.moveToNext());
}
db.close();
return pin;
}
}
and the MainActivity
public class MainActivity extends AppCompatActivity {
DatabaseHelper helper = new DatabaseHelper(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int pin = helper.getPIN();
if (pin==0){
Intent i = new Intent(MainActivity.this, Loginpin.class);
startActivity(i);
}
if (pin==1) {
Intent i = new Intent(MainActivity.this, Setuppin.class);
startActivity(i);
}
//pin = helper.getPIN();
}
public void b_newOnClick(View v) {
if (v.getId() == R.id.blogin)
{
EditText user = (EditText) findViewById(R.id.tfuser);
String su = user.getText().toString();
EditText pass = (EditText) findViewById(R.id.tf_pw);
String spass = pass.getText().toString();
String password = helper.searchPass(spass);
if(spass.equals(password))
{
Intent i = new Intent(MainActivity.this, Welcome.class);
i.putExtra("username", su);
startActivity(i);
}
else{
Toast.makeText(MainActivity.this, "Password incorrect", Toast.LENGTH_LONG).show();
}
}
}
public void onSignClick(View v) {
if (v.getId() == R.id.bsign) {
Intent i = new Intent(MainActivity.this, SignUp.class);
startActivity(i);
}
}
}
Thank you so much.
regards, S
Kilimanscharo
Don't call getWritableDatabase() or getReadableDatabase() from your SQLiteOpenHelper lifecycle methods such as onCreate() or onUpgrade() that are in turn triggered by a call to get...Database(). Instead, use the SQLiteDatabase object that is given as a parameter to these methods.
Specifically, remove this line from your onCreate():
db=this.getWritableDatabase();
I'm new to Java and just tried to make a database. I managed to make a DB and all but when I want to read the values it seems to get an error.
This is my code for my settings activity (which asks for setting values and add them in the DB on a specific ID)
public class Settings extends Activity{
Button Save;
static Switch SwitchCalculations;
public static String bool;
public static List<Integer> list_id = new ArrayList<Integer>();
public static List<String> list_idname = new ArrayList<String>();
public static List<String> list_kind = new ArrayList<String>();
public static List<String> list_value = new ArrayList<String>();
static Integer[] arr_id;
static String[] arr_idname;
static String[] arr_kind;
static String[] arr_value;
public static final String TAG = "Settings";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
Save = (Button) findViewById(R.id.btnSave);
SwitchCalculations = (Switch) findViewById(R.id.switchCalcOnOff);
readData();
Save.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
writeData();
//Toast.makeText(this, "Data has been saved.", Toast.LENGTH_SHORT).show();
readData();
Save.setText("Opgeslagen");
}
});
}
public void writeData() {
int id = 1;
String idname = "switchCalcOnOff";
String kind = "switch";
boolean val = SwitchCalculations.isChecked();
String value = new Boolean(val).toString();
dbHelper_Settings dbh = new dbHelper_Settings(this);
SQLiteDatabase db = dbh.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(dbh.C_ID, id);
cv.put(dbh.C_IDNAME, idname);
cv.put(dbh.C_KIND, kind);
cv.put(dbh.C_VALUE, value);
if (dbh.C_ID.isEmpty() == true) {
db.insert(dbh.TABLE, null, cv);
Log.d(TAG, "Insert: Data has been saved.");
} else if (dbh.C_ID.isEmpty() == false) {
db.update(dbh.TABLE, cv, "n_id='1'", null);
Log.d(TAG, "Update: Data has been saved.");
} else {
Log.d(TAG, "gefaald");
}
db.close();
}
public void readData() {
dbHelper_Settings dbh = new dbHelper_Settings(this);
SQLiteDatabase db = dbh.getWritableDatabase();
List<String> list_value = new ArrayList<String>();
String[] arr_value;
list_value.clear();
Cursor cursor = db.rawQuery("SELECT " + dbh.C_VALUE + " FROM " + dbh.TABLE + ";", null);
if (cursor.moveToFirst()) {
do {
list_value.add(cursor.getString(0));
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()){
cursor.close();
}
db.close();
arr_value = new String[list_value.size()];
for (int i = 0; i < list_value.size(); i++){
arr_value[i] = list_value.get(i);
}
}
}
Then I have my dbHelper activity see below:
package com.amd.nutrixilium;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class dbHelper_Settings extends SQLiteOpenHelper{
private static final String TAG="dbHelper_Settings";
public static final String DB_NAME = "settings.db";
public static final int DB_VERSION = 10;
public final String TABLE = "settings";
public final String C_ID = "n_id"; // Special for id
public final String C_IDNAME = "n_idname";
public final String C_KIND = "n_kind";
public final String C_VALUE = "n_value";
Context context;
public dbHelper_Settings(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
}
// oncreate wordt maar 1malig uitgevoerd per user voor aanmaken van database
#Override
public void onCreate(SQLiteDatabase db) {
String sql = String.format("create table %s (%s int primary key, %s TEXT, %s TEXT, %s TEXT)", TABLE, C_ID, C_IDNAME, C_KIND, C_VALUE);
Log.d(TAG, "onCreate sql: " + sql);
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + TABLE); // wist een oudere database versie
Log.d(TAG, "onUpgrate dropped table " + TABLE);
this.onCreate(db);
}
}
And the weird thing is I don't get any error messages here.
But I used Log.d(TAG, text) to check where the script is being skipped and that is at cursor.moveToFirst().
So can anyone help me with this problem?
Here, contrary to what you seem to expect, you actually check that a text constant is not empty:
if (dbh.C_ID.isEmpty() == true) {
It isn't : it always contains "n_id"
I think your intent was to find a record with that id and, depending on the result, either insert or update.
You should do just that: attempt a select via the helper, then insert or update as in the code above.
Edit:
Add to your helper something like this:
public boolean someRowsExist(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("select EXISTS ( select 1 from " + TABLE + " )", new String[] {});
cursor.moveToFirst();
boolean exists = (cursor.getInt(0) == 1);
cursor.close();
return exists;
}
And use it to check if you have any rows in the DB:
if (dbh.someRowsExist(db)) { // instead of (dbh.C_ID.isEmpty() == true) {
Looks like you're having trouble debugging your query. Android provides a handy method DatabaseUtils.dumpCursorToString() that formats the entire Cursor into a String. You can then output the dump to LogCat and see if any rows were actually skipped.