Insert Array in SQLite Database in android - android

I want to save weekdays in database, so i thought to store it by assigning int value to each day. i.e
1 -> Selected, 0 -> Not Selected.
Monday = 0/1
Tuesday = 0/1
.
.
.
.
.
Sunday = 0/1.
But this will make 7 columns in DB. So I was thinking if anyone can help me with this if I should store it in a single array and retrieve the values for further use. I was reading some examples over internet but didn't get it in a easy way.

To insert 7 values in one column you can use comma separator like this
where Total_Score_P1 is an string array
//string array
String[] Total_Score = new String[] { p1e1,p1e2,p1e3,p1e4,p1e5,p1e6 };
// Convderting it into a single string
String result_ScoreP1 = ("" + Arrays.asList(Total_Score_P1)).
replaceAll("(^.|.$)", " ").replace(", ", " , " );
result_ScoreP1 will be
// output of this
result_ScoreP1 = "p1e1,p1e2,p1e3,p1e4,p1e5,p1e6";
insert it as a single string in database and
when retrieve it in again break in parts like
// a string array list
// query fired
public ArrayList<String> rulTable(String id) {
// TODO Auto-generated method stub
ArrayList<String> Ruleob = new ArrayList<String>();
Cursor c_rule;
try
{
c_rule = db.query(NameTable, new String[]{
columns1
},
Rule_COurseID + "=" + id ,
null, null,
null, null, null);
c_rule.moveToFirst();
// if there is data available after the cursor's pointer, add
// it to the ArrayList that will be returned by the method.
if (!c_rule.isAfterLast())
{
do
{
Ruleob.add(c_rule.getString(0));
}
while (c_rule.moveToNext());
}
// let java know that you are through with the cursor.
c_rule.close();
}
catch(Exception e)
{
}
return Ruleob;
}
//list to get elements
ArrayList<String> ListOne = new ArrayList<String>();
ArrayList<String> row ;
try{
// received values
row = db.TheTable(id);
String r1 = row .get(0);
}
catch(Exception e)
{
}
StringTokenizer st2 = new StringTokenizer(r1, "||");
while(st2.hasMoreTokens()) {
String Desc = st2.nextToken();
System.out.println(Desc+ "\t" );
ListOne.add(Desc);
//
}

You can use a binary integer 1= selected 0 =Not Selected (1111111) (0000000)
total seven days so index 0=mon, 1=tues, 2=wed, 3=thurs, 4=friday, 5=sat, 6=sunday..and so on..
here 1111111 means all day selected, 0000000 all day not selected, 0001000 only thursday is selected.

I have also discovered a way i.e. convert your so called values to a JSON Array and then store the complete JSON String to an entity/field in Database.
It helps in serving the values easily and effectivly.

Create another table with a column for each day, boolean value. Make an association to this table by integer id (use a foreign key) This is the relational way of solving the problem.

Related

How can I differentiate values in my JSON Array from other values in my ListView?

I have a JSON Array which consists of some contacts in my phonebook who are also users of my app. For example, the JSON Array might look like :
[{"contact_phonenumber":"11111"},{"contact_phonenumber":"22222"},{"contact_phonenumber":"33333"}]
phoneNumberofContact is a string which, in the do statement in my code below, returns every contact in my phone. How can I check which phoneNumberofContact numbers appear in my JSON Array and then, besides those contacts in the ListView put the words '- app user'. My ListView is working fine, I just want to add this feature in.
So, for example, for the number 11111 I would have in my ListView :
Joe Blogs - app user
11111
Here's my code:
JSONArray jsonArrayContacts = response;
//response is something like [{"contact_phonenumber":"11111"}, etc...]
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_contact);
//selectPhoneContacts is an empty array list that will hold our SelectPhoneContact info
selectPhoneContacts = new ArrayList<SelectPhoneContact>();
listView = (ListView) findViewById(R.id.listviewPhoneContacts);
}
//******for the phone contacts in the listview
// Load data in background
class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
// we want to delete the old selectContacts from the listview when the Activity loads
// because it may need to be updated and we want the user to see the updated listview,
// like if the user adds new names and numbers to their phone contacts.
selectPhoneContacts.clear();
// we have this here to avoid cursor errors
if (cursor != null) {
cursor.moveToFirst();
}
try {
// get a handle on the Content Resolver, so we can query the provider,
cursor = getApplicationContext().getContentResolver()
// the table to query
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
null,
null,
// display in ascending order
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
// get the column number of the Contact_ID column, make it an integer.
// I think having it stored as a number makes for faster operations later on.
// get the column number of the DISPLAY_NAME column
int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
// get the column number of the NUMBER column
int phoneNumberofContactIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
cursor.moveToFirst();
// We make a new Hashset to hold all our contact_ids, including duplicates, if they come up
Set<String> ids = new HashSet<>();
do {
System.out.println("=====>in while");
// get a handle on the display name, which is a string
name = cursor.getString(nameIdx);
// get a handle on the phone number, which is a string
phoneNumberofContact = cursor.getString(phoneNumberofContactIdx);
//----------------------------------------------------------
// get a handle on the phone number of contact, which is a string. Loop through all the phone numbers
// if our Hashset doesn't already contain the phone number string,
// then add it to the hashset
if (!ids.contains(phoneNumberofContact)) {
ids.add(phoneNumberofContact);
SelectPhoneContact selectContact = new SelectPhoneContact();
selectContact.setName(name);
selectContact.setPhone(phoneNumberofContact);
selectPhoneContacts.add(selectContact);
}
} while (cursor.moveToNext());
} catch (Exception e) {
Toast.makeText(NewContact.this, "what the...", Toast.LENGTH_LONG).show();
e.printStackTrace();
// cursor.close();
} finally {
}
if (cursor != null) {
cursor.close();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new SelectPhoneContactAdapter(selectPhoneContacts, NewContact.this);
// we need to notify the listview that changes may have been made on
// the background thread, doInBackground, like adding or deleting contacts,
// and these changes need to be reflected visibly in the listview. It works
// in conjunction with selectContacts.clear()
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
}
In the first, you can parse the jsonArrayContacts to a List:
final List<String> responseContacts = new ArrayList<String>();
try {
JSONArray responseObject = new JSONArray(response);
for (int i = 0; i < responseObject.length(); i++) {
final JSONObject obj = responseObject.getJSONObject(i);
responseContacts.add(obj.getString("contact_phonenumber"));
}
// System.out.println("the matching contacts of this user are :" + responseContacts);
} catch(Exception e) {
e.printStackTrace();
}
after you get your local contacts, then you have two sets of contacts, so it's easy to check which number appears in your json array contacts.
And then you can pass the responseContacts into SelectPhoneContactAdapter during you initialize it, and in getView() method of the adapter, you can know whether you need to put the words '- app user' to your item view or not.

android loop through database with cursor speed

I have read several posts here on speed issues when looping through a cursor and tried the answers given in these posts such as e.g. do not use getcolumnindex in the loop call this once etc.
However with a database having around 2400 records it takes around 3 to 5 minutes to finish.
The loop is running in an async task method so that it does not hang up the device and the database is handled via a database adapter.
The loop code is as follows :
while (!exportrec.isAfterLast()) {
if ( exportrec.moveToNext() ) {
fulldate = exportnumberformatter(exportrec.getInt(daye))
+"/"+exportnumberformatter(exportrec.getInt(monthe))+"/"
+String.valueOf(exportrec.getInt(yeare));
fulltime = exportnumberformatter(exportrec.getInt(houre))+":"
+exportnumberformatter(exportrec.getInt(mine))+":"
+exportnumberformatter(exportrec.getInt(sece));
noiseid = exportrec.getInt(typee);
exportedinfo += exporttypes[id] +","+exportrec.getString(notee)+","+
fulldate+","+fulltime+" \n" ;
}
}
The exportnumberformatter does the following :
public String exportnumberformatter(int i) {
String result = Integer.toString(i);
if (result.length() >1 ) {
return Integer.toString(i);
}
String zeroprefix = "";
zeroprefix = "0"+result;
return zeroprefix ;
}
The cursor is called as follows before the loop to get the data :
exportrec = MD.GetAllLogs(2, "date_sort");
exportrec.moveToFirst();
The MD is the database adapter and the GetAllLogs Method (this has been played with to try and speed things up and so the date_sort that is used is really ignored here):
public Cursor GetAllLogs(Integer i,String sortfield)
{
String sorted = "";
if (i == 1 ) {
sorted = "DESC";
} else if (i == 2) {
sorted = "ASC";
}
return mDB.query(DB_TABLE, new String[] {COL_ID, COL_TYPE,COL_IMAGE, COL_INFO,COL_IMAGE,COL_HOUR,COL_SEC,COL_MIN,COL_DAY,COL_MON,COL_YEAR,COL_SORT_DATE},
null, null, null, null, COL_ID+" "+sorted);
}
When I created the table in the database it had no indexes so I created these via the upgrade method. However they did not error or appear to fail when I did this but what I do not know is A) does the database/table need rebuilding after an index is created and B) how to tell if they have been created ? the two indexes were based on the ID as the first and a field that holds the year month day hour minute second all in on Long Integer.
I am concerned that the loop appears to be taking this long to read through that many records.
Update:
rtsai2000's and the suggestion from CL answer has improved the speed from minutes to seconds
Your exportedInfo String is growing and growing. Save the results in an array and Stringify later (such as with StringBuilder).
You are not closing your cursor after reading the records.
List<String> exportedInfo = new ArrayList<String>();
Cursor exportrec = GetAllLogs();
try {
while (exportrec.moveToNext()) {
String info = String.format("%s, %s, %02d/%02d/%02d, %02d:%02d:%02d",
exporttypes[id],
exportrec.getString(notee),
exportrec.getInt(daye),
exportrec.getInt(monthe),
exportrec.getInt(yeare),
exportrec.getInt(houre),
exportrec.getInt(mine),
exportrec.getInt(sece));
exportedInfo.add(info);
}
} finally {
exportrec.close();
}
return exportedInfo;

Android: basic java + array

This is a basic question - but i am new to Android and Java, so please help.
Am trying to retrive all the rows from a DB (SQLite) and show it on screen.
So far it is working fine for a simple retreive and show.
But now, i want to add logic. If a certain field in the array is equal to a value, then i want to perform some operation and then display that field on the screen.
In more detail
Bank table - has Bank Name, Bank Balance, Bank Currency.
I want to read Bank Currency in a variable, if it is USD, then display Bank Balance as it is. If it is INR, then i want to convert it Bank Balance * 55 and then display the new Balance.
Here is my current code
DB Helper
public ArrayList<ArrayList<Object>> getAllRowsAsArrays()
{
// create an ArrayList that will hold all of the data collected from
// the database.
ArrayList<ArrayList<Object>> dataArrays = new ArrayList<ArrayList<Object>>();
Cursor cursor;
try
{
// ask the database object to create the cursor.
cursor = db.query(
BANKTABLE_NAME,
new String[]{BANKTABLE_ROW_ID, BANKTABLE_BANKNAME, BANKTABLE_BALAMT, BANKTABLE_CURRENCY},
null, null, null, null, null
);
// move the cursor's pointer to position zero.
cursor.moveToFirst();
// if there is data after the current cursor position, add it
// to the ArrayList.
if (!cursor.isAfterLast())
{
do
{
ArrayList<Object> dataList = new ArrayList<Object>();
dataList.add(cursor.getLong(0));
dataList.add(cursor.getString(1));
dataList.add(cursor.getInt(2));
dataList.add(cursor.getString(3));
dataArrays.add(dataList);
}
// move the cursor's pointer up one position.
while (cursor.moveToNext());
}
}
catch (SQLException e)
{
Log.e("DB Error in Retreive all", e.toString());
e.printStackTrace();
}
// return the ArrayList that holds the data collected from
// the database.
return dataArrays;
}
and this is the java class where i am calling this array
private void updateTable()
{
// collect the current row information from the database
ArrayList<ArrayList<Object>> data = db.getAllRowsAsArrays();
// iterate the ArrayList, create new rows each time and add them
// to the table widget.
for (int position=0; position < data.size(); position++)
{
TableRow tableRow= new TableRow(this);
ArrayList<Object> row = data.get(position);
TextView bankNameN = new TextView(this);
bankNameN.setText(row.get(1).toString());
tableRow.addView(bankNameN);
TextView balINRA = new TextView(this);
balINRA.setText(row.get(2).toString());
tableRow.addView(balINRA);
dataTable.addView(tableRow);
}
}
this is the simple code to extact the Bank Name and Amount as it is. I want to add logic for the IF ELSE.
Please guide me with the code. Thanks!
use this code to display amount in balINRA
TextView balINRA = new TextView(this);
if(row.get(3).toString.equals("USD"))
{
balINRA.setText(String.valueOf((Integer.parseInt(row.get(2).toString()))*55));
}
tableRow.addView(balINRA);

Sorting the contents of ArrayAdapter or ArrayList

I am working on android project and am making using of a ListView that retrieves data from the SQLite database.
I am making a dataset using an ArrayList and then adding this ArrayList into an ArrayAdapter.
When the data is being retrieved from the database, I am telling SQLite to do the sorting so everything is in alphabetical order when it is added into the ListView. At certain times, the information will be added dynamically to to the ListView without it requiring to re-fetch everythin from the database again. However, I want to keep everything in alphabetical order.
How would I do this, do I sort the DataSet and then call the notifyDataSet Changes or do I do the sort directly on the ArrayAdapter. I've looked into performing the sort on the ArrayAdapter but this wants an argument that uses a Comparator but not sure what this is and can't find any working examples that may be of any help for what I want to achieve.
Below is the code that populates the array and sets the list adapter
ArrayList<Spanned> passwords = managePasswordList.getPasswordList();
if (passwords != null && passwords.size() > 0)
{
passwordArrayAdapter = new ArrayAdapter<Spanned>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_activated_1, passwords);
setListAdapter(passwordArrayAdapter);
myListView.setTextFilterEnabled(true);
txtNoRecords.setVisibility(View.GONE);
}
else
{
txtNoRecords.setVisibility(View.VISIBLE);
}
I am then adding data to the dataset and refreshing the list view using the following
String company = Encryption.decrypt(passwords.get(i).company);
String username = Encryption.decrypt(passwords.get(i).username);
details = Html.fromHtml(company + "<br />" + "<small><font color=\"#767676\">" + username + "</b></small>");
passwords.add(details);
passwordArrayAdapter.notifyDataSetChanged();
Thanks for any help you can provide.
UPDATE 1
I've tried doing what Nick Bradbury suggested but I am having a problem with the comparator. I have the following code but I don't know where to go from here.
SQLiteDatabase myDb = null;
Cursor cursor = null;
ArrayList<Spanned> passwords = new ArrayList<Spanned>();
try
{
myDb = context.openOrCreateDatabase("PasswordManager", Context.MODE_PRIVATE, null);
cursor = myDb.rawQuery("SELECT * FROM password ASC", null);
while (cursor.moveToNext())
{
final String company = Encryption.decrypt(cursor.getString(2));
final String username = Encryption.decrypt(cursor.getString(4));
Spanned details = Html.fromHtml(company + "<br />" + "<small><font color=\"#767676\">" + username + "</b></small>");
passwords.add(details);
Collections.sort(passwords, new Comparator<Spanned>() {
public int compare(Spanned lhs, Spanned rhs) {
return 0;
}
});
}
}
catch (SQLiteException ex)
{
common.showBasicAlertDialog("Unfortunately something has gone wrong.\n\nWe will fix this as soon as we can", false);
Log.e("Database Error", ex.toString());
return null;
}
In the return statement I have no idea what to do, I've tried return lhs.compareTo but the lhs and rhs variables don't have the compareTo function so I have not got a clue what to do.
Here's a simple example of sorting an ArrayList using Comparator. In this example, the ArrayList is defined as:
public class StatusList extends ArrayList<Status>
A sort routine for this ArrayList could look like this:
public void sort() {
Collections.sort(this, new Comparator<Status>() {
#Override
public int compare(Status item1, Status item2) {
return item2.getDate().compareTo(item1.getDate());
}
});
}
Replace <Status> with whatever object your ArrayList contains, then change the comparison to compare the values of the object you wish to sort by.

ORMLite select some columns using predicates

I have ORMLite database with some fields. I want to select titles from the table where id == id which I get from webservice. I do like that:
try {
Dao<ProcessStatus,Integer> dao = db.getStatusDao();
Log.i("status",dao.queryForAll().toString());
QueryBuilder<ProcessStatus,Integer> query = dao.queryBuilder();
Where where = query.where();
String a = null;
for(Order r:LoginActivity.orders) {
//LoginActivity.orders - array of my objects which I get from webservice
Log.i("database",query.selectRaw("select title from process_status").
where().rawComparison(ProcessStatus.STATUS_ID, "=",
r.getProcess_status().getProccessStatusId()).toString());
}
Log.i("sr",a);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I tried like this but I get only sets of my id, not titles. I tried like this:
Log.i("database", query.selectColumns(ProcessStatus.STATUS_TITLE).where().
eq(ProcessStatus.STATUS_ID, r.getProcess_status().getProccessStatusId())
.toString());
but I have the same result. How should I get data from database?
For selecting an specific field from the table, you could do something like this:
String result = "";
try {
GenericRawResults<String[]> rawResults = yourDAO.queryRaw("select " +
ProcessStatus.STATUS_TITLE +" from YourTable where "+
ProcessStatus.STATUS_ID + " = " +
r.getProcess_status().getProccessStatusId());
List<String[]> results = rawResults.getResults();
// This will select the first result (the first and maybe only row returned)
String[] resultArray = results.get(0);
//This will select the first field in the result which should be the ID
result = resultArray[0];
} catch (Exception e) {
e.printStackTrace();
}
Hope this helps.
It's hard to properly answer this question without seeing all of the classes of the processStatusId field and others. However I think you are doing too much raw method and may not be properly escaping your values and the like.
I would recommend that you use the IN SQL statement instead of what you are doing in the loop. Something like:
List<String> ids = new ArrayList<String>();
for(Order r : LoginActivity.orders) {
ids.add(r.getProcess_status().getProccessStatusId());
}
QueryBuilder<ProcessStatus, Integer> qb = dao.queryBuilder();
Where where = qb.where();
where.in(ProcessStatus.STATUS_ID, ids);
qb.selectColumns(ProcessStatus.STATUS_TITLE);
Now that you have built your query, either you can retrieve your ProcessStatus objects or you can get the titles themselves using dao.queryForRaw(...):
List<ProcessStatus> results = qb.query();
// or use the prepareStatementString method to get raw results
GenericRawResults<String[]> results = dao.queryRaw(qb.prepareStatementString());
// each raw result would have a String[] with 1 element for the title

Categories

Resources