How to get specific rows from ContentProvider? - android

I am a little new to using content providers. I was wondering how I would get specific rows from a content provider?
For example how would I get the first row of my provider?
This is what I tried but It isnt working:
final Cursor cursorConversations = getActivity().getContentResolver()
.query(CONTENT_URI, null, null, null, null);
Toast.makeText(
getActivity(),
cursorConversations.getString(cursorConversations
.getColumnIndex(Columns.TITLE)),
Toast.LENGTH_LONG).show();

you simply use cursor move methods ex:
cursorConversations.moveToFirst();
cursorConversations.moveToPosition(0);
cursorConversations.moveToNext(); // <-- if at beginning position
just to make this answer a little more meaty, a popular technique used to loop through the rows of the cursor 1 by 1 from the beginning is:
while (cursorConversations.moveToNext()) {
// do something
}
Because the moveToNext() method (as well as other move methods) return a boolean, the loop will exit when the last row has been reached and can no longer moved to the next. effective and easy on the eyes too. One more tip: the cursor starts at the -1 index, before the first position of a zero-based query index results.

use something like this:---
if(cursorConversations.moveToFirst()){
int size=cursorConversations.getCount();
for(int i=0;i<size;i++){
cursorConversations.getString(cursorConversations
.getColumnIndex(Columns.TITLE));
cursorConversations.moveToNext();
}
}
cursorConversations.close();
Or
while(cursorConversations.moveTonext())
{
cursorConversations.getString(cursorConversations
.getColumnIndex(Columns.TITLE));
}

Related

Reading a value from a database

I have a database in my app with several columns of which 3 are: _id name selected.
Now, I want to read a single selected value from a row with the name being a string I get from some code. What would be the best way to do this?
Thanks
P.S. I am getting that value to check if it's 0 or 1 (only two possible values), so I want to ask how to make a kind of an if statement in the return field? I have seen some people do it with something resembling this: return true ? ... false
EDIT:
Okay, this is my code atm, haven't checked it yet since I need to do some other things to get it all up, but I think there may be a better way to do this.
public boolean isBandSelected(String name) {
// TODO Auto-generated method stub
Cursor cursor = mDb.query("bands", new String[] { "selected" }, "name="
+ name, null, null, null, null);
int index = cursor.getColumnIndex("selected");
String selected = cursor.getString(index);
return selected == "1";
}
You can use regular expression to match rows whose name field being string. Many databases can support regular expression.
The ternary operator(? :) can be used to make return statement like this.
return value == 0 ? false : true
But it depends on what kind of data type you what to return. Code above returns boolean data type.
The last line of your code above will always return false. This is because the == operator compares the reference of the two objects. you can use:
return "1".equals(selected);

Android do while loop

Hi This my second question here.
I have the following table
|-----|-------|------|------|
|._id.|..INFO.|.DONE.|.LAST.|
|..1..|...A...|...N..|......|
|..2..|...B...|...Y..|..L...|<--- cursor.moveToPosition((int)_id-1);
|..3..|...C...|...Y..|......|
|..4..|...D...|...Y..|......|
|..5..|...E...|...N..|......|
|..6..|...F...|...N..|......|
|-----|-------|------|------|
I use the code:
cursor = db.query(TABLE_NAME, new String[]{INFO,DONE,LAST},null,null,null,null,null);
cursor.moveToPosition((int)_id-1);
String Yval = cursor.getString(cursor.getColumnIndex(DONE));
do
{
cursor.moveToNext();
Yval= cursor.getString(cursor.getColumnIndex(DONE));
}
while (Yval=="Y");
s = Yval;
I initially point the cursor to the LAST row I accessed, then I make a loop to go through the values in the DONE column, not stopping if there are Y's in the row of the column. When an N appears in the loop, the loop should stop.
But it doesn't work.
Yval never equals "Y". So the cursor does one 'moveToNext' and then exits the loop, because it doesn't read Yval as a "Y".
(I also changed everything to integers. 1 for N, and 0 for Y, but it still didn't work)
So what am I doing wrong here?
So you have to use equals() method if you want to compare Strings
while (Yval.equals("Y"));
You should know that:
== tests for reference equality.
equals tests for value equality.
So you want to test if Yval String has Y value so you have to use equals() method.
You approach doesn't work bacause:
String data = "lorem";
data == "lorem" ==> FALSE
data.equals("lorem") == TRUE
Also make sure that your Cursor has valid row so you need to add to condition also cursor.moveToNext() so
cursor.moveToNext() && (Yval.equals("Y")
also you need to treat cursor.moveToPosition((int)_id-1) so add it to condition.
I recommend changing a few things:
if(cursor.moveToPosition((int) _id - 1)) {
int doneIndex = cursor.getColumnIndex(DONE);
String Yval;
do {
Yval = cursor.getString(doneIndex);
} while(Yval.equals("Y") && cursor.moveToNext());
}
You should check if a row exists at position _id - 1 since the SQLite _id is a unique id, not the position of a row in a Cursor.
You only need to fetch the index of the DONE column once, simply store it in a local variable.
As deceiver mentioned, String are tested with equals() and similar methods.
You need consider what happens if all of the rows are "DONE", then you must stop trying to read the Cursor before an out of bounds exception is thrown.

OR operation in WHERE clause

Right now my code looks like this:
Cursor cursor = getContentResolver().query(messagesUri, null,"address=?", smsNo, null);
where smsNo is a singleton array.
I would like to add elements to this array and implement an OR operation in the WHERE clause. Is this possible to do continuing to use an array?
I'm not quite sure what you're asking, but you certainly can continue to use an array here. If you're asking how to extend an existing array to have more items, you can use Arrays.copyOf(oldArray, newSize) to make additional space in it. And you can then just use multiple ? placeholders in your query string to reference the new items.
For example:
queryParameters = Arrays.copyOf(smsNo, 2);
queryParameters[1] = "another number"
Cursor cursor = getContentResolver().query(messagesUri, null,"address=? or address=?", queryParameters, null);

Android: loading from SQLite Database

So I'm still building a Database to support a project of mine. There are two different things to be saved: first, attribute values of some player objects and second, simple values stored in a java class.
ATM my problem lies in the process of loading values of a player object and writing it in the respective class.
Now let's see some code:
Following you see the method I want to use for saving the values in the database.
That works fine atm, but I just realized I'm still passing the contentValues object an extra value for the 'ID' , which I did set - and planned to keep that way - as autoincrement.
Any Idea how to work this in accordingly?
public void savePlayer(Player player[]) {
for (int i = 0; i <= 3; i++) {
playerValues.put("ID", i);
playerValues.put("Name", player[i].getName());
playerValues.put("HP", player[i].getHp());
playerValues.put("Satisfaction", player[i].getsatisfaction());
playerValues.put("Hygiene", player[i].isHygieneInt());
playerValues.put("IsAlive", player[i].isAliveInt());
}
db.insert("playertable", null, playerValues);
}
Okay, hold on to your hats because this might look a bit like spaghetti - the load-method:
public void loadPlayer() {
String[] namecolumn = { "Name" };
String[] intcolumn = { "ID, HP, Satisfaction, Hygiene, IsAlive" };
String[] namesToString = new String[4];
for (int j = 0; j <= 3; j++) {
Cursor playerCursorName = db.query("playertable", namecolumn, "ID="
+ j, null, null, null, null);
namesToString = cursorToString(playerCursorName);
Resource.playerArray[j].setName(namesToString[j]);
}
for (int i = 0; i < 3; i++) {
int[] restToInt;
Cursor playerCursorInt = db.query("playertable", intcolumn, "ID="
+ i, null, null, null, null);
restToInt = cursorToInt(playerCursorInt, 4);
Resource.playerArray[i].setHp(restToInt[i]);
Resource.playerArray[i].setsatisfaction(restToInt[i]);
Resource.playerArray[i].setHygieneInt(restToInt[i]);
Resource.playerArray[i].setAliveInt(restToInt[i]);
}
}
Yeah, I know this looks pretty ugly but let me explain it:
Because there are 4 player objects I planned on iterating through the database entries by using the ID as identifier to get exactly one row at a time and writing the name and the other values of this object in the java class where I want to manage them within my project.
Note: same problem with autoincrement here than in the save method
In addition, I get a CursorIndexOutOfBoundsException when calling loadPlayer because
Index -1 is being requested - isn't that the result of an operation on the database resulting in an error?
Yeah that's pretty much it, I'll provide you with additional code if requested, hope someone can help me
You are using Cursors in a slightly odd way here.
The point of a Cursor is to ask SQLite to do the hard work of fetching data for you, and your job is simply to use the cursor to iterate through the returned values.
Firstly, I would change the query here to ask for all values in the table (and perhaps put some condition to constrain what you get back), to make sure your cursor then contains all your values.
Then, I would loop through the cursor's values by using a while loop, (with cursor.moveToPosition(-1) before the loop) moving along the cursor by using cursor.moveToNext().
See the API for more information:
http://developer.android.com/reference/android/database/Cursor.html
With regard to the autoincrement problem, as far as I can remember you can leave out the ID and use db.insert() without that field and the database will provide an ID for you.
You shouldn't have the same issue in your load method because it doesn't make sense to autoincrement when loading, you just get back what's in the database.

What to do with Cursor after a SQLite query?

This is my first time using a database and I'm not really sure how this works. I made the database and made a query that returns a cursor and... now what? What is a cursor, really? Can I just use that to navigate through my data or do I have to put it in an ArrayList or ListActivity or what?
You need to iterate the cursor to get your results.
Use cursor.moveToFirst() and/or cursor.moveToNext() (with a while loop). Then you can use the getX() method, like cursor.getInt() or cursor.getString().
For example, ir your are expecting one result from your query:
if (cursor.moveToFirst()) {
String name = cursor.getString(cursor.getColumnIndex('NAME'));
int age = cursor.getInt(cursor.getColumnIndex('AGE'));
} else {
// oops nothing found!
}
First call cursor.moveToFirst(). Each time you call cursor.moveToNext() it will move to the next row. Make sure when you are done with your cursor you call cursor.deactivate() or you will get errors in your log cat.
Iterate over the returned Cursor instance
public List<Object[]> cursorToTableRows(Cursor cursor) {
List<Object[]> result = new ArrayList<Object[]>(cursor.getCount());
cursor.move(0);
cursor.moveToNext();
while (cursor.isAfterLast() == false) {
Object[] tableRow = new Object[cursor.getColumnCount()];
for(int i=0; i<cursor.getColumnNames().length; i++) {
int columnIndex = cursor.getColumnIndex(cursor.getColumnName(i));
String columnValue = cursor.getString(columnIndex);
tableRow[i] = columnValue;
}
result.add(tableRow);
cursor.moveToNext();
}
cursor.close();
return result;
}
Then create the desired objects.
public List<Vehicle> getVehicles() {
List<Vehicle> vehicles = new ArrayList<Vehicle>();
Cursor cursor = null;
List<Object[]> objects = cursorToTableRows(cursor);
for(Object[] row : objects) {
int i=0;
Vehicle vehicle = new Vehicle(row[i++].toString(), row[i++].toString()));
vehicles.add(vehicle)
}
return vehicles;
}
from Developer.android: This interface provides random read-write access to the result set returned by a database query.
In other words: query returns you a set of data represented by a cursor. First you need to make sure you got a valid cursor (not null) and then try to move it to desired position in the data set (use moveToXXX methods). In order to obtain data pointed by cursor use getXXX methods. When done using it make sure to call close to release resources.
According to this link it looks like you can iterate through the query return using something like:
cursor.next();
And grab the data at the location you are looking for using:
cursor.getString(0)
After you successfully have your Cursor setup, you would typically want to display that to a view in some form.
Have a look at the following answer for a detailed, but simple example of using a Cursor Adapter to pair up your newly-minted Cursor with your desired XML View:
https://stackoverflow.com/a/20532937/293280

Categories

Resources