Android Get Data from Database from an intent value - java

Im so new to this android development. What im trying to do is to pass the id from MainActivity to Details. So i need to get the id from the MainActivity in order to display the details of a person in Details class. I can pass the id already and display it, but im having trouble on displaying the details of that specific id which is from the database values. How can i display the contents of that specific id in the Details class using the Database function getDetails(id); ? I need to display it on the textviews of the Details activity class. Please help
DB Function
public Cursor getDetails(String id) {
return database.query(TABLENAME, null, id + "=" + id, null, null,
null, null);
}
MainActivity.java
this.listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3){
TextView txtID = (TextView) view.findViewById(R.id.id);
String id = txtID.getText().toString();
Intent intent = new Intent(MainActivity.this, Details.class);
intent.putExtra("id", id);
startActivity(intent);
}
});
In Details.java, i want to display here the contents of the ID which is on the database. How can i call on to that function and make it display using the ID from the intent being passed?
Details.java
Intent i = getIntent();
String id = i.getStringExtra("id");
txtId = (TextView) findViewById(R.id.id);
txtName= (TextView) findViewById(R.id.name);
txtAbout = (TextView) findViewById(R.id.about);
txtId.setText(id);
txtName.setText(name);
txtAbout .setText(about);

public HashMap<String,String> getDetails(String id) {
HashMap<String, String> hm = new HashMap<>();
SQLiteDatabase db = getWritableDatabase();
Cursor c = db.query(TABLENAME, null, "id=?", new String[]{id}, null, null, null);
if(c.getCount()>0){
c.moveToFirst();
hm.put(KEY, c.getString(c.getColumnIndex(COLUMN_NAME)));
// do this for all columns that you want.
}
c.close();
db.close();
return hm;
}
and in Details.java
String id = getIntent().getExtras.getString("id");
HashMap<String, String> hm = (Your database class Object).getDetails(id);
if(hm.size()>0){
String value1 = hm.get(KEY);
// get all data and show according to you.
}

Related

Error querying sqlite database in android studio

I have a problem in my application, to see if there is someone who can help me.
It turns out that in my application I have made a database with SQLite that has two tables, one for players and one for results.
#Override
public void onCreate(SQLiteDatabase BaseDeDades) {
BaseDeDades.execSQL("create table jugadors(codi int primary key, nom text, cognoms text, data date, club text, categoria text)");
BaseDeDades.execSQL("create table resultats(codipuntuacio int primary key, codijugador int,codiexercici text, puntuacio text, temps long, data date)");
}
To consult the first of the tables (players) that shows a list of all the players entered in the database, I did it as follows.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_llistajug);
Llistajugadors();
}
public void Llistajugadors(){
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,"administracio",null,1);
SQLiteDatabase BaseDeDades = admin.getWritableDatabase();
if(BaseDeDades!=null){
Cursor c= BaseDeDades.rawQuery("select * from jugadors",null);
int quantitat = c.getCount();
int i=0;
String[] array = new String[quantitat];
if (c.moveToFirst()){
do{
String linia = c.getInt(0)+"-"+c.getString(1);
array[i] = linia;
i++;
}while(c.moveToNext());
}
ArrayAdapter<String>adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
final ListView llista = (ListView)findViewById(R.id.llista);
llista.setAdapter(adapter);
llista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = getIntent();
intent.putExtra("dato2", llista.getItemAtPosition(position).toString());
setResult(RESULT_OK,intent);
finish();
}
});
}
}
}
The problem has arisen when trying to consult the data of the other table (results) since I have tried to do it the same way
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_llistajug);
jugador = getIntent().getStringExtra("name");
exercici = getIntent().getStringExtra("exercise");
nom = jugador.split("-")[1];
codi = Integer.parseInt(jugador.split("-")[0]);
Resultats();
}
public void Resultats() {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this, "administracio", null, 1);
SQLiteDatabase BaseDeDades = admin.getWritableDatabase();
if (BaseDeDades != null) {
Cursor c2 = BaseDeDades.rawQuery("select * from resultats",null);
int quantitat2 = c2.getCount();
int i2 = 0;
String[] array2 = new String[quantitat2];
if (c2.moveToFirst()) {
do {
String linia2 = c2.getInt(0) + "-" + c2.getString(1);
array2[i2] = linia2;
i2++;
} while (c2.moveToNext());
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, array2);
final ListView llista2 = (ListView) findViewById(R.id.llista2);
llista2.setAdapter(adapter);
}
}
}
But when executing this activity, in this case the application stops.
Does anyone know why if I have done it the same way? Thank you
This is the error that appears in Logcat when executing the activity:
Logcat error
Thanks, the bug was fixed. But now I have another problem with the query. How can I make the query for a string?
codijugador i codi are integers and it works correctly but adding another parameter codiexercici = exerici which are strings gives me an error, are they not done the same way?
Thanks, the bug was fixed. But now I have another problem with the query. How can I make the query for a string?
Thanks, the bug was fixed. But now I have another problem with the query. How can I make the query for a string?
co-player i codi are integers and it works correctly but adding another parameter codiexercici = exerici which are strings gives me an error, are they not done the same way?
Cursor c = BaseDeDades.rawQuery("select * from resultats where codijugador = "+codi+" and codiexercici="+exercici, null);
String must be enclosed inside single quotes, but this is something that you should not do by concatenating the parameters and the single quotes.
Use ? placeholders for the parameters and the 2nd argument of rawQuery() to pass them:
Cursor c = BaseDeDades.rawQuery(
"select * from resultats where codijugador = ? and codiexercici = ?",
new String[] {String.valueOf(codi), exercici}
);

Updating Firebase records that are displayed in an Android ListView

So far, I have been able to display my Firebase records for node maintenance in an Android ListView. However, there is one part of these records that I wish to update.
When clicking on a record, an AlertDialog dialog will appear with a spinner (spinnerProgress). By changing the option on this spinner and clicking an OK 'button', then the ListView and of course the Firebase database will update.
* EDIT *
So, I have progressed with this problem a bit. When I click my buttonUpdateProgress, the part of the ListView (progress) updates perfectly.
However, along with it, it removes my strings title and description from the ListView. Any ideas so that it only progress changes?
Below is my code:
listViewIssues.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Maintenance maintenance = maintenanceList.get(position);
showProgressDialog(maintenance.getMaintenanceId(), maintenance.getMaintenanceTitle(), maintenance.getMaintenanceDescription(), maintenance.getMaintenanceProperty(), maintenance.getMaintenanceProgress());
}
});
--
private void showProgressDialog(final String id, String title, String description, String property, String maintenanceTitle) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.archive_maintenance, null);
dialogBuilder.setView(dialogView);
final Spinner spinnerProgress = (Spinner) dialogView.findViewById(R.id.spinnerProgress);
final Button buttonUpdateProgress = (Button) dialogView.findViewById(R.id.buttonUpdateProgress);
dialogBuilder.setTitle("Maintenance: " + maintenanceTitle);
final AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
buttonUpdateProgress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String progress = spinnerProgress.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
updateProgress(title, desc, id, property, progress);
alertDialog.dismiss();
}
});
}
--
private boolean updateProgress (String title, String desc, String id, String property, String progress) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("maintenance").child(id);
Maintenance maintenance = new Maintenance(id, title, desc, property, progress);
FirebaseUser user = mAuth.getCurrentUser();
String uid = user.getUid();
databaseMaintenance.child(uid).child(id).setValue(maintenance);
databaseReference.setValue(maintenance);
Toast.makeText(this, "Maintenance Updated Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
Can you please try replacing this function with your function and try
Some explanation:
ref.updateChildren(hashMap); // will let you update the only data you want to change
ref.setValue(model); // will replace the existing data with the model you provided
Function to replace
private boolean updateProgress (String title, String desc, String id, String property, String progress) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance()
.getReference().child("maintenance");
FirebaseUser user = mAuth.getCurrentUser();
String uid = user.getUid();
Map<String, Object> params = new HashMap<>();
params.put("progress", progress); // put only params you want to update
databaseReference.child(uid)
.child(id)
.updateChildren(params);
Toast.makeText(this, "Maintenance Updated Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
Note: put only params you want to update like in example below, here if you want to change progress only then snippet will be like,
Map<String, Object> params = new HashMap<>();
params.put("progress", progress);
ref.updateChildren(params);

Need Help Refreshing my database ListView in my app

My app layout apparently isn't a normal layout so I a having trouble setting my List Adapter to auto updated when an edit is made.
I make my edits to my database in this Java File which is controlled in its own activity and layout.
public void onClick(View view){
if (view == findViewById(R.id.addsave)) {
RecipeRepo repo = new RecipeRepo(this);
Recipe recipe = new Recipe();
if (editTextName.getText().toString().equals("")) {
editTextName.setError("Recipe name required!");
return;
} else {
recipe.name = editTextName.getText().toString();
}
if (textImagePath.getText().toString().equals("") ) {
recipe.image = ("");
}else{
recipe.image = textImagePath.getText().toString();
}
recipe.category = staticSpinner.getSelectedItem().toString();
if (editTextIngredients.getText().toString().equals("")) {
editTextIngredients.setError("Ingredient required!");
return;
} else {
recipe.ingredients = editTextIngredients.getText().toString();
}
if (editTextInstruct.getText().toString().equals("")) {
editTextIngredients.setError("Instruction required!");
return;
} else {
recipe.instructions = editTextInstruct.getText().toString();
}
recipe.cooktemp = editTextCookTemp.getText().toString();
recipe.cooktime = editTextCookTime.getText().toString();
recipe.serves = editTextServings.getText().toString();
recipe.recipe_Id = _Recipe_Id;
if (_Recipe_Id == 0) {
_Recipe_Id = repo.insert(recipe);
Toast.makeText(this, "New Recipe Added", Toast.LENGTH_SHORT).show();
finish();
it actually inserts and updates in this java file
int insert(Recipe recipe){
//Open connection to write data
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
//Inserting Row
long recipe_Id = db.insert(Recipe.TABLE, null, values);
db.close();// Closing database connection
return (int) recipe_Id;
}
void delete(int recipe_Id){
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(Recipe.TABLE, Recipe.KEY_ID + "=?", new String[] {String.valueOf(recipe_Id)});
db.close();
}
void update(Recipe recipe){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Recipe.KEY_SERVES, recipe.serves);
values.put(Recipe.KEY_COOKTIME, recipe.cooktime);
values.put(Recipe.KEY_COOKTEMP, recipe.cooktemp);
values.put(Recipe.KEY_INSTRUCT, recipe.instructions);
values.put(Recipe.KEY_INGREDIENTS, recipe.ingredients);
values.put(Recipe.KEY_CATEGORY, recipe.category);
values.put(Recipe.KEY_IMAGE, recipe.image);
values.put(Recipe.KEY_NAME, recipe.name);
db.update(Recipe.TABLE, values, Recipe.KEY_ID + "=?", new String[]{String.valueOf(recipe.recipe_Id)});
db.close();
}
and lastly it gets put into the list view from this Java file and separate layout. Which is where my adapters are but i cannot get the notifyDataSetChanged() to work here at all... as in it wont even come up.
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
RecipeRepo repo = new RecipeRepo(this);
if (id == R.id.nav_meat) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeMeat();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
} else if (id == R.id.nav_veg) {
final ArrayList<HashMap<String, String>> recipeList = repo.getRecipeVeg();
if(recipeList.size()!=0) {
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
recipe_Id = (TextView) view.findViewById(R.id.recipe_Id);
String recipeId = recipe_Id.getText().toString();
Intent objIndent = new Intent(getApplicationContext(), RecipeDetail.class);
objIndent.putExtra("recipe_Id", Integer.parseInt(recipeId));
startActivity(objIndent);
}
});
ListAdapter adapter = new SimpleAdapter(SousChef.this, recipeList, R.layout.view_recipe_entry, new String[]{"id", "category", "name"}, new int[]{R.id.recipe_Id, R.id.recipe_list_category, R.id.recipe_list_name});
lv.setAdapter(adapter);
}else {
Toast.makeText(this, "No recipe!", Toast.LENGTH_SHORT).show();
}
So any advise on setting this up to automatically update would be a huge help. I have been racking my brain over this for a couple days now looking at different examples and what not, but no setup is quite like this one which doesnt allow me to have everything in one file.
And thank you in advance.
category picking image:
Category picking Image
There are for sure more answers but this is one that might help,
Quick Example for the proposed solution
SHORT EXPLANATION
inside MainActivity
//create a public static adapter
public static ListAdapter adapter
inside onCreateView()
//Create your adapter and set it to the right ListView
ListView lv = findViewById(R.id.listView_in_xml);
adapter = new SimpleAdapter(...)
lv.setAdapter(adapter)
inside CustomAdapter which in your case I assume is SimpleAdapter
//add a public method to be called so that the Adapter updates and displays the new data
public void updateMethod(){
//update your List<Recipe> that I would guess you have calling the database again
//if needed update your getCount() return value so that it returns the number of childs in your ListView which most of the cases is just the List<Recipe>.size()
//notifyDataSetChanged()
}
inside your DB HANDLER CLASS
//in every update, add, delete or any method that requires the ListView to Update just call the created method,
MainActivity.CustomAdapter.updateMethod();
PROBLEMS
You will have to make sure the public static adapter has been initialized and is not null, or simply check whether the adapter is not null and update, because if the adapter is null that activity has not launched yet thus no need to trigger the updateMethod().
OTHER SOLUTIONS
Instead of creating a public static adapter create a public static boolean, then whenever data changes set that boolean to true from the database.
Finally, whenever you resume your activity check against that boolean and update your ListViewAdapter if needed.
MORE COMPLICATED SOLUTIONS WHICH I KNOW WORK CAUSE I USE IT
Use TaskAsyncTaskLoader which utilizes a Loader in your MainActivity and implements LoaderManager.LoaderCallbacks.
Optionally, you can make the Loader be, public static Loaderand inside your DBHandler you trigger the loader to load the data again or use any other logic you want.
Proofs of Working suggested solution,
You can Broadcast Intent from the change database file after you get the response in the onCreate() of adapter loading class
Intent intent = new Intent("key_to_identify_the_broadcast");
Bundle bundle = new Bundle();
bundle.putString("edttext", "changed");
intent.putExtra("bundle_key_for_intent", bundle);
context.sendBroadcast(intent);
and then you can receive the bundle in your fragment by using the BroadcastReceiver class
private final BroadcastReceiver mHandleMessageReceiver = new
BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle =
intent.getExtras().getBundle("bundle_key_for_intent");
if(bundle!=null){
String edttext = bundle.getString("edttext");
}
//you can call any of your methods for using this bundle for your use case
}
};
in onCreate() of your adapter adding class you need to register the broadcast receiver first otherwise this broadcast receiver will not be triggered
IntentFilter filter = new IntentFilter("key_to_identify_the_broadcast");
getActivity().getApplicationContext().
registerReceiver(mHandleMessageReceiver, filter);
Finally you can unregister the receiver to avoid any exceptions
#Override
public void onDestroy() {
try {
getActivity().getApplicationContext().
unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
Log.e("UnRegister Error", "> " + e.getMessage());
}
super.onDestroy();
}

How to access items from ListView connected to SQL Server

I have a listview with textviews that bring information from a table in sql server as id, description and quantity. I need that when the user clicks on an item in the listview, open another activity with that information that the user selected, the user can edit and save in the database.
I have the following code that queries the database and fills the listview, but I can't find the way to pass the information to another activity. Any help?
public void getProd() {
comandSQL = "Select * from Inventory where [Code] = '"+loccode+"' order by [Bin Code]";
try {
Statement statement = MainActivity.connect.createStatement();
rs = statement.executeQuery(comandSQL);
List<Map<String, String>> data = null;
data = new ArrayList<Map<String,String>>();
while(rs.next()){
Map<String, String> datanum = new HashMap<String, String>();
datanum.put("idProd", rs.getString("No_"));
datanum.put("desc", rs.getString("Description"));
datanum.put("ubic", rs.getString("Bin Code"));
datanum.put("cant", rs.getString("Inventory"));
data.add(datanum);
}
String[] from = {"idProd","desc","ubic","cant"};
int[] views = {R.id.id_prod,R.id.descripcion, R.id.ubicacion,R.id.cant};
AD = new SimpleAdapter(this, data, R.layout.list, from, views);
Lista.setAdapter(AD);
} catch (Exception e) {
Log.e("ERROR",e.getMessage());
}
}
You want to set up a click listener for each listview item:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Do something when a list item is clicked
}
When the item is clicked, you need to gather the data from that view and then simply start a new activity passing that data via an Intent
Intent intent = new Intent(mContext, YourNewActivity.class);
intent.putExtra("MyData", userData.toString());
startActivity(intent);

Get value from a LinkedList into a LinkedList

I have a linkedlist name categories.
Into this linkedlist i had values like : id, name, description, entries(linkedlist)
in the method i get a the id with a bundle. now my problem is, how can i connect/enter/get the data from entries by using the id?
(the id, name, description and entries data will be loaded from the database)
Loading from Database and add it to the LinkedList:
CRUDDatabase dbHandler = new CRUDDatabase(this);
SQLiteDatabase db1 = dbHandler.getWritableDatabase();
dbHandler.open();
String[] categoryColumns = {dbHandler.ID, dbHandler.NAME, dbHandler.DESCRIPTION};
String[] entryColumns = {dbHandler.ID, dbHandler.CATEG_ID, dbHandler.NAME, dbHandler.DESCRIPTION};
Cursor cursorLoadCategory = db1.query(dbHandler.tableCategory, categoryColumns, null, null, null, null, null);
cursorLoadCategory.moveToFirst();
while(!cursorLoadCategory.isAfterLast()){
String whereClause = dbHandler.CATEG_ID + "= ?";
String whereArgs = String.valueOf(cursorLoadCategory.getInt(0));
Cursor cr2 = db1.query(dbHandler.tableEntry, entryColumns,whereClause,new String[]{whereArgs},null,null,null);
cr2.moveToFirst();
Log.v("Get Entry Data by ID: ", "" + whereClause+" ::: " + whereArgs);
LinkedList<Entry> entries = new LinkedList<Entry>();
while(!cr2.isAfterLast()){
entries.add(new Entry(cr2.getInt(0), cr2.getInt(1), cr2.getString(2), cr2.getString(3)));
cr2.moveToNext();
}
System.out.println("--- CREATE CATEGORY ---");
Category category = new Category(cursorLoadCategory.getInt(0), cursorLoadCategory.getString(1), cursorLoadCategory.getString(2), null, null, null, entries);
MainActivity.categories.add(category);
From the MainActivity:
#Override
public void onClick(View v) {
ViewGroup elements = (ViewGroup)v.getParent();
LinearLayout lL = (LinearLayout)elements.findViewById(R.id.CatTemp_menuBoxContainer);
int categoryId = (Integer)lL.getTag();
Intent intentSelectedCategory = new Intent(MainActivity.this, ItemScreen.class);
intentSelectedCategory.putExtra("catId", (int)categoryId);
startActivity(intentSelectedCategory);
finish();
}
From the ItemScreen.java:
public void onCreate(Bundle savedInstanceState ){
super.onCreate(savedInstanceState);
setContentView(R.layout.item_screen);
Intent i = getIntent();
Bundle extra = getIntent().getExtras();
int categoryId = extra.getInt("catId");
Log.v("THIS IS THE ID OF THIS CATEGORY:", ""+categoryId);
TextView headTBox = (TextView)findViewById(R.id.HeadTextBox);
headTBox.setText(MainActivity.categories.get(categoryId-1).getName());
...
Now here is my problem... how can i get the entries values?
It looks like you have to start at the beginning of the linked list and go through each node comparing the bundle ID to the categories node ID.
Good luck!

Categories