In my app I want to put in an array some items from database. I can see them, as a list using this function :
private void fillData()
{
c = db.fetchListId(listid);
startManagingCursor(c);
adapter = new SimpleCursorAdapter(this, R.layout.listproduct, c,
new String[] { DbAdapter.KEY_ITEM,
DbAdapter.KEY_QUANTITY,
DbAdapter.KEY_UNITS },
new int[] { R.id.prod1,
R.id.prod2,
R.id.prod3 }
);
setListAdapter(adapter);
}
But I don't know how can I put them in an array.
Can anyone help me, please?
I suppose you would like to do something like this:
private String[] getItems(<the selection params>) {
Cursor c = db.retrieveItems(<the selection params>);
String[] items = new String[c.getCount()];
for (int i = 0; c.moveToNext() != null; i++) {
String item = c.getString(c.getColumnIndexOrThrow(DbAdapter.KEY_ITEM));
String quantity = c.getString(c.getColumnIndexOrThrow(DbAdapter.KEY_QUANTITY));
String units = c.getString(c.getColumnIndexOrThrow(DbAdapter.KEY_UNITS));
items[i] = item + " " + quantity + units;
}
c.close();
return items;
}
I have assumed that your DB class has a method called retrieveItems, that takes some selection params, in order to perform the appropriate query.
I have not tested the code, there may be some typo or minor error, but I hope it can direct you to the desired solution.
You're definitely going to begin by iterating through the cursor:
while(c.moveToNext()){
myString = c.getString(c.getColumnIndex("MyColumnName")); // or somesuch
array[x][y][z] = myString; // also somesuch
}
Without knowing more about how you want to store the data, it's impossible to guess what you need beyond c.moveToNext().
UPDATE:
OK, so you just want to accumulate them into a String. Try something like:
String theList="";
while(c.moveToNext()){
theList += c.getString(0) + " " + c.getString(1) + c.getString(2) + "\n";
}
Related
I need to populate the data from the query and populate it on ListView with custom Item.
on OnCreateView, I'm calling my adapter like this:
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
(getContext(), android.R.layout.simple_list_item_1, stops)
This is my whole code of LoadData
public void LoadData() {
String query = "SELECT ticket_placeto, COUNT(CASE WHEN passenger_type <> 'Baggage' THEN 1 END) AS Pass,\n" +
"COUNT(CASE WHEN passenger_type = 'Baggage' THEN 1 END) AS Baggage FROM tickets GROUP BY ticket_placeto";
c = sqldb.rawQuery(query, null);
if (c != null) {
if (c.moveToFirst()) {
do {
String placeto = c.getString(0);
String passengers = c.getString(1);
String baggages = c.getString(2);
stops.add(placeto + " " + passengers + " " + baggages);
} while (c.moveToNext());
}
}
}
This is the output of it
I've just hard coded the spacing on stops.add for temporary display of data. I already have a custom ListItem Layout but didn't use it for the mean time.
this is the result of the query on chrome://inspect
enter image description here
for your reference, i just re-code LoadData. thanks to pskink who help me here and to other that respond on this thread.
public void LoadData() {
String query = "SELECT _id, ticket_placeto, " +
"COUNT(CASE WHEN passenger_type <> 'Baggage' THEN 1 END) AS Pass," +
"COUNT(CASE WHEN passenger_type = 'Baggage' THEN 1 END) AS Baggage " +
"FROM tickets GROUP BY ticket_placeto";
final String[] columns = new String[]{
DBHelper.TICKET_ID,
DBHelper.TICKET_PLACETO,
"Pass",
"Baggage",
};
final int[] to = new int[]{
R.id.stops_id,
R.id.stops_location,
R.id.stops_passengers,
R.id.stops_baggages
};
c = sqldb.rawQuery(query,null);
if (c != null) {
adapter = new SimpleCursorAdapter(getContext(), R.layout.item_for_stops, c, columns, to, 0);
lv_stops.setAdapter(adapter);
}
}
1.First initialize your List in onCreate() method of activty,
ArrayList<String> stops = new ArrayList<>();
then pass it to ArrayAdapter.
2.After successfully executing query add data to your "stops" list,then
add following line to your code.
arrayAdapter.notifyDataSetChanged();//to notify that your data of list has been change
This question already has an answer here:
Android:SQLite - Querying an Array in SelectionArgs as well as other string values
(1 answer)
Closed 8 years ago.
I have an array userNames which contains list of names and its not predetermined. I have to query a database which returns only the rowIDs which have any of the username from the array only if their availability is true. I think I can achieve this by using the code below but in my opinion its not efficient to use it.
ArrayList<Long> rowIDs = new ArrayList<Long>();
for (int i = 0 ; i < userNames.length ; i++) {
String selection = Columns.NAME + "=? and " + Columns.AVAILABILITY + "=?";
String[] selectionArgs = { userNames[i], true };
Cursor c = getContentResolver().query(Columns.URI,null,selection,selectionArgs,null);
if (c.getCount() > 0) {
rowIDs.add(c.getLong(c.getColumnIndex(Columns.ID)));
}
}
userNames in the array containing usernames. As it shows, db will be accessed again and again which isn't efficient especially if there are many user names. If possible, provide an efficient way to achieve it.
I donno where you require the thing.... I think we can use this String query="SELECT * FROM users WHERE username IN (?,?,.......)";
Cursor cur=db.rawQuery(query,new String[]{'name1','name2',....}); directly in the query. This is one method i remember.
But if you find something good do let me know too...
thx
Try this:
ArrayList rowIDs = new ArrayList();
String users="";
for (int i = 0 ; i < userNames.length ; i++) {
users=users+","+userNames[i];
}
String selection = Columns.NAME + " in (?) and " + Columns.AVAILABILITY + "=?";
String[] selectionArgs = { users[i], true };
Cursor c = etContentResolver().query(Columns.URI,null,selection,selectionArgs,null);
if (C.moveToFirst()) {
do{
rowIDs.add(c.getLong(c.getColumnIndex(Columns.ID)));
}while(c.moveToNext());
}
You can also use like instead of IN
I'm working on a symptoms checker android application where user can check as many symptoms he may be having. Please do check what I have tried so far:
public String getData(String[] symptoms) {
String search = "";
Cursor c = myDataBase.query(DB_TABLE, new String[]
{KEY_CONDITIONS}, KEY_SYMPTOMS + "= ? ", symptoms, null, null, null);
c.moveToFirst();
while (c.isAfterLast() == false) {
search += c.getString(0) + ", ";
c.moveToNext();
}
return search;
}
but I will need to generate that where string dynamically, because I don't know how many symptoms will be selected. How will I accomplish this? Help from you will truly be appreciated. Thanks!
The trick is you must have one insertion character (?) for each String in your Array.
One solution is to use a loop:
String where = KEY_SYMPTOMS + " = ?";
String relation = " OR "; /* Maybe " AND "? */
StringBuilder builder = new StringBuilder(where);
for(int i = 1; i < symptoms.length; i++)
builder.append(relation).append(where);
Cursor c = myDataBase.query(DB_TABLE, new String[]
{KEY_CONDITIONS}, builder.toString(), symptoms, null, null, null);
You can also write a shorter but equivalent loop:
while (c.moveToNext())
search += c.getString(0) + ", "; // A StringBuilder should be faster
Whenever I want to add new data to an existing Android contact, I use the following function to retrieve all RawContacts IDs for the given contact ID:
protected ArrayList<Long> getRawContactID(String contact_id) {
ArrayList<Long> rawContactIDs = new ArrayList<Long>();
String[] projection = new String[] { ContactsContract.RawContacts._ID };
String where = ContactsContract.RawContacts.CONTACT_ID + " = ?";
String[] selection = new String[] { contact_id };
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, where, selection, null);
try {
while (c.moveToNext()) {
rawContactIDs.add(c.getLong(0));
}
}
finally {
c.close();
}
return rawContactIDs;
}
After that, I just insert the data using the ContentResolver:
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
This is done for all RawContacts IDs that have been found previously. The effect is, of course, that all data is added repeatedly. Thus I want to return only one result now, but this has to meet special requirements.
I would like to adjust my function above so that its result meets the following requirements:
ContactsContract.RawContactsColumn.DELETED must be 0
The RawContacts entry must not be a secured one like Facebook's
ContactsContract.SyncColumns.ACCOUNT_TYPE is preferably "com.google". So if there is one entry that meets this requirement, it should be returned. If there is none, return any of the remaining entries.
How can I do this (most efficiently)? I don't want to make the query to complex.
I have given this some thought, from my experience with contact r/w, and with your needs in mind. I hope this helps you solve the issue and or points you in the direction you are looking for.
Please note that i have no device available with any sync adapters such as facebook so unfortunately i cannot confirm my answer viability (the read only bit mainly which might changeable to a simple != '' ).
Same getRawContactID function with some adjustments
protected ArrayList<Long> getRawContactID(String contact_id) {
HashMap<String,Long> rawContactIDs = new HashMap<String,Long>();
String[] projection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.ACCOUNT_TYPE };
String where = ContactsContract.RawContacts.CONTACT_ID + " = ? AND " + ContactsContract.RawContacts.DELETED + " != 1 AND " + ContactsContract.RawContacts.RAW_CONTACT_IS_READ_ONLY + " != 1" ;
String[] selection = new String[] { contact_id };
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, where, selection, null);
try {
while (c.moveToNext()) {
rawContactIDs.put(c.getString(1),c.getLong(0));
}
}
finally {
c.close();
}
return getBestRawID(rawContactIDs);
}
And another getBestRawID function to find the best suited account -
protected ArrayList<Long> getBestRawID(Map<String,Long> rawContactIDs)
{
ArrayList<Long> out = new ArrayList<Long>();
for (String key : rawContactIDs.KeySet())
{
if (key.equals("com.google"))
{
out.clear(); // might be better to seperate handling of this to another function to prevent WW3.
out.add(rawContactIDs.get(key));
return out;
} else {
out.add(rawContactIDs.get(key));
}
}
return out;
}
Also note - I wrote most of the code without running / testing it. Apologies in advance.
I'm trying to make a query where I get data from two tables but it won't show me any result. I know there is a result because in SQLite3 it displays at least one, e.g.
sqlite> select eventthemename, eventtypename from event_type, event_theme
...> where event_type.eventthemes = event_theme._id
...> and event_type._id = '2';
Tribal | Dance
I'm using a content provider. Does anyone have an idea on how to make this?
Your question isn't really clear (you should include some of your code!), so I might not answer your question as you hoped. But following is a simple example I have where I join two tables in one query:
private static final String QUERY_ALL_COURSES_WITH_SEMESTER =
"SELECT * FROM Course JOIN Semester ON semesterId = courseSemesterId";
public Course getCourseByCodeAndSemester(String courseCode, Semester semester)
{
Course result = null;
String whereClause = " WHERE courseCode = '" + courseCode.toUpperCase() + "'"
+ " AND semesterId = " + semester.getInternalId();
Cursor cursor = db.rawQuery(QUERY_ALL_COURSES_WITH_SEMESTER + whereClause, null);
if (cursor.moveToFirst())
{
result = Course.createFromCursor(cursor);
}
cursor.close();
return result;
}
Note that there are probably many things that could be optimized in this function, but it illustrates how it can be done.
As I'm using content providers I ended doing something not quite fast but that works:
themes = managedQuery(
EventTheme.CONTENT_URI,
PROJECTIONTHEMES,
EventTheme.EVENTTYPE + "= ?",
new String[] {eventType},
EventTheme.DEFAULT_SORT_ORDER);
String[] from = new String[] {
Event._ID,
Event.NAME,
Event.STARTDATE,
Event.ENDDATE,
PointOfInterest.POINTOFINTERESTNAME
};
int[] to = new int[] {
R.id.event_id,
R.id.name,
R.id.start_date,
R.id.end_date,
R.id.location_name
};
while (themes.getPosition() < themes.getCount() - 1) {
themes.moveToNext();
eventTheme = themes.getString(themes.getColumnIndexOrThrow(EventTheme._ID));
events = managedQuery(
Event.CONTENT_URI,
PROJECTIONEVENTS,
Event.EVENTTHEME + "= ?",
new String [] { eventTheme } ,
Event.DEFAULT_SORT_ORDER);
}