So I recently got into Android programming and have been following this tutorial on how to insert, update, delete and view data in an SQLite database. Now, I would also like to add a search functionality to this SQLite database where I can search for a name (the columns I'm using are name, contact and DOB) and if the searched for name matches an existing one in the database, display this row/entry from the database in the application. I figured this could be done in a similar way as the viewing/updating the database, so I tried coming up with a solution for this with these as reference, however after having tried a good amount of ways that seemed reasonable to me I still haven't gotten it to work, so I'd greatly appreciate any help with this! I feel like I was close w/ some of my attempts but something with the logic didn't click completely.
MainActivity.java:
package com.example.sqliteapplication;
import ...
public class MainActivity extends AppCompatActivity {
EditText name, contact, dob;
Button insert, update, delete, view, search;
DBHelper DB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = findViewById(R.id.name);
contact = findViewById(R.id.contact);
dob = findViewById(R.id.dob);
insert = findViewById(R.id.btnInsert);
update = findViewById(R.id.btnUpdate);
delete = findViewById(R.id.btnDelete);
view = findViewById(R.id.btnView);
search = findViewById(R.id.btnSearch);
DB = new DBHelper(this);
insert.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString();
String contactTXT = contact.getText().toString();
String dobTXT = dob.getText().toString();
Boolean checkinsertdata = DB.insertuserdata(nameTXT, contactTXT, dobTXT);
if(checkinsertdata==true)
Toast.makeText(MainActivity.this, "New Entry Inserted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "New Entry Not Inserted", Toast.LENGTH_SHORT).show();
} });
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString();
String contactTXT = contact.getText().toString();
String dobTXT = dob.getText().toString();
Boolean checkupdatedata = DB.updateuserdata(nameTXT, contactTXT, dobTXT);
if(checkupdatedata==true)
Toast.makeText(MainActivity.this, "Entry Updated", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "New Entry Not Updated", Toast.LENGTH_SHORT).show();
} });
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString();
Boolean checkudeletedata = DB.deletedata(nameTXT);
if(checkudeletedata==true)
Toast.makeText(MainActivity.this, "Entry Deleted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "Entry Not Deleted", Toast.LENGTH_SHORT).show();
} });
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Cursor res = DB.getdata();
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()){
buffer.append("Name :"+res.getString(0)+"\n");
buffer.append("Contact :"+res.getString(1)+"\n");
buffer.append("Date of Birth :"+res.getString(2)+"\n\n");
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("User Entries");
builder.setMessage(buffer.toString());
builder.show();
} });
}
}
DBHelper.java:
package com.example.sqliteapplication;
import ...
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "Userdata.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase DB) {
DB.execSQL("create Table Userdetails(name TEXT primary key," +
"contact TEXT, dob TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase DB, int oldVersion, int newVersion) {
DB.execSQL("drop Table if exists Userdetails");
}
public Boolean insertuserdata(String name, String contact, String dob) {
SQLiteDatabase DB = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("contact", contact);
contentValues.put("dob", dob);
long result = DB.insert("Userdetails",
null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public Boolean updateuserdata(String name, String contact, String dob) {
SQLiteDatabase DB = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("contact", contact);
contentValues.put("dob", dob);
Cursor cursor = DB.rawQuery(
"Select * from Userdetails where name = ?", new String[]{name});
if (cursor.getCount() > 0) {
long result = DB.update("Userdetails",
contentValues, "name=?",
new String[]{name});
if (result == -1) {
return false;
} else {
return true;
}
} else {
return false;
}
}
public Boolean deletedata(String name) {
SQLiteDatabase DB = this.getWritableDatabase();
Cursor cursor = DB.rawQuery(
"Select * from Userdetails where name = ?", new String[]{name});
if (cursor.getCount() > 0) {
long result = DB.delete("Userdetails", "name=?",
new String[]{name});
if (result == -1) {
return false;
} else {
return true;
}
} else {
return false;
}
}
public Cursor getdata () {
SQLiteDatabase DB = this.getWritableDatabase();
Cursor cursor = DB.rawQuery(
"Select * from Userdetails ", null);
return cursor;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:padding="10dp"
tools:context=".MainActivity">
<TextView
android:id="#+id/texttitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Please enter details below"
android:textSize="24dp"
android:layout_marginTop="20dp"
/>
<EditText
android:id="#+id/name"
android:hint="Name"
android:textSize="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/texttitle"
android:inputType="textPersonName"
/>
<EditText
android:id="#+id/contact"
android:hint="Contact"
android:textSize="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/name"
android:inputType="number"
/>
<EditText
android:id="#+id/dob"
android:hint="Date of Birth"
android:textSize="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/contact"
android:inputType="number"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnInsert"
android:textSize="24dp"
android:text="Insert New Data"
android:layout_marginTop="30dp"
android:layout_below="#+id/dob"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnUpdate"
android:textSize="24dp"
android:text="Update Data"
android:layout_below="#+id/btnInsert"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnDelete"
android:textSize="24dp"
android:text="Delete Data"
android:layout_below="#+id/btnUpdate"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnView"
android:textSize="24dp"
android:text="View Data"
android:layout_below="#+id/btnDelete"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnSearch"
android:textSize="24dp"
android:text="Search Data"
android:layout_below="#+id/btnView"
/>
</RelativeLayout>
Sorry in advance for perhaps some bad explanations/something not making sense, I'm only a few weeks into this and got a lot to learn for sure! Thanks
You can modify getdata() so that it takes as an argument the name, or part of the name that you search for:
public Cursor getdata(String name) {
SQLiteDatabase DB = this.getWritableDatabase();
String sql = "Select * from Userdetails";
String[] selectionArgs = null;
if (name != null) {
sql += " where name LIKE '%' || ? || '%'";
selectionArgs = new String[] {name};
}
return DB.rawQuery(sql, selectionArgs);
}
and you should also modify in the listener of the button view the call to getdata() to pass null so that you get as result all the rows of the table:
Cursor res = DB.getdata(null);
Then you create the listener for the button search:
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String searchName = name.getText().toString().trim();
if (searchName.length() == 0) return;
Cursor res = DB.getdata(searchName);
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()){
buffer.append("Name :"+res.getString(0)+"\n");
buffer.append("Contact :"+res.getString(1)+"\n");
buffer.append("Date of Birth :"+res.getString(2)+"\n\n");
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("User Entries");
builder.setMessage(buffer.toString());
builder.show();
}
});
Note that there is no need to query the table before you insert, update, delete a row.
You can perform the operation that you want and then examine the result of the method insert() or update() or delete() to decide whether it was successful or not.
Remember that only insert() returns -1 if unsuccessful.
update() and delete() return the number of affected (updated/deleted) rows.
So, I would write the code like this:
package com.example.sqliteapplication;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "Userdata.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase DB) {
DB.execSQL("create Table Userdetails(name TEXT primary key, contact TEXT, dob TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase DB, int oldVersion, int newVersion) {
DB.execSQL("drop Table if exists Userdetails");
}
public Boolean insertuserdata(String name, String contact, String dob) {
SQLiteDatabase DB = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("contact", contact);
contentValues.put("dob", dob);
long result = DB.insert("Userdetails", null, contentValues);
return (result != -1);
}
public Boolean updateuserdata(String name, String contact, String dob) {
SQLiteDatabase DB = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("contact", contact);
contentValues.put("dob", dob);
long result = DB.update("Userdetails", contentValues, "name = ?", new String[]{name});
return (result > 0);
}
public Boolean deletedata(String name) {
SQLiteDatabase DB = this.getWritableDatabase();
long result = DB.delete("Userdetails", "name = ?", new String[]{name});
return (result > 0);
}
public Cursor getdata(String name) {
SQLiteDatabase DB = this.getWritableDatabase();
String sql = "Select * from Userdetails";
String[] selectionArgs = null;
if (name != null) {
sql += " where name LIKE '%' || ? || '%'";
selectionArgs = new String[] {name};
}
return DB.rawQuery(sql, selectionArgs);
}
}
and for the activity class:
package com.example.sqliteapplication;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText name, contact, dob;
Button insert, update, delete, view, search;
DBHelper DB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = findViewById(R.id.name);
contact = findViewById(R.id.contact);
dob = findViewById(R.id.dob);
insert = findViewById(R.id.btnInsert);
update = findViewById(R.id.btnUpdate);
delete = findViewById(R.id.btnDelete);
view = findViewById(R.id.btnView);
search = findViewById(R.id.btnSearch);
DB = new DBHelper(this);
insert.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString().trim();
String contactTXT = contact.getText().toString().trim();
String dobTXT = dob.getText().toString().trim();
Boolean checkinsertdata = DB.insertuserdata(nameTXT, contactTXT, dobTXT);
if(checkinsertdata==true)
Toast.makeText(MainActivity.this, "New Entry Inserted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "New Entry Not Inserted", Toast.LENGTH_SHORT).show();
}
});
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString().trim();
String contactTXT = contact.getText().toString().trim();
String dobTXT = dob.getText().toString().trim();
Boolean checkupdatedata = DB.updateuserdata(nameTXT, contactTXT, dobTXT);
if(checkupdatedata==true)
Toast.makeText(MainActivity.this, "Entry Updated", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "New Entry Not Updated", Toast.LENGTH_SHORT).show();
}
});
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String nameTXT = name.getText().toString().trim();
Boolean checkudeletedata = DB.deletedata(nameTXT);
if(checkudeletedata==true)
Toast.makeText(MainActivity.this, "Entry Deleted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "Entry Not Deleted", Toast.LENGTH_SHORT).show();
}
});
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Cursor res = DB.getdata(null);
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()){
buffer.append("Name :"+res.getString(0)+"\n");
buffer.append("Contact :"+res.getString(1)+"\n");
buffer.append("Date of Birth :"+res.getString(2)+"\n\n");
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("User Entries");
builder.setMessage(buffer.toString());
builder.show();
}
});
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String searchName = name.getText().toString().trim();
if (searchName.length() == 0) return;
Cursor res = DB.getdata(searchName);
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()){
buffer.append("Name :"+res.getString(0)+"\n");
buffer.append("Contact :"+res.getString(1)+"\n");
buffer.append("Date of Birth :"+res.getString(2)+"\n\n");
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("User Entries");
builder.setMessage(buffer.toString());
builder.show();
}
});
}
}
In DBHelper.java add:
public Cursor getDataByName(String name){
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery("SELECT * FROM Userdetails WHERE name LIKE '%"+name+"'%", null);
}
In MainActivity.java:
Add a new global EditText:
EditText name, contact, dob, **search**;
onCreate() add:
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchInDatabase();
}
}
Somewhere in your MainActivity.java add this new method.
private void searchInDatabaseByName(){
Cursor res = DB.getDataByName(name.getText().toString());
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
Cursor res = DB.getdata();
if(res.getCount()==0){
Toast.makeText(MainActivity.this, "No Entry Exists", Toast.LENGTH_SHORT).show();
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()){
buffer.append("Name :"+res.getString(0)+"\n");
buffer.append("Contact :"+res.getString(1)+"\n");
buffer.append("Date of Birth :"+res.getString(2)+"\n\n");
}
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setTitle("User Entries");
builder.setMessage(buffer.toString());
builder.show();
}
Now the explanation:
In sqlite you can query for data using the LIKE keyword. for example in order to find all the rows with the name 'Bob' you can query for
SELECT * FROM Userdetails WHERE name LIKE '%Bob%'
Then, the returned cursor will contain all the rows that have the name Bob.
Then we've added another EditText variable to search (you'll need to add it to the main_acitivity.xml as well).
Now you can use that to type in the name you want to search and then click the 'search' button, which in return will call the 'searchInDatabaseByName' method which does the exact same thing as your 'view' button but simply goes to our new DBHelper method 'getDataByName'.
Please notice that its recommended to let the DBHelper do all the stuff of fetching the actual data (meaning it will get the cursor and also parse it)
You might want to create a model class for your User entity.
and then the database method will return an arraylist of users which will later be much easier to show in a Dialog (or even better, in a ListView)
Related
//MAIN ACTIVITY
package com.example.saosteste2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private BancoDados_Registo dbManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbManager = new BancoDados_Registo(MainActivity.this);
TextView email = (TextView) findViewById(R.id.id_email);
TextView password = (TextView) findViewById(R.id.id_password);
Button BLogIn = (Button) findViewById(R.id.id_Blogin);
Button conta_btn = (Button) findViewById(R.id.id_criarconta);
//testing email e password
BLogIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ????
}
});
conta_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, registo.class);
startActivity(intent);
}
});
}
}
//-----------------------SECOND ACTIVITY WITH THE DATABASE-----------------------//
//BANCODADOS_REGISTOS
package com.example.saosteste2;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class BancoDados_Registo extends SQLiteOpenHelper {
public BancoDados_Registo(Context context) {
super(context, "REGISTOS.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create Table Registos(nome TEXT primary key, email TEXT, password TEXT, morada TEXT, telemovel TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop Table if exists Registos");
}
// INSERT DATA
public Boolean insertuserdata(String nome, String email, String password, String morada, String telemovel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("nome", nome);
contentValues.put("email", email);
contentValues.put("password", password);
contentValues.put("morada", morada);
contentValues.put("telemovel", telemovel);
long result=db.insert("Registos", null, contentValues);
if (result==-1){ //se o insert falhar
return false;
}else{
return true;
}
}
//UPDATE DATA
public Boolean updateuserdata(String nome, String email, String password, String morada, String telemovel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("nome", nome);
contentValues.put("email", email);
contentValues.put("password", password);
contentValues.put("morada", morada);
contentValues.put("telemovel", telemovel);
Cursor cursor = db.rawQuery("Select * from Registos where nome = ?", new String[] {nome});
if (cursor.getCount()>0){ //se o cursor tiver dados
long result=db.update("Registos", contentValues, "nome=?", new String [] {nome});
if (result==-1){ //se o insert falhar
return false;
}else{
return true;
}
}else {
return false;
}
}
//DELETEDATA
public Boolean deleteuserdata(String nome){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("Select * from Registos where nome = ?", new String[] {nome});
if (cursor.getCount()>0){ //se o cursor tiver dados
long result=db.delete("Registos", "nome=?", new String [] {nome});
if (result==-1){ //se o insert falhar
return false;
}else{
return true;
}
}else {
return false;
}
}
public Cursor getuserdata(String email, String password){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("Select * from Registos", null);
return cursor;
}
Hi everyone!
I'm new in the world of Java and Android Studio. I don't know how to transmit data from the databse created in the second Activity to the first one. I need help checking if the email and password that the user puts on the first Activity (MainActivity) already exists in the database I created in the second Activity (BancoDados_Registo). Thank you for your attention in advance!
Here's a working example (but one that uses the deprecated startActivityForresult) based upon your code.
You should really look at https://developer.android.com/training/basics/intents/result for the non-deprecated way though.
When the App is started MainActivity displays the login/registo buttons:-
note hints added for email and password just to show where the TextViews.
Clicking the Registo button starts the Registo activity with empty EditTexts
for the nome,email,password morada and telemovel and a button to register (add) :-
Entering suitable data e.g. :-
And then clicking the Registo button, adds the user (if not a duplicate) and returns to MainActivity passing the nome and rowid which is then used to complete the email and password TextViews (not that you would do this, but rather to show extracting the data from the database) :-
The code:-
MainActivty
public class MainActivity extends AppCompatActivity {
private BancoDados_Registo dbManager;
TextView email; //<<<<< MOVED for full scope
TextView password; //<<<<< Moved for full scope
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbManager = new BancoDados_Registo(MainActivity.this);
email = (TextView) findViewById(R.id.id_email);
password = (TextView) findViewById(R.id.id_password);
Button BLogIn = (Button) findViewById(R.id.id_Blogin);
Button conta_btn = (Button) findViewById(R.id.id_criarconta);
//testing email e password
BLogIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ????
}
});
conta_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, Registo.class);
startActivityForResult(intent,Registo.REGISTO_RESULTSCODE); // deprecated but works
}
});
}
#SuppressLint("Range")
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Registo.REGISTO_RESULTSCODE && resultCode == RESULT_OK) {
Toast.makeText(this,"Registered with ID " + data.getLongExtra(Registo.INTENTEXTRAKEY_REGISTOID,-1),Toast.LENGTH_LONG).show();
if (data.getLongExtra(Registo.INTENTEXTRAKEY_REGISTOID,-1) > 0) {
Cursor csr = dbManager.getUserDataByNome(data.getStringExtra(Registo.INTENTEXTRAKEY_REGISTONOME));
if (csr.moveToFirst()) {
password.setText(csr.getString(csr.getColumnIndex("password")));
email.setText(csr.getString(csr.getColumnIndex("email")));
}
}
}
}
}
BancoDados_Registo (changed/added methods only) :-
// INSERT DATA <<<<< CHANGED (to return rowid which can be more useful as it can be used to get the row)
public Long insertuserdata(String nome, String email, String password, String morada, String telemovel) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("nome", nome);
contentValues.put("email", email);
contentValues.put("password", password);
contentValues.put("morada", morada);
contentValues.put("telemovel", telemovel);
return db.insert("Registos", null, contentValues);
}
/* ADDED to get User just by nome */
public Cursor getUserDataByNome(String nome) {
SQLiteDatabase db = this.getWritableDatabase();
return db.query("Registos",null,"nome=?",new String[]{nome},null,null,null);
}
Registo activity (note capitalised) :-
public class Registo extends AppCompatActivity {
private BancoDados_Registo dbManager;
public static final int REGISTO_REQUESTCODE = 98; //<<<
public static final String INTENTEXTRAKEY_REGISTOID = "ie_registo_id";
public static final String INTENTEXTRAKEY_REGISTONOME = "ie_registo_nome";
EditText nome;
EditText email;
EditText password;
EditText morada;
EditText telemovel;
Button registro;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registo);
nome = this.findViewById(R.id.id_nome);
email = this.findViewById(R.id.id_email);
password = this.findViewById(R.id.id_password);
morada = this.findViewById(R.id.id_morada);
telemovel = this.findViewById(R.id.id_telemovel);
registro = (Button) findViewById(R.id.id_registro);
dbManager = new BancoDados_Registo(this);
registro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/* Only insert in valid data - else Toast incomplete*/
if (
email.getText().length() > 0
&& password.getText().length() >= 8
&& morada.getText().length() > 0
&& telemovel.getText().length() > 0
) {
Long rowid = dbManager.insertuserdata(nome.getText().toString(),email.getText().toString(),password.getText().toString(),morada.getText().toString(),telemovel.getText().toString());
if (rowid > 0) {
Toast.makeText(view.getContext(),"Registered",Toast.LENGTH_LONG).show();
Intent resultIntent = new Intent();
resultIntent.putExtra(INTENTEXTRAKEY_REGISTOID,rowid);
resultIntent.putExtra(INTENTEXTRAKEY_REGISTONOME,nome.getText().toString());
setResult(RESULT_OK,resultIntent);
finish();
} else {
Toast.makeText(view.getContext(),"Not Registered (duplicate)",Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(view.getContext(),"Not Registered Incomplete input fields!!",Toast.LENGTH_LONG).show();
}
}
});
}
}
im trying to implement database to my aplication. It is first time when i am doing this.
I have a layout with list view and im using a SimpleCoursorAdapter to transport data from dataBase to my ListView. The aplication doesn't show anything. ListView is empty i don't know why.
It is my TopLevelActivity
public class TopLevelActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top_level);
AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView,
View v,
int position,
long id) {
if(position == 0){
Intent intent = new Intent(TopLevelActivity.this, DrinkCategoryActivity.class);
startActivity(intent);
}
if(position == 1){
Intent intent = new Intent(TopLevelActivity.this, SnacksCategoryActivity.class);
startActivity(intent);
}
}
};
ListView listView = (ListView) findViewById(R.id.list_options);
listView.setOnItemClickListener(itemClickListener);
}
}
xml from TopLevelActivity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".TopLevelActivity">
<ImageView
android:layout_width="200dp"
android:layout_height="100dp"
android:src="#drawable/starbuzz_logo"
android:contentDescription="#string/starbuzz_logo"/>
<ListView
android:id="#+id/list_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/options"/>
</LinearLayout>
the DrinkCategoryActivity i think here is somethink wrong
public class DrinkCategoryActivity extends Activity {
private SQLiteDatabase db;
private Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_category);
ListView listDrinks = (ListView) findViewById(R.id.list_drinks);
SQLiteOpenHelper coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
try {
db = coffeinaDatabaseHelper.getReadableDatabase();
cursor = db.query("DRINK",
new String[]{"_id", "NAME"},
null, null, null, null, null);
SimpleCursorAdapter listAdapter = new SimpleCursorAdapter
(this,
android.R.layout.simple_list_item_1,
cursor,
new String[]{"NAME"},
new int[]{android.R.id.text1},0
);
listDrinks.setAdapter(listAdapter);
} catch (SQLiteException e) {
Toast toast = Toast.makeText(this, "Baza danych jest niedostepna",
Toast.LENGTH_SHORT);
toast.show();
}
AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> listDrinks,
View itemView,
int position,
long id) {
Intent intent = new Intent(DrinkCategoryActivity.this,
DrinkActivity.class);
intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int) id);
startActivity(intent);
}
};
listDrinks.setOnItemClickListener(itemClickListener);
}
public void onDestroy() {
super.onDestroy();
cursor.close();
db.close();
}
}
xml from DrinkCategoryActivity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_height="match_parent"
tools:context=".DrinkCategoryActivity">
<ListView
android:id="#+id/list_drinks"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
DrinkAtivity
public class DrinkActivity extends AppCompatActivity {
public static final String EXTRA_DRINKID = "drinkId";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);
SQLiteOpenHelper starbuzzDatabaseHelper = new CoffeinaDatabaseHelper(this);
try{
SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
Cursor cursor = db.query("DRINK",
new String[]{"NAME", "DESCRIPTION", "IMAGE_RESORUCE_ID"},
"_id = ?",
new String[]{Integer.toString(drinkId)},
null, null, null);
if(cursor.moveToFirst()){
String nameText = cursor.getString(0);
String descriptionText = cursor.getString(1);
int photoId = cursor.getInt(2);
TextView name = (TextView)findViewById(R.id.name);
name.setText(nameText);
TextView description = (TextView)findViewById(R.id.description);
description.setText(descriptionText);
ImageView photo = (ImageView)findViewById(R.id.latte);
photo.setImageResource(photoId);
photo.setContentDescription(nameText);
}
cursor.close();
db.close();
}catch (SQLiteException e){
Toast toast = Toast.makeText(this, "Bada danych jest niedostepna",
Toast.LENGTH_SHORT);
toast.show();
}
}
}
xml from DrinkActivity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".DrinkActivity">
<ImageView
android:id="#+id/latte"
android:layout_width="190dp"
android:layout_height="190dp"/>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
and my DataBaseHelper and here can be also somethink wrong.
The complicator doesn't show any error.
package com.hfad.coffeina;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CoffeinaDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "coffeina";
private static final int DB_VERSION = 2;
CoffeinaDatabaseHelper(Context context){
super(context, DB_NAME, null, DB_VERSION);
}
public void onCreate(SQLiteDatabase db){
updateMyDatabase(db, 0, DB_VERSION);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
updateMyDatabase(db, oldVersion, newVersion);
}
private static void insertDrink(SQLiteDatabase db, String name, String description,
int resourceId){
ContentValues drinkValues = new ContentValues();
drinkValues.put("NAME", name);
drinkValues.put("DESCRIPTION", description);
drinkValues.put("IMAGE_RESOURCE_ID", resourceId);
db.insert("DRINK", null, drinkValues);
}
private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion){
if(oldVersion < 1){
db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+"NAME TEXT, "
+"DESCRIPTON TEXT , "
+"IMAGE_RESOURCE_ID INTEGER);");
insertDrink(db, "Latte", "Czarne espresso z gorącym mlekiem i mleczną pianką.",
R.drawable.latte);
insertDrink(db, "Cappucciono", "Czarne espresso z dużą ilościa spienionego mleka",
R.drawable.cappuccino);
insertDrink(db, "Espresso", "Czarna kawa ze świeżo mielonych ziaren najwyższej jakości.",
R.drawable.filter);
}
if(oldVersion < 2){
db.execSQL("ALTER TABLE DRINK ADD COLUMN FAVORITE NUMERIC;");
}
}
}
The print Screen from emulator enter image description here
The Issue
I believe that your prime issue is that in the DRINK table you define a column name using +"DESCRIPTON TEXT , " yet you refer to the DESCRIPTION column (tion as opposed to ton) elsewhere including when inserting the 3 initial rows. Hidden/disguised because they are in try .... catch constructs.
Note that wrapping SQLite stuff in try .... catch is typically unhelpful and leads to confusion, especially if the log isn't checked when testing.
That is the log would show something like :-
07-21 17:29:20.748 4340-4340/a.a.so68457788javesqlitelistview E/SQLiteLog: (1) table DRINK has no column named DESCRIPTION
07-21 17:29:20.749 4340-4340/a.a.so68457788javesqlitelistview E/SQLiteDatabase: Error inserting NAME=Latte DESCRIPTION=Czarne espresso z gorącym mlekiem i mleczną pianką. IMAGE_RESOURCE_ID=10
android.database.sqlite.SQLiteException: table DRINK has no column named DESCRIPTION (code 1): , while compiling: INSERT INTO DRINK(NAME,DESCRIPTION,IMAGE_RESOURCE_ID) VALUES (?,?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
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.insertWithOnConflict(SQLiteDatabase.java:1469)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.insertDrink(CoffeinaDatabaseHelper.java:32)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.updateMyDatabase(CoffeinaDatabaseHelper.java:42)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.onCreate(CoffeinaDatabaseHelper.java:18)
As such the database will be empty and hence why the ListView shows nothing.
I would suggest ALWAYS using a single definition for database components and ALWAYS referring to the components using the single definition.
Suggested Fix/Improvment
Perhaps consider using :-
class CoffeinaDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "coffeina";
private static final int DB_VERSION = 2;
public static final String DRINK_TABLENAME = "DRINK";
public static final String DRINK_ID_COLUMN = BaseColumns._ID; // Android _id column name
public static final String DRINK_NAME_COLUMN = "NAME";
public static final String DRINK_DESCRIPTION_COLUMN = "DESCRIPTION";
public static final String DRINK_IMAGE_RESOURCE_ID_COLUMN = "IMAGE_RESOURCE_ID";
public static final String DRINK_FAVORITE_COLUMN = "FAVOURITE";
CoffeinaDatabaseHelper(Context context){
super(context, DB_NAME, null, DB_VERSION);
}
public void onCreate(SQLiteDatabase db){
updateMyDatabase(db, 0, DB_VERSION);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
updateMyDatabase(db, oldVersion, newVersion);
}
private static void insertDrink(SQLiteDatabase db, String name, String description,
int resourceId){
ContentValues drinkValues = new ContentValues();
drinkValues.put(DRINK_NAME_COLUMN, name);
drinkValues.put(DRINK_DESCRIPTION_COLUMN, description);
drinkValues.put(DRINK_IMAGE_RESOURCE_ID_COLUMN, resourceId);
db.insert(DRINK_TABLENAME, null, drinkValues);
}
private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion){
if(oldVersion < 1){
/* no need for autoincrement id's will be generated without the overheads
check https://sqlite.org/autoinc.html for details/why
*/
db.execSQL("CREATE TABLE " + DRINK_TABLENAME + " (" + DRINK_ID_COLUMN + " INTEGER PRIMARY KEY, "
+ DRINK_NAME_COLUMN + " TEXT,"
+ DRINK_DESCRIPTION_COLUMN +" TEXT , "
+ DRINK_IMAGE_RESOURCE_ID_COLUMN + " INTEGER);");
insertDrink(db, "Latte", "Czarne espresso z gorącym mlekiem i mleczną pianką.",10);
insertDrink(db, "Cappucciono", "Czarne espresso z dużą ilościa spienionego mleka", 11);
insertDrink(db, "Espresso", "Czarna kawa ze świeżo mielonych ziaren najwyższej jakości.", 12);
}
if(oldVersion < 2){
db.execSQL("ALTER TABLE DRINK ADD COLUMN " + DRINK_FAVORITE_COLUMN + " NUMERIC;");
}
}
}
NOTE for testing the image resource id's have been made up, these will need to be changed to reflect your original code.
And then subsequently referring the the database components elsewhere using the constants. For example consider the following version of the DrinkCategoryActivity class :-
public class DrinkCategoryActivity extends AppCompatActivity {
CoffeinaDatabaseHelper coffeinaDatabaseHelper; //<<<<< ADDED you want instance of YOUR helper not an SQLiteOpenHelper
SQLiteDatabase db;
Cursor cursor;
SimpleCursorAdapter listAdapter; //<<<<< Better here, more scope
ListView listDrinks;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_category);
listDrinks = (ListView) findViewById(R.id.list_drinks);
// SQLiteOpenHelper coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
db = coffeinaDatabaseHelper.getWritableDatabase(); // get readable will typically get writeable anyway
setOrRefreshListView();
}
private void setOrRefreshListView() {
cursor = db.query(CoffeinaDatabaseHelper.DRINK_TABLENAME,
new String[]{"_id", CoffeinaDatabaseHelper.DRINK_NAME_COLUMN},
null, null, null, null, null);
if (listAdapter == null) {
listAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1, cursor,
new String[]{"NAME"},
new int[]{android.R.id.text1}, 0);
listDrinks.setAdapter(listAdapter);
listDrinks.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(view.getContext(), DrinkActivity.class);
intent.putExtra(DrinkActivity.EXTRA_DRINKID, l);
startActivity(intent);
}
});
} else {
listAdapter.swapCursor(cursor);
}
}
/* If returning to Activity (from DrinkActivity) refresh the ListView
just in case it has changed
*/
#Override
protected void onResume() {
super.onResume();
setOrRefreshListView();
}
#Override
protected void onDestroy() {
super.onDestroy();
cursor.close();
}
}
Using the above then :-
Additional
taking the above further then a working (albeit without the images) and more concise version of the DrinkActity is :-
public class DrinkActivity extends AppCompatActivity {
public static final String EXTRA_DRINKID = "drinkId";
CoffeinaDatabaseHelper DBHelper;
SQLiteDatabase db;
TextView name,description;
ImageView photo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
long drinkId = this.getIntent().getLongExtra(DrinkActivity.EXTRA_DRINKID,-1); // Should be LONG
DBHelper = new CoffeinaDatabaseHelper(this);
db = DBHelper.getWritableDatabase();
name = this.findViewById(R.id.name);
description = this.findViewById(R.id.description);
Cursor cursor = db.query(CoffeinaDatabaseHelper.DRINK_TABLENAME,
null,
CoffeinaDatabaseHelper.DRINK_ID_COLUMN +" = ?",
new String[]{String.valueOf(drinkId)}, // cope with Long
null, null, null);
if(cursor.moveToFirst()){
name.setText(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_NAME_COLUMN)));
description.setText(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_DESCRIPTION_COLUMN)));
//<<<<< COMMENTED OUT FOR TESTING (as invalid resource id's have been used) >>>>>
//photo.setImageResource(cursor.getInt(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_IMAGE_RESOURCE_ID_COLUMN)));
//photo.setContentDescription(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_NAME_COLUMN)));
} else {
Toast.makeText(this, "Bada danych jest niedostepna", Toast.LENGTH_SHORT).show();
}
cursor.close();
//db.close(); don't close, resource expensive to open
}
}
So selecting Latte gives :-
I have a problem, namely, I have an application that displays in the RecyclerView 2 types of salads and after pressing, one of them should show a view showing their exact details with the option of whether or not we like it. These data are obviously retrieved from the database. And everything works until we just go to a detailed view - when we click on the picture of Greek salad we get a blank view, but what is interesting when we click on the chicken salad we get just a view of Greek salad? So where does the view of the chicken salad? And why the views turned into places. I attach the code at the bottom with the pictures so that you can understand exactly what the problem is.
DatabaseHelper
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "app";
private static final int DB_VERSION = 1;
public MiodzioDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE SALAD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "NAME TEXT, "
+ "IMAGE_RESOURCE_ID INTEGER, "
+ "FAVORITE INTEGER);");
insertSalatki(db, "Greek salad", R.drawable.salad_greek, 0);
insertSalatki(db, "Chicken salad", R.drawable.salad_chicken, 0);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private static void insertSalatki(SQLiteDatabase db, String name, int resourceId, int favorite){
ContentValues saladValues = new ContentValues();
salatkiValues.put("NAME", name);
salatkiValues.put("IMAGE_RESOURCE_ID", resourceId);
salatkiValues.put("Favorite", favorite);
db.insert("SALAD", null, salatkiValues);
}
}
Salad
public class Salad {
private String name;
private int imageResourceId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageResourceId() {
return imageResourceId;
}
public void setImageResourceId(int imageResourceId) {
this.imageResourceId = imageResourceId;
}
}
SaladDetailActivity
public class SaladDetailActivity extends AppCompatActivity {
public static final String EXTRA_SALAD = "salad";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_salatki_detail);
int salads = (Integer) getIntent().getExtras().get(EXTRA_SALAD);
try {
SQLiteOpenHelper miodzioDatabaseHelper = new MiodzioDatabaseHelper(this);
SQLiteDatabase db = miodzioDatabaseHelper.getWritableDatabase();
Cursor cursor = db.query("SALATKI",
new String[]{"NAME", "IMAGE_RESOURCE_ID", "FAVORITE"},
"_id = ?",
new String[]{Integer.toString(salads)},
null, null, null);
if(cursor != null) {
if (cursor.moveToFirst()) {
do {
String nameText = cursor.getString(0);
int photoId = cursor.getInt(1);
boolean isFavorite = (cursor.getInt(2) == 1);
TextView name = (TextView) findViewById(R.id.salad_text);
name.setText(nameText);
ImageView photo = (ImageView) findViewById(R.id.salad_image);
photo.setImageResource(photoId);
photo.setContentDescription(nameText);
CheckBox favorite = (CheckBox) findViewById(R.id.favorite);
favorite.setChecked(isFavorite);
}while (cursor.moveToNext());
}
}
cursor.close();
db.close();
}catch (SQLiteException e){
Toast.makeText(this, "Database does not work!", Toast.LENGTH_SHORT).show();
}
Toolbar myChildToolbar = (Toolbar) findViewById(R.id.my_child_toolbar_salad_detail);
setSupportActionBar(myChildToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create_order:
Intent intent = new Intent(this, AddActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onFavoriteClicked(View view) {
int salads = (Integer) getIntent().getExtras().get(EXTRA_SALAD);
CheckBox favorite = (CheckBox) findViewById(R.id.favorite);
ContentValues saladValues = new ContentValues();
saladValues.put("FAVORITE", favorite.isChecked());
SQLiteOpenHelper databaseHelper = new DatabaseHelper(this);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.update("SALAD", saladValues,
"_id = ?", new String[]{Integer.toString(salads)});
db.close();
}
}
SaladMaterialFragment
public class SaladMaterialFragment extends Fragment {
private DatabaseHelper dataBaseHelper;
private Cursor cursor;
private ArrayList<Salad> arrayList = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView saladRecyler = (RecyclerView) inflater.inflate(R.layout.fragment_salad_material, container, false);
try{
SQLiteOpenHelper databaseHelper = new databaseHelper(inflater.getContext());
SQLiteDatabase db = databaseHelper.getReadableDatabase();
cursor = db.query("SALAD",
new String[] {"NAME", "IMAGE_RESOURCE_ID"},
null, null, null, null, null);
if(cursor != null){
if(cursor.moveToFirst()){
do{
Salad salads = new Salad();
salad.setName(cursor.getString(0));
salad.setImageResourceId(cursor.getInt(1));
arrayList.add(salad);
}while (cursor.moveToNext());
}
}
}catch (SQLiteException e){
Toast.makeText(inflater.getContext(), "Database does not work!", Toast.LENGTH_SHORT).show();
}
CaptionedImagesAdapter adapter = new CaptionedImagesAdapter(getActivity(), arrayList);
saladRecyler.setAdapter(adapter);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
saladRecyler.setLayoutManager(gridLayoutManager);
adapter.setListener(new CaptionedImagesAdapter.Listener() {
#Override
public void onClick(int position) {
Intent intent = new Intent(getActivity(), SaladDetailActivity.class);
intent.putExtra(SaladDetailActivity.EXTRA_SALAD, position);
getActivity().startActivity(intent);
}
});
return salatkaRecyler;
}
}
SaladDetailLayout
<LinearLayout
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"
android:orientation="vertical"
tools:context="com.hfad.SaladDetailActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/my_child_toolbar_salad_detail"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#android:color/holo_green_light"
android:elevation="4dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
<TextView
android:id="#+id/salatki_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<ImageView
android:id="#+id/salad_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
<CheckBox
android:id="#+id/favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/favorite"
android:onClick="onFavoriteClicked"/>
So when I click on Salad greek, I get an empty view only with the option of whether it is a favorite. And when I hit the chicken salad I get a view of the Greek Salad. I have no idea what's going on?
Problem is in the onClick method in SaladMaterialFragment class.
You are passing the position of the item, and in ArrayList indexing is starting with 0.
But in Database insertion, _id INTEGER PRIMARY KEY AUTOINCREMENT, Database indexing will start with 1.
So you need to change onClick method with below.
adapter.setListener(new CaptionedImagesAdapter.Listener() {
#Override
public void onClick(int position) {
Intent intent = new Intent(getActivity(), SaladDetailActivity.class);
intent.putExtra(SaladDetailActivity.EXTRA_SALAD, position+1);
getActivity().startActivity(intent);
}
});
Just change position with position+1.
Also you are inserting the int value of your drawable resource which is not a good idea. This value is not necessarily constant throughout the life of your app -- a later version may issue a new value to this resource.
So please do not do this.
insertSalatki(db, "Greek salad", R.drawable.salad_greek, 0);
Instead map the drawable to an independent yet constant reference. Some thing like:
insertSalatki(db, "Greek salad", idSaladGreek, 0);
So, since you have potentially many rows in your database with the same salad type (eg. Greek Salad) with potentially many different resource ids, when you query your database for a salad type yon might be getting the wrong resource id. This might be causing the problem of you not being able to display your image.
Test this by comparing the int value coming from the database (int photoId = cursor.getInt(1)) and the int value of R.drawable.salad_greek.
In your SaladDetailActivity you should also check to see if you are getting a valid value for:
int salads = (Integer) getIntent().getExtras().get(EXTRA_SALAD);
I want list view automatically update after deletion. I use adapter.notifyDataSetChanged() but it doesn't work for me
Here is my code
DatabaseHelper
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
private static final String TABLE_NAME = "people_table";
private static final String COL1 = "ID";
private static final String COL2 = "name";
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL2 +" TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, item);
Log.d(TAG, "addData: Adding " + item + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
//if date as inserted incorrectly it will return -1
if (result == -1) {
return false;
} else {
return true;
}
}
/**
* Returns all the data from database
* #return
*/
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
public Cursor getItemID(String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL1 + " FROM " + TABLE_NAME +
" WHERE " + COL2 + " = '" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Delete from database
*/
public void deleteName(int id, String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE "
+ COL1 + " = '" + id + "'" +
" AND " + COL2 + " = '" + name + "'";
Log.d(TAG, "deleteName: query: " + query);
Log.d(TAG, "deleteName: Deleting " + name + " from database.");
db.execSQL(query);
}
}
EditData
public class EditDataActivity extends AppCompatActivity {
private static final String TAG = "EditDataActivity";
private Button btnDelete;
DatabaseHelper mDatabaseHelper;
private String selectedName;
private int selectedID;
#Override
public void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_data_layout);
ActionBar actionBar=getSupportActionBar();
actionBar.hide();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
getWindow().setLayout((int)(width*.4),(int)(height*.2));
btnDelete = (Button) findViewById(R.id.btnDelete);
mDatabaseHelper = new DatabaseHelper(this);
//get the intent extra from the ListDataActivity
Intent receivedIntent = getIntent();
//now get the itemID we passed as an extra
selectedID = receivedIntent.getIntExtra("id",-1); //NOTE: -1 is just the default value
//now get the name we passed as an extra
selectedName = receivedIntent.getStringExtra("name");
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDatabaseHelper.deleteName(selectedID,selectedName);
toastMessage("removed from database");
adapter.notifyDataSetChanged();
}
});
}
/**
* customizable toast
*/
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
}
ListData
public class ListDataActivity extends AppCompatActivity {
private static final String TAG = "ListDataActivity";
static ArrayAdapter adapter;
DatabaseHelper mDatabaseHelper;
private ListView mListView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_layout);
mListView = (ListView) findViewById(R.id.listView);
mDatabaseHelper = new DatabaseHelper(this);
populateListView();
}
public void populateListView() {
Log.d(TAG, "populateListView: Displaying data in the ListView.");
//get the data and append to a list
Cursor data = mDatabaseHelper.getData();
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
listData.add(data.getString(1));
}
//create the list adapter and set the adapter
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
//set an onItemClickListener to the ListView
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String name = adapterView.getItemAtPosition(i).toString();
Log.d(TAG, "onItemClick: You Clicked on " + name);
Cursor data = mDatabaseHelper.getItemID(name); //get the id associated with that name
int itemID = -1;
while(data.moveToNext()){
itemID = data.getInt(0);
}
if(itemID > -1){
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(ListDataActivity.this, EditDataActivity.class);
editScreenIntent.putExtra("id",itemID);
editScreenIntent.putExtra("name",name);
startActivity(editScreenIntent);
}
else{
toastMessage("No ID associated with that name");
}
}
});
}
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDatabaseHelper;
private Button btnAdd, btnViewData;
EditText editField;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnViewData = (Button) findViewById(R.id.btnView);
mDatabaseHelper = new DatabaseHelper(this);
editField = (EditText) findViewById(R.id.editText);
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (editField.getText().toString().length() == 0) {
Toast.makeText(MainActivity.this, "Please Enter!", Toast.LENGTH_SHORT).show();
return;
}
String editText = editField.getText().toString();
AddData(editText);
}
});
btnViewData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ListDataActivity.class);
startActivity(intent);
}
});
}
public void AddData(String newEntry) {
boolean insertData = mDatabaseHelper.addData(newEntry);
if (insertData) {
toastMessage("Data Successfully Inserted!");
} else {
toastMessage("Something went wrong");
}
}
private void toastMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
And Layout are
activity_main
<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:orientation="vertical"
tools:context="com.tabian.saveanddisplaysql.MainActivity">
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="Enter any Thing"
android:layout_marginBottom="47dp"
android:layout_above="#+id/linearLayout"
android:layout_alignParentStart="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="197dp"
android:orientation="horizontal"
android:id="#+id/linearLayout">
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:text="Add" />
<Button
android:id="#+id/btnView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/btnAdd"
android:text="View Data" />
</LinearLayout>
</RelativeLayout>
edit_data_layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="vertical">
<Button
android:id="#+id/btnDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="DELETE" />
</RelativeLayout>
list_layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"/>
</LinearLayout>
After deletion instead of adapter.notifyDataSetChanged(); you can use the following code. It works fine for me:
adapter.remove(selectedName);
I made an android SQLDatabase with two edittext. One save the name and the other some number. This is my activity
public class AccountActivity extends ActionBarActivity {
int from_Where_I_Am_Coming = 0;
private DBHelper mydb ;
TextView name ;
TextView amount;
int id_To_Update = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
name = (TextView) findViewById(R.id.input_name);
amount = (TextView) findViewById(R.id.input_amount);
mydb = new DBHelper(this);
Bundle extras = getIntent().getExtras();
if(extras !=null) {
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 nam = rs.getString(rs.getColumnIndex(DBHelper.ACCOUNT_COLUMN_NAME));
String amo = rs.getString(rs.getColumnIndex(DBHelper.ACCOUNT_COLUMN_AMOUNT));
if (!rs.isClosed()) {
rs.close();
}
Button b = (Button) findViewById(R.id.btn_save);
b.setVisibility(View.INVISIBLE);
name.setText((CharSequence) nam);
name.setFocusable(false);
name.setClickable(false);
amount.setText((CharSequence) amo);
amount.setFocusable(false);
amount.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_account, 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.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
switch(item.getItemId())
{
case R.id.Edit_Contact:
Button b = (Button)findViewById(R.id.btn_save);
b.setVisibility(View.VISIBLE);
name.setEnabled(true);
name.setFocusableInTouchMode(true);
name.setClickable(true);
amount.setEnabled(true);
amount.setFocusableInTouchMode(true);
amount.setClickable(true);
return true;
case R.id.Delete_Contact:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.deleteAccount)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mydb.deleteAccount(id_To_Update);
Toast.makeText(getApplicationContext(), "Deleted Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(),com.tubapps.accountdb.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 run(View view)
{
Bundle extras = getIntent().getExtras();
if(extras !=null)
{
int Value = extras.getInt("id");
if(Value>0){
if(mydb.updateAccount(id_To_Update, name.getText().toString(), amount.getText().length())){
Intent intent = new Intent(getApplicationContext(),com.tubapps.accountdb.MainActivity.class);
startActivity(intent);
}
else{
Toast.makeText(getApplicationContext(), "not Updated", Toast.LENGTH_SHORT).show();
}
}
else{
if(mydb.insertAccount(name.getText().toString(), amount.getText().length())){
}
else{
}
Intent intent = new Intent(getApplicationContext(),com.tubapps.accountdb.MainActivity.class);
startActivity(intent);
}
}
}
}
And this is my 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="#E0EEEE"
tools:context="com.tubapps.accountdb.AccountActivity">
<EditText
android:id="#+id/input_name"
android:layout_width="fill_parent"
android:inputType="text"
android:layout_height="wrap_content"
android:hint="#string/account_name"
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip" />
<EditText
android:id="#+id/input_amount"
android:layout_width="fill_parent"
android:inputType="numberSigned"
android:layout_height="wrap_content"
android:hint="#string/initial_value"
android:layout_below="#+id/input_name"
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:adjustViewBounds="true"
android:orientation="horizontal"
android:showDividers="middle">
<Button
android:id="#+id/btn_cnc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:clickable="true"
android:focusable="true"
android:text="#string/cancel" />
<Button
android:id="#+id/btn_save"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="run"
android:background="#FFFFFF"
android:text="#string/save_income" />
</LinearLayout>
</RelativeLayout>
And this is my DBHelper.
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "MyDBName.db";
public static final String ACCOUNT_TABLE_NAME = "accounts";
public static final String ACCOUNT_COLUMN_ID = "id";
public static final String ACCOUNT_COLUMN_NAME = "name";
public static final String ACCOUNT_COLUMN_AMOUNT = "amount";
private HashMap hp;
public DBHelper(Context context)
{
super(context, DATABASE_NAME , null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(
"create table accounts " +
"(id integer primary key, name text,amount integer)"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS accounts");
onCreate(db);
}
public boolean insertAccount (String name, Integer amount)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("amount", amount);
db.insert("accounts", null, contentValues);
return true;
}
public Cursor getData(int id){
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from accounts where id="+id+"", null );
return res;
}
public int numberOfRows(){
SQLiteDatabase db = this.getReadableDatabase();
int numRows = (int) DatabaseUtils.queryNumEntries(db, ACCOUNT_TABLE_NAME);
return numRows;
}
public boolean updateAccount (Integer id, String name, Integer amount)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("amount", amount);
db.update("accounts", contentValues, "id = ? ", new String[] { Integer.toString(id) } );
return true;
}
public Integer deleteAccount (Integer id)
{
SQLiteDatabase db = this.getWritableDatabase();
return db.delete("accounts",
"id = ? ",
new String[] { Integer.toString(id) });
}
public ArrayList getAllAccounts()
{
ArrayList array_list = new ArrayList();
//hp = new HashMap();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from accounts", null );
res.moveToFirst();
while(res.isAfterLast() == false){
array_list.add(res.getString(res.getColumnIndex(ACCOUNT_COLUMN_NAME)));
res.moveToNext();
}
return array_list;
}
}
When I insert a number it saves just the number 3. I don't know where is the problem.
You are getting the "length" of the number, not the value on these lines:
amount.getText().length()
I suspect you should be doing something like:
Integer.valueOf(amount.getText())