i am using code this blog to have a draggable list. This tutorial is using a custom DragNDropAdapter
that takes the content as an ArrayList.
In my listActivity i query a table with returned column name.It has 11 values inserted.
i tried to convert it to ArrayList from String[] with many ways such as :
String[] from = new String[]{DbManager.KEY_NAME};
ArrayList<String> content = new ArrayList<String>();
for (int i=-1,l=from.length; ++i<l;) {
content.add(from[i]);
//Log.i("ArrayList", from[i]);
}
or
while(!mShopCatCursor.isAfterLast()){
content.add(mShopCatCursor.getString(0));
}
what i get is a list with just the name of the column, name.
do you have any ideas
You can use following method this method will get data from db and then return you an ArrayList of String for this data. In your case this array list will contain names.
private ArrayList<String> getArrayList() {
ArrayList<String> namesList = null;
Cursor cursor = null;
try {
String query = "";//your query here
cursor = db.rawQuery(query,null);
if (cursor != null && cursor.moveToFirst()) {
namesList = new ArrayList<String>();
do {
namesList.add(cursor.getString(0));
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
namesList = null;
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.deactivate();
cursor.close();
cursor = null;
}
close();
}
return namesList;
}
/**
* Closes the database
*/
private void close() {
try {
if (db != null && db.isOpen()) {
DBHelper.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
String[] from = new String[]{DbManager.KEY_NAME};
Because your string array has only one value which is KEY_NAME.
What you need to do is,
Get values from Cursor using loop and populate it String[] above.
Cursor userCur = adaptor.getYourData();
if (userCur != null) {
String[] strArr = new String[userCur.getCount()];
startManagingCursor(userCur);
if (userCur.moveToFirst()) {
int count = 0;
do {
String userName = userCur.getString(1);
strArr[count] = userName.trim();
count++;
} while (userCur.moveToNext());
}
ArrayList<String> content = new ArrayList<String>();
for (int i=-1,l=from.length; ++i<l;) {
content.add(from[i]);
//Log.i("ArrayList", from[i]);
}
}
Note: I haven't validated this in IDE, there may be syntax errors.
Related
I'm trying to retrieve data using an ArrayList, but I'm doing something wrong. There is no error, but I'm always getting a size of 0
Here is the method I'm using to retrieve the data from the database:
public List<Topic> getTopics() {
List<Topic> topics = new ArrayList<>();
SQLiteDatabase database = this.getReadableDatabase();
Cursor cursor = database.query(TABLE_NAME,
new String[] { KEY_ID,
KEY_TOPIC_USER_ID,
KEY_TOPIC_USER_NAME,
KEY_TOPIC_IMAGE,
KEY_TOPIC_LIKES,
KEY_DATE}, null, null, null,
null, null);
while (cursor.moveToNext()) {
Topic topic = new Topic();
topic.setId(cursor.getInt(0));
topic.setUserId(cursor.getString(1));
topic.setName(cursor.getString(2));
topic.setPostImage(cursor.getString(3));
topic.setNumOfLikes(cursor.getInt(4));
topic.setCreatedTime(loadDate(cursor, 5));
}
cursor.close();
database.close();
return topics;
}
These are utility methods for storing my dates as long:
public static Long persistDate(Date date) {
if (date != null) {
return date.getTime();
}
return null;
}
public static Date loadDate(Cursor cursor, int index) {
if (cursor.isNull(index)) {
return null;
}
return new Date(cursor.getLong(index));
}
I am working in Android application in which I am using ormlite. I am taking my phone book contacts and saving them in my local database, but the problem is that it is taking too much time like for almost 1500 contact it is taking almost 70 seconds.
I searched for the Bulk insert in ormlite, but I can't figure it out how to implement it in my following code.
public static void loadLocalPhoneBookSample(Context ctx) {
try{
ContentResolver contentRes = ctx.getContentResolver();
Cursor cur = null;
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
cur = contentRes.query(ContactsContract.Contacts.CONTENT_URI, PROJECTIONS, selection, null, Phone.DISPLAY_NAME + " ASC");
context = ctx;
if (cur.getCount() > 0) {
// create DB object
MUrgencyDBHelper db = new MUrgencyDBHelper(ctx);
RuntimeExceptionDao<ContactLocal, ?> contactDAO = db.getContactLocalIntDataDao();
UpdateBuilder<ContactLocal, ?> updateDAO = contactDAO.updateBuilder();
try {
updateDAO.updateColumnValue("isUseless", true);
updateDAO.update();
} catch (SQLException e) {
e.printStackTrace();
}finally {
// db.writeUnlock();
}
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
/** read names **/
String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
/** Phone Numbers **/
Cursor pCur = contentRes.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
String number = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String formatedNo = number.replaceAll("\\s+", "").replace("+", "00").replace("-", "").trim();
try {
QueryBuilder<ContactLocal, ?> query = contactDAO.queryBuilder();
query.where().eq("mFormatedNumber", number);
ContactLocal contact = query.queryForFirst();
boolean addContact = false, alreadyUpdated = true;
if (contact == null) {
addContact = true;
contact = new ContactLocal();
contact.setFirstName(displayName.trim());
contact.setLastName(displayName.trim());
contact.setContactNumber(formatedNo);
}
// check if this contact was already updated before
if (contact.getContactNumber() == null || contact.getContactNumber().length() == 0) {
contact.setContFirstLastNo(number, displayName, displayName, number);
alreadyUpdated = false;
}
contact.setUseless(false);
// if not updated already, Create/Update
if (addContact) {
contactDAO.create(contact);
} else
contactDAO.update(contact);
}
}
pCur.close();
}
}
}
the problem is that it is taking too much time like for almost 1500 contact it is taking almost 70 seconds
#CarloB has the right answer in terms of doing the mass creates inside the dao. callBatchTasks(...) method. Here's the docs on that subject:
http://ormlite.com/docs/batch
To make things a bit faster, you could also go through and record all of the mFormatedNumber in another List and then query for them using an IN query. Use a raw in query to get back the mFormatedNumber that are already in the database:
results = dao.queryRaw(
"SELECT mFormatedNumber from Contact WHERE mFormatedNumber IN ?",
mFormatedNumberList);
For using raw queries with ORMLite, see:
http://ormlite.com/docs/raw-queries
So then you would make one query to see which of the contacts need to be created and then do all of the inserts from within a batch transaction.
Otherwise you are doing ~3000 synchronous database transactions and 40/sec on an Android device is unfortunately pretty typical.
Here is my revised version (might need a few syntax changes)
public static void loadLocalPhoneBookSample(Context ctx) {
try {
ContentResolver contentRes = ctx.getContentResolver();
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Cursor cur = contentRes.query(ContactsContract.Contacts.CONTENT_URI, PROJECTIONS, selection, null, Phone.DISPLAY_NAME + " ASC");
context = ctx;
if (cur.getCount() > 0) {
// create DB object
MUrgencyDBHelper db = new MUrgencyDBHelper(ctx);
RuntimeExceptionDao<ContactLocal, ?> contactDAO = db.getContactLocalIntDataDao();
UpdateBuilder<ContactLocal, ?> updateDAO = contactDAO.updateBuilder();
try {
updateDAO.updateColumnValue("isUseless", true);
updateDAO.update();
} catch (SQLException e) {
e.printStackTrace();
}finally {
// db.writeUnlock();
}
ArrayList<ContactLocal> contacts = new ArrayList<>();
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
/** read names **/
String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
/** Phone Numbers **/
Cursor pCur = contentRes.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
String number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String formatedNo = number.replaceAll("\\s+", "").replace("+", "00").replace("-", "").trim();
try {
QueryBuilder<ContactLocal, ?> query = contactDAO.queryBuilder();
query.where().eq("mFormatedNumber", number);
ContactLocal contact = query.queryForFirst();
if (contact == null) {
contact = new ContactLocal();
contact.setFirstName(displayName.trim());
contact.setLastName(displayName.trim());
contact.setContactNumber(formatedNo);
}
contact.setUseless(false);
contacts.add(contact);
}
}
pCur.close();
}
contactDao.callBatchTasks(new Callable<Void>() {
public Void call() throws Exception {
for (ContactLocal contact : contacts) {
contactDAO.createOrUpdate(contact);
}
}
});
}
}
The main optimization is to use callBatchTasks. From the ormlite documentation:
Databases by default commit changes after every SQL operation. This method disables this "auto-commit" behavior so a number of changes can be made faster and then committed all at once.
By creating an ArrayList and keeping track of the changes, you can use callBatchTasks to create/update at the end all in one shot.
Also I noticed that alreadyUpdated was never accessed, so it's safe to remove.
Also Dao has a createOrUpdate method which is the same as the addContact if statement you had before.
I have searched found a few answers but I am not quite sure I understand them. I want a multidimensional array or the equivalent of say string[0][1][1].
Here is what I have:
public List<List<List<String>>> loadCompleteExercises(String workout)
{
List<List<List<String>>> listExercises = new ArrayList<List<List<String>>>();
List<String> complete_time = new ArrayList<String>();
List<String> rest_time = new ArrayList<String>();
db = dbHelper.getReadableDatabase();
Cursor c = db.rawQuery("SELECT complete_time, rest_time FROM tbl_exercises WHERE workout = '"+workout+"';", null);
c.moveToFirst();
while(!c.isAfterLast()) {
try {
if(c.isNull(c.getColumnIndex("exercise"))) {
complete_time.add("00:00:05");
rest_time.add("00:00:00");
}else {
complete_time.add(c.getString(c.getColumnIndex("complete_time")));
rest_time.add(c.getString(c.getColumnIndex("rest_time")));
}
}catch (NullPointerException e)
{
Log.d("GET EXERCISES ERROR: ", e.toString());
}
c.moveToNext();
}
//listExercises.add();
return listExercises;
}
--- I want to add complete_time and rest_time to listExercises so that I can say do the following
listExercises.get(i).get(j) to yield the below
1 "00:00:05" "00:00:00"
2 "00:10:00" "00:10:00"
...
n "xx:xx:xx" "xx:xx:xx"
Try this, use a holder for both time, add them in a List
private class TimeHolder
{
public String completeTime;
public String restTime;
}
public List<TimeHolder> loadCompleteExercises(String workout)
{
List<TimeHolder> listExercises = new ArrayList<TimeHolder>();
db = dbHelper.getReadableDatabase();
Cursor c = db.rawQuery("SELECT complete_time, rest_time FROM tbl_exercises WHERE workout = '"+workout+"';", null);
c.moveToFirst();
while(!c.isAfterLast()) {
try
{
TimeHolder holder = new TimeHolder();
if(c.isNull(c.getColumnIndex("exercise"))) {
holder.completeTime = "00:00:05";
holder.restTime = "00:00:00";
}else {
holder.completeTime = c.getString(c.getColumnIndex("complete_time"));
holder.restTime = c.getString(c.getColumnIndex("rest_time"));
}
listExercises.add(holder);
}
catch (NullPointerException e)
{
Log.d("GET EXERCISES ERROR: ", e.toString());
}
c.moveToNext();
}
return listExercises;
}
I am trying to create an array of id strings that have already been used to prevent duplications. If the ID does not exist in the array, I add it to the usedID array so next time an id is scanned, if it already exists in the array it won't accepted = false. But that does not seem to be the case. Help?
ArrayList<String> list = new ArrayList<>();
ArrayList<String> ID = new ArrayList<>();
ArrayList<String> usedID = new ArrayList<>();
boolean accepted;
File file = new File("C:/Embarq/purchasedList.txt");
if (file.exists()) {
try {
list = (ArrayList<String>) Files.readAllLines(file.toPath(), Charset.defaultCharset());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
if (list.isEmpty()) {
return;
}
for (String line : list) {
String[] res = line.split(";");
ID.add(res[2]);
}
if (ID.contains(jTextField1.getText())) {
if (usedID.contains(jTextField1.getText())) {
accepted = false;
} else {
accepted = true;
usedID.add(jTextField1.getText());
}
} else {
accepted = false;
}
if (accepted) {
JOptionPane.showMessageDialog(null, "Accepted");
} else {
JOptionPane.showMessageDialog(null, "Denied");
}
jTextField1.setText("");
} else {
JOptionPane.showMessageDialog(null, "purchasedList.txt does not exist!");
}
}
pardon the ugly code..
Each time this code run, you create a new usedID, so everything that was there on the previous run is lost. You need to keep the usedID between calls.
Note that you should consider using HashSet instead of ArrayList, with ArrayList every check will be O(n), while with HashSet it will be O(1).
So just create an object that does this for you:
public class MyArrayList extends ArrayList<String>{
#Override
public boolean add(String id){
if(!this.contains(id))
return super.add(id);
// else you shouldn't add, so the ArrayList isn't modified, return false
return false;
}
}
Now when you create your userID in your main method, use this class instead of ArrayList:
final ArrayList<String> userID = new MyArrayList();
I do not know how to get the data of two columns. I only know how to do it when it deals with one column only.
here is the code where the issue is:
public ArrayList<String> getData() {
ArrayList<String> List = new ArrayList<String>();
Cursor c = db.rawQuery("SELECT Column1, Column2 FROM Table where id = 1", null);
try {
if (c != null) {
if (c.moveToFirst()) {
do {
String levelData = c.getString(c.getColumnIndex("Column1"));
List.add("" + levelData);
}
while (c.moveToNext());
}
}
} catch (SQLiteException e) {
Log.e("Retrieve Data", "Unable to get Data " + e);
}
return List;
}
I know that the problem is at the c.getColumnIndex("Column1")); because that will be the place where to type the column of the table you want to get data from. But what will I do if I will try to do it using two columns?
the answer is simple. it was the first time i tried this and i didn't expect it to work so
this is what i did:
try {
if (c != null) {
if (c.moveToFirst()) {
do {
String levelData = c.getString(c.getColumnIndex("Column1"));
List.add("" + levelData);
}
while (c.moveToNext());
}
}
if (c != null) {
if (c.moveToFirst()) {
do {
String levelData = c.getString(c.getColumnIndex("Column2"));
List.add("" + levelData);
}
while (c.moveToNext());
}
}
} catch (SQLiteException e) {
Log.e("Retrieve Data", "Unable to get Data " + e);
}
I simply added another exact code but this time, it reads Column2 and worked as expected. :D
Make a java bean class with 2 variable and their getters & Setters like
public class Data {
String coloumn1;
String coloumn2;
public String getColoumn1() {
return coloumn1;
}
public void setColoumn1(String coloumn1) {
this.coloumn1 = coloumn1;
}
public String getColoumn2() {
return coloumn2;
}
public void setColoumn2(String coloumn2) {
this.coloumn2 = coloumn2;
}
}
Use
ArrayList dataList = new ArrayList();
dataList.setsetColoumn1(Your Data);
same for coloumn2 and for getters.