I am trying to write a simple app just to display on screen the results on a sql query.
public class ContactLookup extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null
);
}
}
How exactly do I print the results of the cursor? Everything I find goes into to way more detail then I need at the moment... I just want to know how to get that variable printed on screen.
You'll need to have something that shows text (or whatever you get from your DB). Most likely this will be a simple TextView (you can do this in the XML-Layout or in Java-Code).
If you declared your TextView in the XML-Layout, then you'll need to find the TextView in order to set it's text.
After that, you'll want to move the Cursor to the first set of data in it so you can read your results from it.
After that, you can simply use the Cursor's getXX()-methods to get your values form the result-set.
Related
I have two activities: one NoteListActivity which inherits from ListActivity, and I used SimpleCursorAdapter as its adapter where the cursor is obtained as below:
public Cursor getAllNotesCursor() {
String selectQuery = "SELECT _id , title, content FROM " + NOTE_TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
return cursor;
}
The another activity NoteEditorActivity is responsible for creating new note, there is a save action there and on click I will add a new note in the SQLite database then call finish to the NoteListActivity.
The problem is that the NoteListActivity didn't get updated with new note, do you know the best practice to achieve this?
One solution I can thought of is starting NoteEditorActivity by calling startActivityForResults then call cursor requery in onActivityResult, I don't know whether there is better solution?
startActivityForResults is good, but why not try to override onResume() method, with yourAdapter.notifyDataChange()
#Override
public void onResume() {
...
yourAdapter.notifyDataSetChanged();
}
Of course you have to add yourAdapter on your field class.
Whatever you are doing in onCreate method that is affecting UI to draw or show note by fetching from database.
Don't do it in onCreate.
DO IT IN onResume
#Override
public void onResume(){
//fetch here, do other operation, or set layout here
}
notifyDataSetChanged Update List View Adopter
http://androidadapternotifiydatasetchanged.blogspot.in/
try following steps..
use startActivityForResult() inside NoteListActivity to start NoteEditorActivity.
set RESULT_OK in save button click event
Populate list in onActivityResult() of NoteListActivity
I have connected a database in my Android Application. Now I have created a button and when it is clicked, that should get the next data from the table of database. I have cursor and he moveToFirst() and moveToNext() methods in my code. also I have set onclick listener to my button. but in output when I click the button, its is not fetching the next data from database
heres the part of code where I have tried to set on click listener for button
c=myDbHelper.query(myDbHelper.DB_PATH +"/MainTable",null, null, null, null,null, null);
c.moveToFirst();
myques=(TextView)findViewById(R.id.question);
myrg=(RadioGroup)findViewById(R.id.rg1);
myc1=(RadioButton)findViewById(R.id.radio0);
myc2=(RadioButton)findViewById(R.id.radio1);
myc3=(RadioButton)findViewById(R.id.radio2);
myc4=(RadioButton)findViewById(R.id.radio3);
NxtQues=(Button)findViewById(R.id.button1);
myques.setText(c.getString(1));
myc1.setText(c.getString(2));
myc2.setText(c.getString(3));
myc3.setText(c.getString(4));
myc4.setText(c.getString(5));
NxtQues.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View V)
{
c.moveToNext();
}
});
what changes should I make in this code to set on click listener in a proper way.
So in your code is a few problems. At first here:
c = myDbHelper.query(myDbHelper.DB_PATH +"/MainTable", ...);
As first parameter of query() method is "raw" tablename so you can't assign there full path of your database(if it isn't real tablename...), it's wrong. Just assign MainTable like this:
c = myDbHelper.query("MainTable", null, null, null, null, null, null);
Then your logic about fetching data from database is not good at all. You assigned values to your widgets only once and no more. They never be refreshed, you need to call as many times setText() method as you want to update widget's content. Actually you don't update them.
You need to change your logic to:
#Override
public void onClick(View V) {
if (c.moveToNext()) {
myques.setText(c.getString(1));
myc1.setText(c.getString(2));
myc2.setText(c.getString(3));
myc3.setText(c.getString(4));
myc4.setText(c.getString(5));
}
}
Recommendation:
When you are using "getters" methods of Cursor, i recommend you to use column names to get columns indexes:
myques.setText(c.getString(c.getColumnIndex("columnName")));
I have an app that functions properly and does not force close or crash. But when I look at LogCat, it occasionally gives me this:
05-20 15:24:55.338: E/SQLiteDatabase(12707): close() was never explicitly called on database '/data/data/com.---.--/databases/debt.db'
05-20 15:24:55.338: E/SQLiteDatabase(12707): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
a little ways down...
05-20 15:24:55.338: E/System(12707): Uncaught exception thrown by finalizer
05-20 15:24:55.338: E/System(12707): java.lang.IllegalStateException: Don't have database lock!
I am not sure when I should be opening and closing my Database?
I have a Main activity that is simply a splash screen. It then goes into an activity that calls a ListView using info from the DB; so it is at this activity where the DB is first opened.
There is also one other Activity where the DB is required that branches off the one with the ListVeew. When am I supposed to be opening and closing this? Word seems to be that I simply need to open once, and then close when the app is "paused", "stopped" or "destroyed".
If this is the case, where do I put the db.close() method... in the Splash Screen Main Activity where onStop, etc is located? or the same Activity as the one that opens the DB? or.. is there another place?
UPDATE:
This is the line in code that the error keeps pointing to:
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
If you're using an instance of a DatabaseHelper class, and after you initialize the DBHelper object, every time you do work in the database you should call the open method before you do work, then create a new cursor, query the database, do work with the information you just stored in the cursor, when you're done close the cursor, then close the database. For example if you wanted to grab every item in a database you would do something like :
...
DataBaseHelper db = new DataBaseHelper(this);
...
db.open();
Cursor cursor = db.getAllItems();
maxCount = cursor.getCount();
Random gen = new Random();
row = gen.nextInt(maxCount); // Generate random between 0 and max
if (cursor.moveToPosition(row)) {
String myString = cursor.getString(1); //here I want the second column
displayString(myString); //private method
}
cursor.close();
db.close();
getAllItems is a public method in my DatabaseHelper, it looks like this in case you were wondering
public Cursor getAllItems() {
return db.query(DATABASE_TABLE,
new String[] {
KEY_ROWID,
KEY_NAME
},
null,
null,
null,
null,
null);
}
This is how I access my database and I haven't gotten any of the errors you've got, and it works perfectly.
I used to do the way #Shikima mentioned above but in complex applications which has many background services, multi-threading,etc it can get real tiresome when you have to manage many database instances and on top of that, opening and closing them.
To overcome this, I used the following method and it seems to be working fine.
1.
Declare and initialize an instance of YourDBHelperClass in your Application base class like this :
public class App extends Application {
public static YourDBHelperClass db;
#Override
public void onCreate() {
super.onCreate();
db = new YourDBHelperClass(getApplicationContext());
db.open();
}
}
2.
In you activity, or any other place you want to use the DB, initialize the YourDBHelperClass object like this :
YourDBHelperClass db = App.db;
And then you can use the database anyway you want without having to worry about opening and closing it manually each time. The SQLiteOpenHelper takes care of the closing when the Application is destroyed
You are probably not handling your database correctly; you are opening more database instances than you are closing.
There are a number of design patterns you can follow to correct this behavior. You might want to consult this answer for more information.
I will like to know if we can continuously call some service for fetching results and displaying in Autocomplete list.
I have one screen with the text box and when user starts entering in that textbox the autocomplete should get filled with the data. The data will not be hardcoded and will be fetched through http connection. I think I need to call http connection in onTextChanged method of Edittext but is that the perfect solution.
Moreover, should this type of implementation done in mobile application. Since, this feature is web based. Can this be done in mobile application too?
Is this feasible?
Write a custom SimpleCursorAdapter. Now associate this adapter to your EditText. Here is the code to construct a Cursor object and return it:
public class ValueCursorAdapter extends SimpleCursorAdapter implements Filterable
{
...
// overrise the newView() to associate mCursor[1] and mCursor[2] to relevant views within
...
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint)
{
MatrixCursor mCursor = new MatrixCursor(new String[] { "_id", "uri", "label" });
.. // result = ??
while (result.hasNext())
{
mCursor.addRow(new Object[] { count, "uri", "title"});
count++;
}
return mCursor;
}
}
Here is an example for Customizing Cursor Adapter. You might need to customize it to fit your requirements.
Right now, I'm running into issues trying to implement a FilterQueryProvider in my custom SimpleCursorAdapter, since I'm unsure of what to do in the FilterQueryProvider's runQuery function.
In other words, since the query that comprises my ListView basically gets the rowID, name, and a third column from my databases's table, I want to be able to filter the cursor based on the partial value of the name column.
However, I am uncertain of whether I can do this directly from runQuery without expanding my DB class since I want to filter the existing cursor, or will I have to create a new query function in my DB class that partially searches my name column, and if so, how would I go about creating the query statement while using the CharSequence constraint argument in runQuery?
I am also concerned about the performance issues associated with trying to run multiple queries based on partial text since the DB table in question has about 1300-1400 rows. In other words, would I run into a bottleneck trying to filter the cursor?
You need to run a query that will return a new filtered cursor:
public class MyActivity extends ListActivity implements FilterQueryProvider {
private Cursor cursor;
#Override
public Cursor runQuery(CharSequence constraint) {
if(cursor != null) {
cursor.close();
}
cursor = somehowGetAFilteredCursorFor(constraint);
startManagingCursor(cursor);
return cursor;
}
}