I am presenting user with the add calendar event screen with the below mentioned code.
For example the following will prompt the user if an event should be created with certain details.
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setData(CalendarContract.Events.CONTENT_URI);
startActivity(intent);
This part is working fine with Android 4.0 and above but not working on android 2.3....?
I want this to work on all android OS between 2.3 till 4.1.
you can use this also if you it to do with some other way :
mCursor = getContentResolver().query(
CalendarContract.Events.CONTENT_URI, COLS, null, null, null);
its a contentProvider for calender .
public class Main extends Activity implements OnClickListener{
private Cursor mCursor = null;
private static final String[] COLS = new String[]
{ CalendarContract.Events.TITLE, CalendarContract.Events.DTSTART};
}
Now we need to override the on create method. Pay special attention to how we populate the database cursor. This is where we need our previously defined COLS constant. You’ll note also that after the database cursor is initialized and the click handler callbacks are set, we go ahead and manually invoke the on click handler. This shortcut allows us to initially fill out our UI without having to repeat code.
Main.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCursor = getContentResolver().query(
CalendarContract.Events.CONTENT_URI, COLS, null, null, null);
mCursor.moveToFirst();
Button b = (Button)findViewById(R.id.next);
b.setOnClickListener(this);
b = (Button)findViewById(R.id.previous);
b.setOnClickListener(this);
onClick(findViewById(R.id.previous));
}
In our callback, we will manipulate the cursor to the correct entry in the database and update the UI.
#Override
public void onClick(View v) {
TextView tv = (TextView)findViewById(R.id.data);
String title = "N/A";
Long start = 0L;
switch(v.getId()) {
case R.id.next:
if(!mCursor.isLast()) mCursor.moveToNext();
break;
case R.id.previous:
if(!mCursor.isFirst()) mCursor.moveToPrevious();
break;
}
Format df = DateFormat.getDateFormat(this);
Format tf = DateFormat.getTimeFormat(this);
try {
title = mCursor.getString(0);
start = mCursor.getLong(1);
} catch (Exception e) {
//ignore
}
tv.setText(title+" on "+df.format(start)+" at "+tf.format(start));
}
Related
This question already has an answer here:
attempt to re-open an already-closed object: SQLiteDatabase
(1 answer)
Closed 8 years ago.
I know there are several questions like this one, but all of them seem to have a different approach to solve the problem and none have solved mine.
I have my main activity working just fine, loading the db and populating the listview. Then I call a second activity and the problem shows up when I try to load the listview.
I have tried using start/stop managingcursor(cursor) even though it is deprecated, but it didn't fix the problem. Also I tried cloasing the cursor and db in my main activity before firing the next one but that didn't help either.
Both classes extend from ListActivity and follow the same sequence:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Open db in writing mode
MySQLiteHelper.init(this);
MySQLiteHelper tpdbh =
new MySQLiteHelper(this, "DB", null, 1);
SQLiteDatabase db = tpdbh.getWritableDatabase();
checkLocationAndDownloadData(); //this fires a Asynctask that calls method parseNearbyBranches shown bellow
//I load the data to the ListView in the postExecute method of the asynctask by calling:
/*
Cursor cursor = MysSQLiteHelper.getBranchesNames();
adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String branch_id = cursor.getString(cursor.getColumnIndexOrThrow("branch_id"));
cursor.close();
openNextActivity(Integer.parseInt(branch_id));
}
});
}
//In another file:
private void parseNearbyBranches(JSONObject jo) throws JSONException
{
if ( jo.has(jsonTitle) &&
jo.has("company_id") &&
jo.has("id")
) {
String branch = jo.getString(jsonTitle);
MySQLiteHelper tpdbh = MySQLiteHelper.instance;
SQLiteDatabase db = tpdbh.getWritableDatabase();
db.execSQL("INSERT INTO Branches (branch_id, name, company_id) " +
"VALUES ('" +jo.getInt("id")+"', '" + branch +"', '" +jo.getInt("company_id")+"' )");
db.close(); //no difference is I comment or uncomment this line
}
}
In MySQLiteHelper.java:
public static Cursor getBranchesNames() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id", "branch_id", "name", "company_id" };
Cursor c = getReadDb().query(branchesTable, columns, null, null, null, null,
null);
return c;
}
My other activity does basically the same:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branch_surveys);
//Read branch data from DB
int companyID = -1;
MySQLiteHelper.init(this);
String [] columns = new String [] {"company_id"};
String [] args = {Integer.toString(branchID)};
Cursor c = MySQLiteHelper.getReadDb().query(MySQLiteHelper.branchesTable, columns, "branch_id=?", args, null, null, null); //THIS QUERY WORKS JUST FINE
if (c.moveToFirst())
companyID = Integer.parseInt(c.getString(0));
c.close();
if( companyID != -1)
{
new DownloadTask().execute(Integer.toString(companyID) );
//where the Async task calls something just like NearByBranches shown above(but with different objects of course)
//And the postExecute sets the listView:
/* cursor = MySQLiteHelper.getAll();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row, cursor, fields, new int[] { R.id.item_text },0);
setListAdapter(adapter);
*/
}
}
}
In MySQLiteHelper.java:
public static Cursor getAll() {
// TODO Auto-generated method stub
String[] columns = new String[] { "_id","title", "points" };
//********IT IS IN THIS LINE WHERE I GET THE ERROR:********************
Cursor c = getReadDb().query(theTable, columns, null, null, null, null,
null);
return c;
}
public static SQLiteDatabase getReadDb() {
if (null == db) {
db = instance.getReadableDatabase();
}
return db;
}
I hope you can help me out. Thanks!
I just tried commenting the db.close in the similar method of parseNeabyBranches and the problem was solved. Yet I dont get the same error having db.close() in parseNearbyBranches(), can you explain me why?
In parseNearbyBranches() you create a separate SQLiteDatabase object with:
SQLiteDatabase db = tpdbh.getWritableDatabase();
Since this is a different object than the one returned by getReadDb(), you can (and should) close it. The basic rule is each time you call getWritableDatabase() and getReadableDatable() you must have a matching close() statement.
I have this SQLite containing a number of 'Projects'. Each 'Project' with its attributes from the SQLite Database Table are displayed in an activity. What I wanna do is, when a button inside the activity is clicked, it updates the C_FAVORITE row of that 'Project'.
How am I able to do so? Which arguments do I need to put inside the update method below?
public void makeFavorite() {
Database.Project.C_FAVORITE.update(.......);
}
this is how I display the attributes of the Project on the activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.project);
loader = new ImageLoader(this);
Intent intent = getIntent();
if (intent != null) {
Uri uri = intent.getData();
if (uri != null) {
final Cursor cursor = managedQuery(uri, new String[] {
BaseColumns._ID, Database.Project.C_PROJECTTITLE, Database.Project.C_ORGANIZATIONTITLE,
Database.Project.C_PROJECTDESCRIPTION,Database.Project.C_BIGIMAGE,Database.Project.C_DONATIONAMOUNT,Database.Project.C_ADDRESS,Database.Project.C_WEBSITE,Database.Project.C_SHORTCODE,Database.Project.C_KEYWORD,Database.Project.C_PRICE,Database.Project.C_CAMPAIGNID,Database.Project.C_PAYPALEMAIL,Database.Project.C_ELVAVAILABLE}, null, null, null);
if (cursor == null) {
finish();
} else {
if (cursor.moveToFirst()) {
ImageView img = (ImageView) findViewById(R.id.project_image);
TextView project_title = (TextView)findViewById(R.id.txt_project_title);
project_title.setText(cursor.getString(1));
......
You can try as follows:
public SQLiteDatabase sqd;
//Create connection of database
public void makeFavorite(String fieldname,String c_fav_value) {
ContentValues cv = new ContentValues();
cv.put(fieldname,c_fav_value);
int i= sqd.update(table_name, cv, where, where_clause);
}
If you have no where clause you can pass null there.
One way is to add tags to the button and grab the tags from within the makeFavourite()-method. Exactly how it's done depends entirely on your application structure, of which you don't tell us anything about.
In onCreate(), I define a cursor and move down in the results using a button :
final Cursor cursor = (Cursor) WoordData.fetchset(USERCHOICE);
btnVolgende.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tv.setText(cursor.getString(0));
cursor.moveToNext();
if (cursor.isAfterLast()){
cursor.moveToFirst();
}}});
In a seperate activity (through Preferences) I allow the user to change the value of USERCHOICE.
Question : How to I re-load the cursor with the new query (new value of USERCHOICE) when the user returns to the main activity?
thnx!
Thanks to Christian, I solved it. I'm not sure this is the cleanest solution, though..
I created a boolean called resetneeded.
In the clickbutton code I do :
btnVolgende.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (resetneeded) {
cursor = (Cursor) WoordData.fetchset(kernset);
resetneeded = false;
}
startManagingCursor(cursor);
tvFlitswoord.setText(cursor.getString(0));
cursor.moveToNext();
if (cursor.isAfterLast()){
cursor.moveToFirst();
}}
}
And then, in the onStart(), I set the boolean resetneeded to true.
// EDIT - 2nd Solution
In the end, I decided to use an ArrayList for passing the words to the TextView (and cycling through it with the button). An ArrayList seems easier to handle and less fragile..
The code :
public void onStart(){
super.onStart();
getPrefs();
wordlistarray.clear();
cursor = (Cursor) WoordData.fetchset(kernset);
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
String wordtoadd = cursor.getString(0);
wordlistarray.add(wordtoadd);
cursor.moveToNext();
}
for(int i = 0; i < wordlistarray.size();
i++){ Log.d("word in array", "" + wordlistarray.get(i)); }
I need your help to fix my code.
My intention is if i click the item on ListView it will take me to intent action_view.
The problem is i got force close if i click the item on ListView.
I think the problem is in onItemClick method, can you give the better way to get it done.
Here's my code:
public class HotelList extends ListActivity{
hotelHelper dbHotelHelper;
protected Cursor cursor;
protected ListAdapter adapter;
ListView numberList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.hotellist);
numberList = (ListView)findViewById(android.R.id.list);
numberList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
String selectedItem = (String) getListAdapter().getItem(position);
String query = "SELECT lat, long FROM hoteltbl WHERE name = '" + selectedItem + "'";
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?f=d&saddr=&daddr="+lat+","+longi));
startActivity(intent);
}
});
dbHotelHelper = new hotelHelper(this);
try{
dbHotelHelper.createDataBase();
}
catch (Exception ioe){
Log.e("err","Unable to create database");
}
view();
}
private void view() {
// TODO Auto-generated method stub
SQLiteDatabase db = dbHotelHelper.getReadableDatabase();
try{
cursor = db.rawQuery("SELECT * FROM hoteltbl", null);
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
cursor,
new String[]{"name"},
new int[] {android.R.id.text1}
);
numberList.setAdapter(adapter);
}
catch (Exception e){
Log.e("error",e.toString());
}
}
}
Inside item click
you have many ways it might cause exception,
Exception will cause your app force close
your code is not handled with exceptions
I am listing down the causes it might cause the exception, please check followings
String selectedItem = (String) getListAdapter().getItem(position);
here you might get type conversation issue, you are converting something is not supported by String
SQLiteDatabase dbs = dbHotelHelper.getReadableDatabase();
Cursor result = dbs.rawQuery(query, null);
result.moveToFirst();
double lat = result.getDouble(result.getColumnIndex("lat"));
double longi = result.getDouble(result.getColumnIndex("long"));
If dbHotelHelper.getReadableDatabase returns null or dbHotelHelper null, in this case your app will force close
In case dbs.rawQuery return null, your app will force close
if result null then you might calling moveToFirst, getDouble and getColumnIndex on null object, in this case also your app will force close
For your info
SimpleCursorAdapter constructor was deprecated in API level 11.
This option is discouraged, as it results in Cursor queries being performed on the application's UI thread and thus can cause poor responsiveness or even Application Not Responding errors. As an alternative, use LoaderManager with a CursorLoader.
I need to perform a search operation into my SQLite DB.
In my Activity, I have EditText for entering the keyword and a search Button. Once the user clicks the button, the EditText text will be stored in the keyword and sent to a search(String keyword) method in the DBHelper class.
I have this code in my SearchActivityfor onCreate() and onClick():
//SearchActivity class extends ListActivity and implements OnClickListener
Button search;
DataBaseHelper myDbHelper;
SimpleCursorAdapter ca;
ListView lv;
EditText txt;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_layout);
txt = (EditText) findViewById(R.id.search_term);
search = (Button) findViewById(R.id.search_button);
search.setOnClickListener(this);
}
public void onClick(View v) {
try {
myDbHelper.openDataBase();
} catch (SQLException sqle) {}
try {
String keyword= txt.getText().toString();
Cursor cursor = myDbHelper.search(keyword); //A method in my DB
cursor.moveToFirst();
String[] columns = {cursor.getColumnName(1)};
int[] columnsLayouts = {R.id.item_title};
ca = new SimpleCursorAdapter(this.getBaseContext(), R.layout.items_layout, cursor,columns , columnsLayouts);
lv = getListView();
lv.setAdapter(ca);
} catch(Exception e){}
}
However, I got NullPointerException in the LogCat!! I couldn't find where the error is.
Anyone can help ?
The description to the NullPointerException could be a little more informative. But it is very likely that the NullPointerException occurs here:
1: Cursor cursor = myDbHelper.search(keyword); //A method in my DB
2: cursor.moveToFirst();
3: String[] columns = {cursor.getColumnName(1)};
or here:
1: try {
2: myDbHelper.openDataBase();
3: } catch (SQLException sqle) {}
Either in the first part in line 1: or 2: or in the second part in line 2:
You should always check if objects which rely on the existence of data are not null. So you should check if cursor is null. Another thing could be that you never initialize myDbHelper.