SQliteDatabase data is duplicated - java

i am beginning in SQLiteDatabase i am trying to insert data where i fetch it from Internet and i am using asynTask to fetch data and insert it
but data is duplicate in recycleview when rotate the mobile and when reload activity or login to activity
below is my code
#Override
protected String doInBackground(String... arg) {
JSONObject json = jsonFromHttp.makeHttpRequest(URLS.CATEGORIES_URL, "Get", params);
try {
JSONArray products = json.getJSONArray("cat1");
for (int i=0;i< products.length();i++) {
JSONObject Arrobj= products.getJSONObject(i);
String cat_id=Arrobj.getString("cat_id");
String cat_name=Arrobj.getString("cat_name");
String cat_photo=Arrobj.getString("cat_photo");
Integer id=Integer.parseInt(cat_id);
// here i insert data
ContentValues values = new ContentValues();
values.put(DataContract.DataEntry.COLUMN_CATEGORY_NAME, cat_name);
values.put(DataContract.DataEntry.CATEGORY_ID, id);
values.put(DataContract.DataEntry.COLUMN_CATEGORY_IMAGE, "mm");}
Uri newUri = getContext().getContentResolver().insert(DataContract.DataEntry.CONTENT_URI, values);
categoriesList.add(new CategoryModel(cat_name,cat_photo,cat_id,"","")); //put object which carry values in list
i don't know how to solve this problem .

i make cat_id is primary key this prevent data to duplicate

Related

How to Check Data is Inserted Successfully in Firebase in Array

I am inserting some data in Firebase database From json Response in an array with below code
JSONArray arr = new JSONArray(result);
String[] stocks = new String[arr.length()];
for(int i=0;i<arr.length();i++){
JSONObject obj = arr.getJSONObject(i);
mDatabase= FirebaseDatabase.getInstance().getReference().child("books");
atabaseReference newBid=mDatabase.push();
newBid.child("usr_id").setValue(obj.getString("user_id"));
newBid.child("usr_fullNme").setValue(obj.getString("first_name")+" "+obj.getString("last_name"));
newBid.child("usr_mobile").setValue(obj.getString("user_mobile"));
newBid.child("usr_avatr").setValue(obj.getString("src"));
}
How can i check if above operation is successful or not
You can use a Hashmap and do the following:
Map<String, Object> userValues = new HashMap<>();
userValues.put("usr_id", obj.getString("user_id"));
userValues.put("usr_fullNme",obj.getString("first_name")+" "+obj.getString("last_name"));
userValues.put("usr_mobile", obj.getString("user_mobile"));
userValues.put("usr_avatr", obj.getString("src"));
Then use setValue():
mDatabase= FirebaseDatabase.getInstance().getReference().child("books");
String newBid = mDatabase.push().getKey();
mDatabase.child(newBid).setValue(userValues, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
System.out.println(databaseError);
}
});
From the docs:
public void setValue (Object value, DatabaseReference.CompletionListener listener)
Set the data at this location to the given value. Passing null to setValue() will delete the data at the specified location. The native types accepted by this method for the value correspond to the JSON types:
Boolean
Long
Double
String
Map
List

Populate spinner from database content (SQLite)

How can I populate a spinner content from database (SQLite)
I have POJO: categories, contain id and name,
I have the table already, with a function to get the ArrayList like this:
public List<SetcardCategory> getAllSetcardCategory()
{
List<SetcardCategory> setcardCategories = new ArrayList<SetcardCategory>();
String selectQuery = "SELECT * FROM " + TABLE_SETCARD_CATEGORIES;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
SetcardCategory setcardCategory = new SetcardCategory();
setcardCategory.setId(c.getInt((c.getColumnIndex("id"))));
setcardCategory.setName(c.getString(c.getColumnIndex("name")));
// adding to tags list
setcardCategories.add(setcardCategory);
} while (c.moveToNext());
}
return setcardCategories;
}
Then on Activity I call it like this:
List<SetcardCategory> setcardCategories = db.getAllSetcardCategory();
ArrayAdapter<SetcardCategory> arrayAdapter = new ArrayAdapter<SetcardCategory>(
this, android.R.layout.simple_spinner_item, setcardCategories);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner sItems = (Spinner) findViewById(R.id.setcardCategory);
sItems.setAdapter(arrayAdapter);
when I run it, it loads string like this: "schema.SetcardCategory#22293c98" and many others values similar to that.
How can I populate the spinner to show the name field as a label, and id field as the value that we fetch to save into DB?
class Pojo{
private String name;
#Override
public String toString() {
return name;
}
}
do it like this in the pojo class, so this will return a value for the object when it uses the to string method in the adapter, to load the data
Solution 1
Overide the toString method in your SetcardCategory class
class SetcardCategory {
...
...
#Override
public String toString() {
return this.name;
}
}
Solution 2
If you just want to show the name, Just pick name only from DB
public List<String> getAllSetcardCategory()
{
List<String> setcardCategories = new ArrayList<String>();
String selectQuery = "SELECT * FROM " + TABLE_SETCARD_CATEGORIES;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
// adding to tags list
setcardCategories.add(c.getString(c.getColumnIndex("name")));
} while (c.moveToNext());
}
return setcardCategories;
}
And create Array Adapter as
List<String> setcardCategories = db.getAllSetcardCategory();
ArrayAdapter<SetcardCategory> arrayAdapter = new ArrayAdapter<SetcardCategory>(
this, android.R.layout.simple_spinner_item, setcardCategories);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

Cannot retrieve spinner values from sqlite database

I have used a database class, datamodel class and main activity in my application. I am not populating spinner values from sqlite database but I am storing selected spinner values in db. I have a text entry too. I declared datamodel object separately.
StudentModel student=new StudentModel();
I have used this is at two diff places.The first one inside Onclick(text)
if(v == findViewById(R.id.add)){
tv.setText("");
student.name = name.getText().toString();
}
The next inside OnItemSelected(Spinner)
student.subject=subject.getItemAtPosition(position).toString();
In the databasehelper class I insert value like
public long addStudentDetail(StudentModel student) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_SUBJECT, student.subject);
values.put(KEY_NAME, student.name);
long insert = db.insert(TABLE_STUDENT, null, values);
return insert;
}
And in the databasehelper class I retrieve them like
if (c.moveToFirst()) {
do {
StudentModel students = new StudentModel();
students.id = c.getInt(c.getColumnIndexOrThrow(KEY_ID));
students.name = c.getString(c.getColumnIndexOrThrow(KEY_NAME));
students.subject = c.getString(c.getColumnIndexOrThrow(KEY_SUBJECT));
studentsArrayList.add(students);
} while (c.moveToNext());
}
I get java.lang.IllegalArgumentException: column 'subject' does not exist while running.

Is it possible to update a Listview on real-time when we use Json?

I'm a Newbie, so, there are a lot of things that I don't know.
I'm building my first application, using PHP and Java, and my
Database is allocated on Phpmyadmin.
To get the data that I want, I have to create a PHP Query, and output
everything using Json. To get the Json Data I use Java.
I have been searching about my question for hours, and unfortunately,
I couldn't find a specific way to what I want, in my situation. I
would like to update my ListView automatically when a new record is
inserted into my Database.
Lets imagine that you are watching a Listview, and when the owner
from the application inserts a new record on the table that shows the
Listview data, automatically the Listview shows a new record.
My problem is that I am using Json to get the Data, and I can't
change that. And I would like to find a solution for that.
So, I would like to know if it is possible or not to do that. I will
post my full code here:
Json Tags - Calling the URL and the Json Tags here:
public class ListUsersActivity extends ListActivity {
private ProgressDialog pDialog;
private ImageView img;
// URL to get contacts JSON
private static String url = "http://192.168.1.67/example/db_config.php";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_IMAGE = "pic_url";
private static final String TAG_USERID = "user_id";
private static final String TAG_BIRTH_DATE = "birth_date";
// contacts JSONArray
JSONArray contacts = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList;
OnCreate - Calling the Asynctask function, and creating a new arraylist for my Contact list
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lobby);
contactList = new ArrayList<HashMap<String, String>>();
ListView lv = getListView();
// Calling async task to get json
new GetContacts().execute();
}
Asynctask - Getting all the Data json
private class GetContacts extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(ListUsersActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
NewSession app = (NewSession) getApplication();
String username = app.getUsername();
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url + "?id=" + username, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String user_id = c.getString(TAG_USERID);
String birth_date = c.getString(TAG_BIRTH_DATE);
String pic_url_get = c.getString(TAG_IMAGE);
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ID, id);
contact.put(TAG_USERID, user_id);
contact.put(TAG_BIRTH_DATE, getAge(birth_date) + " anos");
contact.put(TAG_IMAGE, "http://*****/images/" + user_id + "/" + pic_url_get);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
Calling the adapter
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
costumeadapter adapter = new costumeadapter(
ListUsersActivity.this,
contactList,
R.layout.list_row,
new String[]{ TAG_NAME, TAG_BIRTH_DATE, TAG_USERID},
new int[]{ R.id.name,R.id.email, R.id.id });
setListAdapter(adapter);
}
}
I tried so far
To build a Timer and refresh my GetContacts calling class every
second, but it doesn't work because the user is not able to scroll, and the application crashes
I tried to use notifyDataSetChanged but I didn't work because I dont know exactly how can i implement that.
I hope you guys can help me.
Thanks.
Of course it is possible.
To build a Timer and refresh my GetContacts calling class every
second, but it doesn't work because the user is not able to scroll,
and the application crashes
Because you're doing it on the main thread. Do it in an AsyncTask or a separate thread, that should work.
I tried to use notifyDataSetChanged but I didn't work because I dont
know exactly how can i implement that.
It's simple, you call it in the adapter: adapter.notifydatasetchanged() after you update it (more detail here).
Just use
adapter.notifydatasetchanged()
You have to add it after setListAdapter() like:
setListAdapter(adapter);
adapter.notifydatasetchanged();

Using content values to convert string to integer

I am currently working from a project used in a tutorial that displays contacts in a listview. All the fields in the database are used and saved as strings. A custom adapter class is being used for the edit and delete buttons - the buttons appear on the listview, per item. Clicking on edit leads to a separate activity to in which details for that record are parsed in.
I have added another button that I'd like to update a record when clicked and reload the activity. When you press the button it calls a method from the connector method:
public void updateContact(long id, String name, String phone, String mail,
String fb, byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE, blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID + "=" + id, null);
db.close();
}
I would like phone to convert the string to an integer, increment the value by 1 and then save using contentvalues as a string. Here is what I've tried:
public void updateContact(long id, String name, String phone,
String mail, String fb, byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
int phone1 = 0;
phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
phone1++;
phone = String.valueOf(phone1);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE, blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID + "=" + id, null);
db.close();
}
This gives me a null pointer exception error. I'm not sure where to go from here.
This is the method from the custom adapter which holds the onclick method
setPresent = (ImageButton) v.findViewById(R.id.setPresent);
setPresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sqlCon.updateContact(id, name, phone, email, fb, image);
Intent intent = new Intent(context, MyContactsActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
It's when I click this button the null pointer exception error occurs. These are the lines it flags up:
sqlCon.updateContact(id, name, phone, email, fb, image);
- from the customadapter
and
phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
- from the connector
This part doesn't really make sense in your code:
ContentValues cv = new ContentValues();
int phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
You are trying to get Contacts.PHONE from a ContentValues you just created.
Perhaps you wanted to do something like this instead:
cv.put(Contacts.PHONE, Integer.parseInt(phone) + 1);
If you clean up this part, the NullPointerException will probably disappear naturally.
Also, it's safer to update tables using ? placeholders for parameters instead of puttin them in the query string, like this:
db.update(Contacts.TABLE, cv, Contacts.ID + " = ?", new long[]{id});

Categories