I created an app to set reminders. For that I use two fragments: one to show the list of reminders and another one to create and edit a specific reminder.
When I edit the reminder, I have issues showing the already saved data from the SQLite Database (saving seems to work fine). I managed to show the title of the reminder by sending it from the list of reminders using arguments. However, I think it would make more sense to directly access the database from the edit fragment. I already tried different methods, but I think I am not accessing the ReminderProvider class correctly. I tried to create a method getTitel in the ReminderProvider classe which is used to handle the database, but I would then need to create an instance of the class and this is where I get lost since I don't instantiate it correctly (I get an NPE).
I would also like to access the db to show the date and time that have been saved before (I haven't been able to solve that with the arguments yet).
I have the same issue with the notification: I get a notification at the indicated time, but the notification does not show the title of the reminder. I can then access the reminder into the edit fragment, but then also I don't see the already saved data - another reason why I would like to load it directly from the database.
I have searched a lot here but didn't not find the answer (or couldn't transfer it to my case). I am still a beginner so I would appreciate any help. Thanks! (And sorry if this is a really stupid question...)
My code for the classes ReminderEditFragment and ReminderProvider is below (I also have the following classes: ReminderListFragment to show all reminders, ReminderListActivity to handle the ListFragment, ReminderEditActivity, ReminderManager, OnAlarmReceiver, OnBootReceiver, ReminderService, als well as fragments for the date- and timepicker)
ReminderEditFragment:
public class ReminderEditFragment extends Fragment implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String TIME_FORMAT = "kk:mm";
private Calendar mCalendar;
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mCalendar.set(Calendar.YEAR, year);
mCalendar.set(Calendar.MONTH, monthOfYear);
mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateButtons();
}
#Override
public void onTimeSet(TimePicker view, int hour, int minute) {
mCalendar.set(Calendar.HOUR_OF_DAY, hour);
mCalendar.set(Calendar.MINUTE, minute);
updateButtons();
}
private void updateButtons() {
//Text des TimeButtons setzen
SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT);
String timeForButton = null;
timeForButton = timeFormat.format(mCalendar.getTime());
mTimeButton.setText(timeForButton);
//Text des DateButtons setzen
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
String dateForButton = null;
dateForButton = dateFormat.format(mCalendar.getTime());
mDateButton.setText(dateForButton);
}
public static final String DEFAULT_EDIT_FRAGMENT_TAG = "editFragmentTag";
private EditText mReminderTitle;
private Button mDateButton;
private Button mTimeButton;
private Button mConfirmButton;
private Button mDeleteButton;
private long mRowID;
private TextView mTextOldDate;
private TextView mOldDate;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments != null) {
mRowID = arguments.getLong(ReminderProvider.COLUMN_ID);
}
if (savedInstanceState != null && savedInstanceState.containsKey(CALENDAR)) {
mCalendar = (Calendar) savedInstanceState.getSerializable(CALENDAR);
} else{
mCalendar = Calendar.getInstance();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.reminder_edit, container, false);
mReminderTitle = v.findViewById(R.id.editText_reminder);
mDateButton = v.findViewById(R.id.button_reminder_date);
mTimeButton = v.findViewById(R.id.button_reminder_time);
if (mRowID != 0) {
Bundle arguments = getArguments();
String reminderTitle = arguments.getString(ReminderProvider.COLUMN_TITLE);
//I have also tried different versions of the following, but here I get the NPE
//Cursor c = (Cursor) new ReminderProvider().getTitle(mRowID);
//String reminderTitle = new ReminderProvider().getTitle(mRowID);
mReminderTitle.setText(reminderTitle);
}
mConfirmButton = v.findViewById(R.id.button_confirm);
mDeleteButton = v.findViewById(R.id.button_delete);
mDateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDatePicker();
}
});
mTimeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
showTimePicker();
}
});
mConfirmButton.setOnClickListener (new View.OnClickListener() {
#Override
public void onClick(View view) {
ContentValues values = new ContentValues();
values.put(ReminderProvider.COLUMN_ID, mRowID);
values.put(ReminderProvider.COLUMN_TITLE, mReminderTitle.getText().toString());
values.put(ReminderProvider.COLUMN_DATE_TIME, mCalendar.getTimeInMillis());
if (mRowID == 0) {
Uri itemUri = getActivity().getContentResolver().insert(ReminderProvider.CONTENT_URI, values);
mRowID = ContentUris.parseId(itemUri);
} else {
int count = getActivity().getContentResolver().update(ContentUris.withAppendedId(ReminderProvider.CONTENT_URI, mRowID),
values, null, null);
if (count != 1)
throw new IllegalStateException(mRowID + " konnte nicht aktualisiert werden.");
}
Toast.makeText(getActivity(), getString(R.string.task_saved_message), Toast.LENGTH_SHORT).show();
getActivity().finish();
new ReminderManager(getActivity()).setReminder(mRowID, mCalendar);
}
});
mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mRowID != 0) {
getActivity().getContentResolver().delete(ContentUris.withAppendedId(ReminderProvider.CONTENT_URI, mRowID), null, null);
Toast.makeText(getActivity(), getString(R.string.task_deleted_message), Toast.LENGTH_SHORT).show();
getActivity().finish();
}
}
});
return v;
}
//Dialogkonstanten
static final String YEAR = "year";
static final String MONTH = "month";
static final String DAY = "day";
static final String HOUR = "hour";
static final String MINS = "mins";
static final String CALENDAR = "calendar";
private void showDatePicker() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = new DatePickerDialogFragment();
Bundle args = new Bundle();
args.putInt(YEAR, mCalendar.get(Calendar.YEAR));
args.putInt(MONTH, mCalendar.get(Calendar.MONTH));
args.putInt(DAY, mCalendar.get(Calendar.DAY_OF_MONTH));
newFragment.setArguments(args);
newFragment.show(ft, "datePicker");
}
private void showTimePicker() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = new TimePickerDialogFragment();
Bundle args = new Bundle();
args.putInt(HOUR, mCalendar.get(Calendar.HOUR_OF_DAY));
args.putInt(MINS, mCalendar.get(Calendar.MINUTE));
newFragment.setArguments(args);
newFragment.show(ft, "timePicker");
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Calendar-Instanz speichern, falls Aenderungen vorgenommen wurden
outState.putSerializable(CALENDAR, mCalendar);
}
}
ReminderProvider:
public class ReminderProvider extends ContentProvider {
//ContentProvider URI und Quelle
public static String AUTHORITY = "com.example.mareike.remindme2.ReminderProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/reminder");
//Fuer Begriffe oder Suche nach Definitionen verwendete MIME Typen
public static final String REMINDERS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.com.example.mareike.remindme2.reminder";
public static final String REMINDER_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.com.example.mareike.remindme2.reminder";
//Datenbank Konstanten
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "reminder";
//Datenbanken Spalten
public static final String COLUMN_ID = "_id";
public static final String COLUMN_DATE_TIME = "reminder_date_time";
public static final String COLUMN_TITLE = "title";
//SQL Anweisung zusammensetzen
private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE +
" (" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_TITLE +
" text not null, " + COLUMN_DATE_TIME + " integer not null);";
//UriMatcher-Zeug
private static final int LIST_REMINDER = 0;
private static final int ITEM_REMINDER = 1;
private static final UriMatcher sURIMatcher = buildUriMatcher();
private SQLiteDatabase mDb;
//Erstellt ein UriMatcher-Objekt fuer Suchvorschlaege und Kurzabfragen
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "reminder", LIST_REMINDER);
matcher.addURI(AUTHORITY, "reminder/#", ITEM_REMINDER);
return matcher;
}
#Override
public boolean onCreate() {
mDb = new DatabaseHelper(getContext()).getWritableDatabase();
return true;
}
#Override
public Cursor query(Uri uri, String[] ignored1, String ignored2, String[] ignored3, String ignored4) {
String[] projection = new String[]{ReminderProvider.COLUMN_ID, ReminderProvider.COLUMN_TITLE, ReminderProvider.COLUMN_DATE_TIME};
//UriMatcher verwenden, um den Abfragetyp festzustellen und die Datenbankanfrage entsprechend zu formatieren
Cursor c;
switch(sURIMatcher.match(uri)) {
case LIST_REMINDER:
c = mDb.query(ReminderProvider.DATABASE_TABLE, projection, null, null, null, null, null);
break;
case ITEM_REMINDER:
c = mDb.query(ReminderProvider.DATABASE_TABLE, projection, ReminderProvider.COLUMN_ID + "=?", new String[]{Long.toString(ContentUris.parseId(uri))},
null, null, null, null);
if (c != null && c.getCount() > 0) {
c.moveToFirst();
}
break;
default:
throw new IllegalArgumentException("Unbekannte URI: " + uri);
}
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
#Override
public Uri insert (Uri uri, ContentValues values) {
values.remove(ReminderProvider.COLUMN_ID);
long id = mDb.insertOrThrow(ReminderProvider.DATABASE_TABLE, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
#Override
public int delete(Uri uri, String ignored1, String[] ignored2) {
int count = mDb.delete(ReminderProvider.DATABASE_TABLE, ReminderProvider.COLUMN_ID + "=?", new String[]{Long.toString(ContentUris.parseId(uri))});
if (count > 0)
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
#Override
public int update(Uri uri, ContentValues values, String ignored1, String[] ignored2) {
int count = mDb.update(ReminderProvider.DATABASE_TABLE, values, COLUMN_ID + "=?", new String[]{Long.toString(ContentUris.parseId(uri))});
if (count > 0)
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
//Methode zur Abfrage der unterstuetzten Typen. Sie wird auch in der Methode query() genutzt, um den Typ der empfangenen Uri festzustellen
#Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case LIST_REMINDER:
return REMINDERS_MIME_TYPE;
case ITEM_REMINDER:
return REMINDER_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
//I also tried the following method(s) to be accessed from ReminderEditFragment
//Methode, um mit ID Titel abzufragen
//public Cursor fetchTitle (int id) {
// return mDb.rawQuery("SELECT title FROM data WHERE _id = " +id, null);
//}
public String getTitle(long id) {
String stringTitle = "kein Titel vorhanden";
int intId = (int)id;
Cursor cursor = mDb.rawQuery ("SELECT title FROM data WHERE _id = " +id, null);
if (cursor.moveToFirst()) {
do {
stringTitle = cursor.getString(cursor.getColumnIndex("title"));
}
while(cursor.moveToNext());
}
cursor.close();
return stringTitle;
}
public class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
throw new UnsupportedOperationException();
}
}
}
I managed to to solve the issue not by using a constructur, but by adding query method for each of the three fields using the content_uri to the ReminderEditFragment class:
public String savedDate (long id) {
//Abfrage
String[] projection = {
ReminderProvider.COLUMN_ID,
ReminderProvider.COLUMN_TITLE,
ReminderProvider.COLUMN_DATE_TIME
};
Uri singleUri = ContentUris.withAppendedId(ReminderProvider.CONTENT_URI, mRowID);
Cursor cursor = getActivity().getContentResolver().query(
singleUri,
projection,
null,
null,
null);
cursor.moveToFirst();
//Date und Time setzen
String dateS = cursor.getString(2);
long dateJavaTimestamp = Long.parseLong(dateS);
Date date = new Date(dateJavaTimestamp);
String savedDate = new SimpleDateFormat(DATE_FORMAT).format(date);
cursor.close();
return savedDate;
}
public String savedTime (long id) {
//Abfrage
String[] projection = {
ReminderProvider.COLUMN_ID,
ReminderProvider.COLUMN_TITLE,
ReminderProvider.COLUMN_DATE_TIME
};
Uri singleUri = ContentUris.withAppendedId(ReminderProvider.CONTENT_URI, mRowID);
Cursor cursor = getActivity().getContentResolver().query(
singleUri,
projection,
null,
null,
null);
cursor.moveToFirst();
//Date und Time setzen
String dateS = cursor.getString(2);
long dateJavaTimestamp = Long.parseLong(dateS);
Date date = new Date(dateJavaTimestamp);
String savedTime = new SimpleDateFormat(TIME_FORMAT).format(date);
cursor.close();
return savedTime;
}
Maybe this helps someone with a similar issue.
Related
i have two activities, each one have a listview. The first one contain the data and i want the other one to be as a favorite list. Right now i can pass the data with intent but its not saving. it shows when i start the intent but when i exit the second activity and go back to it with a custom button nothing is saved in the listview. Please tell me what to do. here is my code
public class MainActivity extends AppCompatActivity {
DB_Sqlite dbSqlite;
ListView listView;
String fav_name;
long fav_id;
ArrayAdapter adapter;
ArrayList arrayList;
String[] number;
Button button;
StringResourcesHandling srh;
Cursor getAllDataInCurrentLocale,getDataInCurrentLocaleById;
SimpleCursorAdapter favourites_adapter,non_favourites_adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
arrayList = new ArrayList<String>();
listView.setAdapter(adapter);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, cc.class);
startActivity(intent);
}
});
/* Show the resources for demo */
for (String s : StringResourcesHandling.getAllStringResourceNames()) {
Log.d("RESOURCEDATA", "String Resource Name = " + s +
"\n\tValue = " + StringResourcesHandling.getStringByName(this, s)
);
}
dbSqlite = new DB_Sqlite(this);
Cursor csr = dbSqlite.getAllDataInCurrentLocale(this);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
#Override
protected void onDestroy() {
super.onDestroy();
getAllDataInCurrentLocale.close();
}
#Override
protected void onResume() {
super.onResume();
manageNonFavouritesListView();
}
private void manageNonFavouritesListView() {
getAllDataInCurrentLocale = dbSqlite.getAllDataInCurrentLocale(this);
if (non_favourites_adapter == null) {
non_favourites_adapter = new SimpleCursorAdapter(
this,
R.layout.textview,
getAllDataInCurrentLocale,
new String[]{FAVOURITES_COL_NAME},
new int[]{R.id.textview10},
0
);
listView.setAdapter(non_favourites_adapter);
setListViewHandler(listView,false);
} else {
non_favourites_adapter.swapCursor(getAllDataInCurrentLocale);
}
}
private void setListViewHandler(ListView listView, boolean favourite_flag) {
if (!favourite_flag) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (i == 0) {
Intent intent = new Intent(MainActivity.this,tc.class);
startActivity(intent);
}
if (i == 1) {
Intent intent = new Intent(MainActivity.this,vc.class);
startActivity(intent);
}
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long l) {
if (position == 0) {
Intent intent = new Intent(MainActivity.this, cc.class);
intent.putExtra("EXTRAKEY_ID",l); // THIS ADDED
startActivity(intent);}
String name = getAllDataInCurrentLocale.getString(getAllDataInCurrentLocale.getColumnIndex(FAVOURITES_COL_NAME));
Toast.makeText(MainActivity.this, name+" Added To Favorite", Toast.LENGTH_SHORT).show();
return true;
}
});
}}
}
public class DB_Sqlite extends SQLiteOpenHelper {
public static final String BDname = "data.db";
public static final int DBVERSION = 1; /*<<<<< ADDED BUT NOT NEEDED */
public static final String TABLE_FAVOURITES = "mytable";
public static final String FAVOURITES_COL_ID = BaseColumns._ID; /*<<<< use the Android stock ID name*/
public static final String FAVOURITES_COL_NAME = "name";
public static final String FAVOURITES_COL_FAVOURITEFLAG = "favourite_flag"; /*<<<<< NEW COLUMN */
public DB_Sqlite(#Nullable Context context) {
super(context, BDname, null, DBVERSION /*<<<<< used constant above */);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_FAVOURITES + " (" +
FAVOURITES_COL_ID + " INTEGER PRIMARY KEY," + /*<<<<< AUTOINCREMENT NOT NEEDED AND IS INEFFICIENT */
FAVOURITES_COL_NAME + " TEXT, " +
FAVOURITES_COL_FAVOURITEFLAG + " INTEGER DEFAULT 0" + /*<<<<< COLUMN ADDED */
")");
/* CHANGES HERE BELOW loop adding all Resource names NOT VALUES */
ContentValues cv = new ContentValues();
for (String s: StringResourcesHandling.getAllStringResourceNames()) {
cv.clear();
cv.put(FAVOURITES_COL_NAME,s);
db.insert(TABLE_FAVOURITES,null,cv);
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVOURITES);
onCreate(db);
}
public boolean insertData(String name){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(FAVOURITES_COL_NAME, name);
long result = db.insert(TABLE_FAVOURITES,null, contentValues);
if (result == -1)
return false;
else
return true;
}
public Cursor getFavouriteRows(boolean favourites) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = FAVOURITES_COL_FAVOURITEFLAG + "=?";
String compare = "<1";
if (favourites) {
compare =">0";
}
return db.query(
TABLE_FAVOURITES,null,
FAVOURITES_COL_FAVOURITEFLAG + compare,
null,null,null,null
);
}
private int setFavourite(long id, boolean favourite_flag) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = FAVOURITES_COL_ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
ContentValues cv = new ContentValues();
cv.put(FAVOURITES_COL_FAVOURITEFLAG,favourite_flag);
return db.update(TABLE_FAVOURITES,cv,whereclause,whereargs);
}
public int setAsFavourite(long id) {
return setFavourite(id,true);
}
public int setAsNotFavourite(long id) {
return setFavourite(id, false);
}
/* Getting everything and make MatrixCursor VALUES from Resource names from Cursor with Resource names */
public Cursor getAllDataInCurrentLocale(Context context) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(TABLE_FAVOURITES,null,null,null,null,null,null);
if (csr.getCount() < 1) return csr;
MatrixCursor mxcsr = new MatrixCursor(csr.getColumnNames(),csr.getCount());
while (csr.moveToNext()) {
mxcsr.addRow(convertCursorRow(context,csr,new String[]{FAVOURITES_COL_NAME}));
}
csr.close();
return mxcsr;
}
public Cursor getDataInCurrentLocaleById(Context context, long id) {
SQLiteDatabase db = this.getWritableDatabase();
String wherepart = FAVOURITES_COL_ID + "=?";
String[] args = new String[]{String.valueOf(id)};
Cursor csr = db.query(TABLE_FAVOURITES,null,wherepart,args,null,null,null);
if (csr.getCount() < 1) return csr;
MatrixCursor mxcsr = new MatrixCursor(csr.getColumnNames(),csr.getCount());
while (csr.moveToNext()) {
mxcsr.addRow(convertCursorRow(context,csr,new String[]{FAVOURITES_COL_NAME}));
}
csr.close();
return mxcsr;
}
/* This getting columns from Cursor into String array (no BLOB handleing)*/
private String[] convertCursorRow(Context context, Cursor csr, String[] columnsToConvert) {
String[] rv = new String[csr.getColumnCount()];
for (String s: csr.getColumnNames()) {
boolean converted = false;
for (String ctc: columnsToConvert) {
if (csr.getType(csr.getColumnIndex(s)) == Cursor.FIELD_TYPE_BLOB) {
//........ would have to handle BLOB here if needed (another question if needed)
}
if (ctc.equals(s)) {
rv[csr.getColumnIndex(s)] = StringResourcesHandling.getStringByName(context,csr.getString(csr.getColumnIndex(s)));
converted = true;
}
} if (!converted) {
rv[csr.getColumnIndex(s)] = csr.getString(csr.getColumnIndex(s));
}
}
return rv;
}
}
public class cc extends AppCompatActivity {
String fav_name;
long fav_id;
DB_Sqlite dbSqlite;
SimpleCursorAdapter favourites_adapter;
ListView listView1;
ArrayList<String> arrayList1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cc);
listView1 = (ListView) findViewById(R.id.list_view1);
arrayList1 = new ArrayList<String>();
fav_id = getIntent().getLongExtra("EXTRAKEY_ID", 0);
if (fav_id == 0) {
}
dbSqlite = new DB_Sqlite(this);
Cursor cursor = dbSqlite.getDataInCurrentLocaleById(this, fav_id);
if (cursor.moveToFirst()) {
fav_name = cursor.getString(cursor.getColumnIndex(FAVOURITES_COL_NAME));
manageNonFavouritesListView();
}
cursor.close();
}
private void manageNonFavouritesListView() {
Cursor cursor = dbSqlite.getDataInCurrentLocaleById(this,fav_id);
if (favourites_adapter == null) {
favourites_adapter = new SimpleCursorAdapter(
this,
R.layout.textview,
cursor,
new String[]{FAVOURITES_COL_NAME},
new int[]{R.id.textview10},
0
);
listView1.setAdapter(favourites_adapter);
setListViewHandler(listView1,true);
} else {
favourites_adapter.swapCursor(cursor);
}
}
private void setListViewHandler(ListView listView1, boolean b) {
listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (fav_id == 1) {
Intent intent = new Intent(cc.this, tc.class);
startActivity(intent);
}
if (fav_id == 2) {
Intent intent = new Intent(cc.this, vc.class);
startActivity(intent);
}
}
});
}
}
public class StringResourcesHandling {
private static final String[] allowedStringResourcePrefixes = new String[]{"db_"};
private static boolean loaded = false;
private static Field[] fields = R.string.class.getFields();
private static ArrayList<String> allowedStringResourceNames = new ArrayList<>();
private static void loadStringResources() {
if (loaded) return;
for (Field f: fields) {
if (isResourceNameAllowedPrefix(f.getName())) {
allowedStringResourceNames.add(f.getName());
}
}
loaded = true;
}
private static boolean isResourceNameAllowedPrefix(String resourceName) {
if (allowedStringResourcePrefixes.length < 1) return true;
for (String s: allowedStringResourcePrefixes) {
if (resourceName.substring(0,s.length()).equals(s)) return true;
}
return false;
}
public static String getStringByName(Context context, String name) {
String rv = "";
boolean nameFound = false;
if (!loaded) {
loadStringResources();
}
for (String s: allowedStringResourceNames) {
if (s.equals(name)) {
nameFound = true;
break;
}
}
if (!nameFound) return rv;
return context.getString(context.getResources().getIdentifier(name,"string",context.getPackageName()));
}
public static List<String> getAllStringResourceNames() {
if (!loaded) {
loadStringResources();
}
return allowedStringResourceNames;
}
}
note: i get the data in 1st listview from strings.xml
please help me thank u in advance
You can add a column say 'isFavourite' in your db table which has list vew data. When user mark listitem as favourite, save the change in db table . When user navigates to favourite list populate the list from. db table with favourite filter in select query.
I suggest using SharedPreferences. You stated that your value gets overwritten. That won't be the case if you create multiple keys.
Example:
Say you have an ArrayList of String you want to pass from ClassA to ClassB:
ClassA:
for (int i = 0; i < list.size(); i++) {
sharedPref.edit().putString("text" + i, "abcde").apply();
}
ClassB:
for (int i = 0; i < list.size(); i++) {
sharedPref.getString("text" + i, null);
}
If you have problems with the listsize, you can also pass the listsize to sharedpref and retrieve it again.
the is my main page of the note app coding:
public class Note_mainActivity extends Fragment implements NoteRecyclerAdapter.NoteOnClick,LoaderManager.LoaderCallbacks<Cursor>{
private RecyclerView mRecycler8;
private NoteRecyclerAdapter mAdapter8;
private List savedNote;
private MyDbHelper myDbHelper;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView1 = inflater.inflate(R.layout.activity_note_main,container,false);
savedNote = new ArrayList<>();
mRecycler8 = (RecyclerView)rootView1.findViewById(R.id.show_note);
WrappedLinearLayoutManager linearLayoutManager = new WrappedLinearLayoutManager(getActivity());
mRecycler8.setLayoutManager(linearLayoutManager);
mAdapter8 = new NoteRecyclerAdapter(getActivity(),this);
mRecycler8.setItemAnimator(new SlideInDownAnimator());
mRecycler8.setHasFixedSize(true);
mAdapter8.setData(savedNote);
myDbHelper = new MyDbHelper(getActivity());
getActivity().getSupportLoaderManager().initLoader(0,null,this);
getActivity().getSupportLoaderManager().initLoader(1,null,this);
return rootView1;
}
#Override
public void containerOnClick(int t) {
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
if(id==0){
return new CursorLoader(getActivity(), NoteContract.NoteItemRow.CONTENT_URI,null,null,null,null);
}else{
return new CursorLoader(getActivity(), NoteContract.NoteItemRow.CONTENT_URI_NEWS,null,null,null,null);
}
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if(loader.getId() ==0){
if(data.moveToFirst()){
do{
int title1 = data.getColumnIndex(NoteContract.NoteItemRow.NOTE);
int date1 = data.getColumnIndex(NoteContract.NoteItemRow.DATE);
String title2 = data.getString(title1);
String date2 = data.getString(date1);
Notesetter setter1 = new Notesetter(title2,date2);
savedNote.add(setter1);
mAdapter8.notifyDataSetChanged();
}while(data.moveToNext());
}
}else{
/* if(data.moveToFirst()){
do{
int title2 = data.getColumnIndex(NoteContract.NoteItemRow.NEWS_TITLE);
int image_url = data.getColumnIndex(NoteContract.NoteItemRow.NEWS_IMAGE);
int source_url = data.getColumnIndex(NoteContract.NoteItemRow.NEWS_URL);
int date3 = data.getColumnIndex(NoteContract.NoteItemRow.NEWS_DATE);
String title3 = data.getString(title2);
String image_url_3 = data.getString(image_url);
String sources_url3 =data.getString(source_url);
String date_saved3 = data.getString(date3);
NewsNotesetter setter1 = new NewsNotesetter(title3,image_url_3,sources_url3,date_saved3);
savedNote.add(setter1);
mAdapter8.notifyDataSetChanged();
}while(data.moveToNext());
}*/
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
the is my content provider coding:
public class TheNewProvider extends ContentProvider {
private MyDbHelper myDbHelper;
private static final String LOG_TAG = TheNewProvider.class.getSimpleName();
private static final int SIMPLE_NOTE =100;
private static final int SIMPLE_NOTE_ID=101;
private static final int NEWS_NOTE =102;
private static final int NEWS_NOTE_ID =103;
private static final UriMatcher sUriMAtcher = new UriMatcher(UriMatcher.NO_MATCH);
static{
sUriMAtcher.addURI(NoteContract.CONTENT_AUTHORITY, NoteContract.path_note,SIMPLE_NOTE);
sUriMAtcher.addURI(NoteContract.CONTENT_AUTHORITY, NoteContract.path_note+"/#",SIMPLE_NOTE_ID);
sUriMAtcher.addURI(NoteContract.CONTENT_AUTHORITY, NoteContract.path_news,NEWS_NOTE);
sUriMAtcher.addURI(NoteContract.CONTENT_AUTHORITY, NoteContract.path_news+"/#",NEWS_NOTE_ID);
}
#Override
public boolean onCreate() {
myDbHelper = new MyDbHelper(getContext());
return true;
}
#Nullable
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, #Nullable String selection, #Nullable String[] selectionArgs, #Nullable String sortOrder) {
SQLiteDatabase sqLiteDatabase = myDbHelper.getReadableDatabase();
Cursor cursor;
int match = sUriMAtcher.match(uri);
switch (match){
case SIMPLE_NOTE:
cursor = sqLiteDatabase.query(NoteContract.NoteItemRow.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
break;
case SIMPLE_NOTE_ID:
selection = NoteContract.NoteItemRow._ID+"=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
cursor = sqLiteDatabase.query(NoteContract.NoteItemRow.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
break;
case NEWS_NOTE:
cursor = sqLiteDatabase.query(NoteContract.NoteItemRow.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
break;
case NEWS_NOTE_ID:
selection = NoteContract.NoteItemRow._ID+"=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
cursor = sqLiteDatabase.query(NoteContract.NoteItemRow.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
break;
default:
throw new IllegalArgumentException("Insertion is not supported" +uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), NoteContract.NoteItemRow.CONTENT_URI);
cursor.setNotificationUri(getContext().getContentResolver(), NoteContract.NoteItemRow.CONTENT_URI_NEWS);
return cursor;
}
#Nullable
#Override
public String getType(#NonNull Uri uri) {
return null;
}
#Nullable
#Override
public Uri insert(#NonNull Uri uri, #Nullable ContentValues values) {
final int match = sUriMAtcher.match(uri);
switch (match){
case SIMPLE_NOTE:
return save(uri,values);
case NEWS_NOTE:
return saveNews(uri,values);
default:
throw new IllegalArgumentException("Insertion is not supported" +uri);
}
}
#Override
public int delete(#NonNull Uri uri, #Nullable String selection, #Nullable String[] selectionArgs) {
return 0;
}
#Override
public int update(#NonNull Uri uri, #Nullable ContentValues values, #Nullable String selection, #Nullable String[] selectionArgs) {
final int match = sUriMAtcher.match(uri);
switch (match){
case SIMPLE_NOTE:
return UpdateNote(uri,values,selection,selectionArgs);
case SIMPLE_NOTE_ID:
selection = NoteContract.NoteItemRow._ID+"=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
return UpdateNote(uri,values,selection,selectionArgs);
case NEWS_NOTE:
return UpdateNews(uri,values,selection,selectionArgs);
case NEWS_NOTE_ID:
selection = NoteContract.NoteItemRow._ID+"=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
return UpdateNews(uri,values,selection,selectionArgs);
default:
throw new IllegalArgumentException("Insertion is not supported" +uri);
}
}
private Uri save(Uri url,ContentValues values){
String name = values.getAsString(NoteContract.NoteItemRow.TITLE);
if(name == null){
throw new IllegalArgumentException("no title");
}
String notes = values.getAsString(NoteContract.NoteItemRow.NOTE);
if(notes == null){
throw new IllegalArgumentException("no note");
}
String date = values.getAsString(NoteContract.NoteItemRow.DATE);
if(date == null){
throw new IllegalArgumentException("no date");
}
SQLiteDatabase db = myDbHelper.getWritableDatabase();
long id = db.insert(NoteContract.NoteItemRow.TABLE_NAME,null,values);
if(id==-1){
Log.v("the note","saved");
}
getContext().getContentResolver().notifyChange(url,null);
return ContentUris.withAppendedId(url,id);
}
private Uri saveNews(Uri url,ContentValues values){
String name = values.getAsString(NoteContract.NoteItemRow.NEWS_TITLE);
if(name == null){
throw new IllegalArgumentException("no title");
}
String notes = values.getAsString(NoteContract.NoteItemRow.NEWS_URL);
if(notes == null){
throw new IllegalArgumentException("no note");
}
String date = values.getAsString(NoteContract.NoteItemRow.NEWS_DATE);
if(date == null){
throw new IllegalArgumentException("no date");
}
String image_url = values.getAsString(NoteContract.NoteItemRow.NEWS_IMAGE);
if(image_url == null){
throw new IllegalArgumentException("no image");
}
SQLiteDatabase db = myDbHelper.getWritableDatabase();
long id = db.insert(NoteContract.NoteItemRow.TABLE_NAME,null,values);
if(id==-1){
Log.v("the note","saved");
}
getContext().getContentResolver().notifyChange(url,null);
return ContentUris.withAppendedId(url,id);
}
private int UpdateNote(Uri url,ContentValues values,String selection,String[]selectionArgs){
String name = values.getAsString(NoteContract.NoteItemRow.TITLE);
if(name == null){
throw new IllegalArgumentException("no title");
}
String notes = values.getAsString(NoteContract.NoteItemRow.NOTE);
if(notes == null){
throw new IllegalArgumentException("no note");
}
String date = values.getAsString(NoteContract.NoteItemRow.DATE);
if(date == null){
throw new IllegalArgumentException("no date");
}
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int rowUpdated = db.update(NoteContract.NoteItemRow.TABLE_NAME,values,selection,selectionArgs);
if(rowUpdated!=0){
getContext().getContentResolver().notifyChange(url,null);
}
return rowUpdated;
}
private int UpdateNews(Uri url,ContentValues values,String selection,String[]selectionArgs){
String name = values.getAsString(NoteContract.NoteItemRow.NEWS_TITLE);
if(name == null){
throw new IllegalArgumentException("no title");
}
String notes = values.getAsString(NoteContract.NoteItemRow.NEWS_URL);
if(notes == null){
throw new IllegalArgumentException("no note");
}
String date = values.getAsString(NoteContract.NoteItemRow.NEWS_DATE);
if(date == null){
throw new IllegalArgumentException("no date");
}
String image_url = values.getAsString(NoteContract.NoteItemRow.NEWS_IMAGE);
if(image_url == null){
throw new IllegalArgumentException("no image");
}
SQLiteDatabase db = myDbHelper.getWritableDatabase();
int rowUpdated = db.update(NoteContract.NoteItemRow.TABLE_NAME,values,selection,selectionArgs);
if(rowUpdated!=0){
getContext().getContentResolver().notifyChange(url,null);
}
return rowUpdated;
}
}
this is my databasehelper class:
public class MyDbHelper extends SQLiteOpenHelper {
private static final int DATABSE_VERSION = 1;
private static final String DATABASE_NAME ="simpleTable.db";
private static final String createDatabase = "CREATE TABLE "
+ NoteItemRow.TABLE_NAME
+"("+NoteItemRow._ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+NoteItemRow.TITLE+" TEXT, "
+NoteItemRow.NOTE+" TEXT NOT NULL, "
+NoteItemRow.DATE+" TEXT NOT NULL);";
private static final String createDatabase2 = "CREATE TABLE "
+ NoteItemRow.TABLE_NAME2
+"("+NoteItemRow._ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+NoteItemRow.NEWS_TITLE+" TEXT, "
+NoteItemRow.NEWS_URL+" TEXT NOT NULL, "
+NoteItemRow.NEWS_DATE+" TEXT NOT NULL, "
+NoteItemRow.NEWS_IMAGE+" TEXT NOT NULL);";
private static final String UPGRADE_DB = "DROP TABLE IF EXISTS"+ NoteItemRow.TABLE_NAME;
private static final String UPGRADE_DB2 = "DROP TABLE IF EXISTS"+ NoteItemRow.TABLE_NAME2;
public MyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABSE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(createDatabase);
db.execSQL(createDatabase2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(UPGRADE_DB);
db.execSQL(UPGRADE_DB2);
onCreate(db);
}
}
this is my editnote class:
public class EditActivity extends AppCompatActivity {
private EditText mTitle,mNote;
String title1;
String note_detail;
private MyDbHelper mDbHelper;
private Uri cureenturi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_editor);
mTitle = (EditText)findViewById(R.id.title_note);
mNote = (EditText)findViewById(R.id.take_note);
}
private void savenote(){
title1 = mTitle.getText().toString().trim();
note_detail = mNote.getText().toString().trim();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
Date date = new Date();
String date_cur = sdf.format(date);
mDbHelper = new MyDbHelper(this);
ContentValues values = new ContentValues();
values.put(NoteContract.NoteItemRow.TITLE,title1);
values.put(NoteContract.NoteItemRow.NOTE,note_detail);
values.put(NoteContract.NoteItemRow.DATE,date_cur);
cureenturi = getContentResolver().insert(NoteContract.NoteItemRow.CONTENT_URI,values);
if(cureenturi == null){
return;
}else {
int updateRow = getContentResolver().update(cureenturi,values,null,null);
if(updateRow==0){
}else {
Toast.makeText(EditActivity.this,"note updated",Toast.LENGTH_SHORT).show();
}
}
Uri newUriContent = getContentResolver().insert(NoteContract.NoteItemRow.CONTENT_URI,values);
if(newUriContent==null){
Toast.makeText(EditActivity.this,"can't created the note",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(EditActivity.this,"note inserted",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
if(TextUtils.isEmpty(title1)&&TextUtils.isEmpty(note_detail)){
finish();
}else{
savenote();
}
}
when i launch the app the error log show this error:
Process: com.example.user.inforting, PID: 5490
java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
at com.example.user.inforting.Note_mainActivity.onLoadFinished(Note_mainActivity.java:72)
at com.example.user.inforting.Note_mainActivity.onLoadFinished(Note_mainActivity.java:30)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:476)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:444)
at android.support.v4.content.Loader.deliverResult(Loader.java:126)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:105)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:37)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:252)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:80)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:485)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:502)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
someone can help to correct me. your help is appreciate.
As i see program error logs it says:
'boolean android.database.Cursor.moveToFirst()' on a null object reference
And also MoveToFirst method,Move the cursor to the first row.
So as my opinion,You have not initiated your SQLiteDataBase Well or You lose your reference Object of DataBase through your program.
hope it would be helpful.
I have been building a simple note app and have successfully SQlite database and loaders to load data on a listview. Next thing I want to do is make loader automatically reload when I add, change or delete a note in database but don't know how. I've search but mainly tutorials are for Content provider, I read this: http://developer.android.com/reference/android/content/AsyncTaskLoader.html#q=addAll
but not understand much because they use BroadcastReceiver to get change on sd card.
Im all ears to any suggestion and thanks for any help in advance!
this is my code: WhiteNote.java
public class WhiteNote extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<NoteItems>> {
private NoteDatabase note_database;
private int i=0;
public Context context;
public NoteListAdapter noteListAdapter;
public ListView note_listview_container;
public SQLiteDatabase note_sqldb;
public Cursor c;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.white_note, container, false);
context=getActivity();
note_database = new NoteDatabase(context);
final EditText text_ed_1;
final EditText text_ed_2;
Button button_addNote;
Button button_listallNote;
Button button_delallNote;
text_ed_1 = (EditText)rootView.findViewById(R.id.textedit1);
text_ed_2 = (EditText)rootView.findViewById(R.id.textedit2);
button_addNote = (Button)rootView.findViewById(R.id.button1);
button_listallNote = (Button)rootView.findViewById(R.id.button2);
button_delallNote = (Button)rootView.findViewById(R.id.button3);
note_listview_container=(ListView)rootView.findViewById(R.id.note_listview);
noteListAdapter=new NoteListAdapter(context, new ArrayList<NoteItems>());
note_database.open();
getLoaderManager().initLoader(0, null,WhiteNote.this);
note_database.close();
button_addNote.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
note_database.open();
note_database.createData(text_ed_1.getText().toString(),text_ed_2.getText().toString());
//i++;
note_database.close();
}
});
button_listallNote.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
note_database.open();
note_database.get_NoteListAdapter();
note_listview_container.setAdapter(note_database.dbnoteListAdapter);
note_database.close();
//note_list.setText(ds);
}
});
button_delallNote.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
note_database.open();
note_database.deleteAllNote();
note_database.close();
}
});
return rootView;
}
#Override
public Loader<ArrayList<NoteItems>> onCreateLoader(int id, Bundle args) {
return new NoteItemsLoader(context,note_database);
}
#Override
public void onLoadFinished(Loader<ArrayList<NoteItems>> loader,
ArrayList<NoteItems> data) {
note_listview_container.setAdapter(new NoteListAdapter(context, data));
}
#Override
public void onLoaderReset(Loader<ArrayList<NoteItems>> loader) {
note_listview_container.setAdapter(null);
}
}
class NoteItemsLoader extends AsyncTaskLoader<ArrayList<NoteItems>> {
private ArrayList<NoteItems> loader_noteitems= new ArrayList<NoteItems>();
private NoteDatabase loader_db;
public NoteItemsLoader(Context context, NoteDatabase db) {
super(context);
loader_db = db;
loader_noteitems=loader_db.get_NoteListArray(loader_noteitems,loader_db);
}
#Override
protected void onStartLoading() {
if (loader_noteitems != null) {
deliverResult(loader_noteitems); // Use the cache
}
else
forceLoad();
}
#Override
protected void onStopLoading() {
cancelLoad();
}
#Override
public ArrayList<NoteItems> loadInBackground() {
loader_db.open();
ArrayList<NoteItems> note_items = new ArrayList<NoteItems>();
loader_db.get_NoteListArray(note_items,loader_db);
loader_db.close();
return note_items;
}
#Override
public void deliverResult(ArrayList<NoteItems> data) {
if (isReset()) {
if (data != null) {
onReleaseResources(data);
}
}
ArrayList<NoteItems> oldNotes = loader_noteitems;
loader_noteitems = data;
if (isStarted()) {
super.deliverResult(data);
}
if (oldNotes != null) {
onReleaseResources(oldNotes);
}
}
#Override
protected void onReset() {
super.onReset();
onStopLoading();
loader_noteitems = null;
}
#Override
public void onCanceled(ArrayList<NoteItems> data) {
super.onCanceled(data);
loader_noteitems = null;
}
protected void onReleaseResources(ArrayList<NoteItems> data) {}
}
my NoteDatabase.java
public class NoteDatabase {
private static final String DATABASE_NAME = "DB_NOTE";
private static final int DATABASE_VERSION = 1;
public static final String TABLE_NOTE = "NOTE";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_TOPIC = "Topic";
public static final String COLUMN_NOTECONTENT = "Content";
public static final String COLUMN_NAME = "Name";
public NoteListAdapter dbnoteListAdapter;
private static Context my_context;
static SQLiteDatabase note_sqldb;
private OpenHelper noteopenHelper;
public NoteDatabase(Context c){
NoteDatabase.my_context = c;
}
public NoteDatabase open() throws SQLException{
noteopenHelper = new OpenHelper(my_context);
note_sqldb = noteopenHelper.getWritableDatabase();
return this;
}
public void close(){
noteopenHelper.close();
}
public long createData(String chude_note, String noidung_note) {
ContentValues cv = new ContentValues();
cv.put(COLUMN_TOPIC, chude_note);
cv.put(COLUMN_NOTECONTENT, noidung_note);
cv.put(COLUMN_NAME, "by Black");
return note_sqldb.insert(TABLE_NOTE, null, cv);
}
public String getData() {
String[] columns = new String[] {COLUMN_ID,COLUMN_TOPIC,COLUMN_NOTECONTENT,COLUMN_NAME};
Cursor c = note_sqldb.query(TABLE_NOTE, columns, null, null, null, null, null);
/*if(c==null)
Log.v("Cursor", "C is NULL");*/
String result="";
int iRow = c.getColumnIndex(COLUMN_ID);
int iTopic = c.getColumnIndex(COLUMN_TOPIC);
int iContent = c.getColumnIndex(COLUMN_NOTECONTENT);
int iOwner = c.getColumnIndex(COLUMN_NAME);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result +" \n"+ c.getString(iRow)
+ "\n - Topic: " + c.getString(iTopic)
+ "\n - Content: " + c.getString(iContent)
+ "\n - Owner: " + c.getString(iOwner) + "\n";
}
c.close();
//Log.v("Result", result);
return result;
}
public Cursor selectQuery(String query) {
Cursor c1 = null;
try {
if (note_sqldb.isOpen()) {
note_sqldb.close();
}
note_sqldb = noteopenHelper.getWritableDatabase();
c1 = note_sqldb.rawQuery(query, null);
} catch (Exception e) {
System.out.println("DATABASE ERROR " + e);
}
return c1;
}
public void get_NoteListAdapter() {
ArrayList<NoteItems> noteList = new ArrayList<NoteItems>();
noteList.clear();
open();
String[] columns = new String[] {NoteDatabase.COLUMN_ID,NoteDatabase.COLUMN_TOPIC,NoteDatabase.COLUMN_NOTECONTENT,NoteDatabase.COLUMN_NAME};
note_sqldb = noteopenHelper.getWritableDatabase();
Cursor c1 = note_sqldb.query(NoteDatabase.TABLE_NOTE, columns, null, null, null, null, null);
int iRow = c1.getColumnIndex(NoteDatabase.COLUMN_ID);
int iTopic = c1.getColumnIndex(NoteDatabase.COLUMN_TOPIC);
int iContent = c1.getColumnIndex(NoteDatabase.COLUMN_NOTECONTENT);
int iOwner = c1.getColumnIndex(NoteDatabase.COLUMN_NAME);
for(c1.moveToFirst(); !c1.isAfterLast(); c1.moveToNext()){
NoteItems one_rowItems = new NoteItems();
one_rowItems.set_rowTopic(c1.getString(iTopic));
one_rowItems.set_rowContent(c1.getString(iContent));
one_rowItems.set_rowOwner(c1.getString(iOwner));
noteList.add(one_rowItems);
}
c1.close();
close();
dbnoteListAdapter = new NoteListAdapter(my_context, noteList);
}
public ArrayList<NoteItems> get_NoteListArray(ArrayList<NoteItems> noteitems_list,NoteDatabase db) {
noteitems_list.clear();
db.open();
String[] columns = new String[] {NoteDatabase.COLUMN_ID,NoteDatabase.COLUMN_TOPIC,NoteDatabase.COLUMN_NOTECONTENT,NoteDatabase.COLUMN_NAME};
note_sqldb = noteopenHelper.getWritableDatabase();
Cursor c1 = note_sqldb.query(NoteDatabase.TABLE_NOTE, columns, null, null, null, null, null);
int iRow = c1.getColumnIndex(NoteDatabase.COLUMN_ID);
int iTopic = c1.getColumnIndex(NoteDatabase.COLUMN_TOPIC);
int iContent = c1.getColumnIndex(NoteDatabase.COLUMN_NOTECONTENT);
int iOwner = c1.getColumnIndex(NoteDatabase.COLUMN_NAME);
for(c1.moveToFirst(); !c1.isAfterLast(); c1.moveToNext()){
NoteItems one_rowItems = new NoteItems();
one_rowItems.set_rowTopic(c1.getString(iTopic));
one_rowItems.set_rowContent(c1.getString(iContent));
one_rowItems.set_rowOwner(c1.getString(iOwner));
noteitems_list.add(one_rowItems);
}
c1.close();
db.close();
return noteitems_list;
}
public int deleteNote(String topic) {
return note_sqldb.delete(TABLE_NOTE, COLUMN_TOPIC + "='" + topic + "'", null);
}
public int deleteAllNote() {
return note_sqldb.delete(TABLE_NOTE, null, null);
}
}
Next thing I want to do is make loader automatically reload when I add, change or delete a note in database but don't know how.
There is no way to make that happen automatically. Either:
Something tells the loader that the data changed, so it knows to reload, or
The Loader is the one that is doing the "add, change, or delete a note in database"
I went with the latter approach with my CWAC-LoaderEx project and its SQLiteCursorLoader.
I have a SQLLite DB that stores an ftp site's login information (name,address,username,password,port,passive). When an item (site) is clicked in the list, it's supposed to load the name, address, username, password etc. into the corresponding EditTexts. What's happening is that the password value is getting loaded into the address EditText and the address isn't getting loaded anywhere.
My Activity's addRecord function looks like this:
public void addRecord() {
long newId = myDb.insertRow(_name, _address, _username, _password,
_port, _passive);
Cursor cursor = myDb.getRow(newId);
displayRecordSet(cursor);
}
The order of the parameters in insertRow() correspond to the order in my DBAdapter, however when I change the order of the parameters I can get the address and password values to end up in the correct EditTexts, just never all of them at once. What am I doing wrong?
public class DBAdapter {
// ///////////////////////////////////////////////////////////////////
// Constants & Data
// ///////////////////////////////////////////////////////////////////
// For logging:
private static final String TAG = "DBAdapter";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
/*
* CHANGE 1:
*/
// TODO: Setup your fields here:
public static final String KEY_NAME = "name";
public static final String KEY_ADDRESS = "address";
public static final String KEY_USERNAME = "username";
public static final String KEY_PASSWORD = "password";
public static final String KEY_PORT = "port";
public static final String KEY_PASSIVE = "passive";
// TODO: Setup your field numbers here (0 = KEY_ROWID, 1=...)
public static final int COL_NAME = 1;
public static final int COL_ADDRESS = 2;
public static final int COL_USERNAME = 3;
public static final int COL_PASSWORD = 4;
public static final int COL_PORT = 5;
public static final int COL_PASSIVE = 6;
public static final String[] ALL_KEYS = new String[] { KEY_ROWID, KEY_NAME,
KEY_ADDRESS, KEY_USERNAME, KEY_PASSWORD, KEY_PORT, KEY_PASSIVE };
// DB info: it's name, and the table we are using (just one).
public static final String DATABASE_NAME = "Sites";
public static final String DATABASE_TABLE = "SiteTable";
// Track DB version if a new version of your app changes the format.
public static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE_SQL = "create table "
+ DATABASE_TABLE
+ " ("
+ KEY_ROWID
+ " integer primary key autoincrement, "
/*
* CHANGE 2:
*/
// TODO: Place your fields here!
// + KEY_{...} + " {type} not null"
// - Key is the column name you created above.
// - {type} is one of: text, integer, real, blob
// (http://www.sqlite.org/datatype3.html)
// - "not null" means it is a required field (must be given a
// value).
// NOTE: All must be comma separated (end of line!) Last one must
// have NO comma!!
+ KEY_NAME + " string not null, " + KEY_ADDRESS
+ " string not null, " + KEY_USERNAME + " string not null, "
+ KEY_PASSWORD + " string not null, " + KEY_PORT
+ " integer not null," + KEY_PASSIVE + " integer not null"
// Rest of creation:
+ ");";
// Context of application who uses us.
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
// ///////////////////////////////////////////////////////////////////
// Public methods:
// ///////////////////////////////////////////////////////////////////
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to the database.
public long insertRow(String name, String address, String user,
String pass, int port, int passive) {
/*
* CHANGE 3:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_ADDRESS, address);
initialValues.put(KEY_USERNAME, user);
initialValues.put(KEY_PASSWORD, pass);
initialValues.put(KEY_PORT, port);
initialValues.put(KEY_PASSIVE, passive);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null,
null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null,
null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, String address,
String username, String password, int port, int passive) {
String where = KEY_ROWID + "=" + rowId;
/*
* CHANGE 4:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_ADDRESS, address);
newValues.put(KEY_USERNAME, username);
newValues.put(KEY_PASSWORD, password);
newValues.put(KEY_PORT, port);
newValues.put(KEY_PASSIVE, passive);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
// ///////////////////////////////////////////////////////////////////
// Private Helper Classes:
// ///////////////////////////////////////////////////////////////////
/**
* Private class which handles database creation and upgrading. Used to
* handle low-level database access.
*/
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
public class SiteManager extends Activity {
DBAdapter myDb;
public FTPClient mFTPClient = null;
public EditText etSitename;
public EditText etAddress;
public EditText etUsername;
public EditText etPassword;
public EditText etPort;
public CheckBox cbPassive;
public ListView site_list;
public Button clr;
public Button test;
public Button savesite;
public Button close;
public Button connect;
String _name;
String _address;
String _username;
String _password;
int _port;
int _passive = 0;
List<FTPSite> model = new ArrayList<FTPSite>();
ArrayAdapter<FTPSite> adapter;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.site_manager);
site_list = (ListView) findViewById(R.id.siteList);
adapter = new SiteAdapter(this, R.id.ftpsitename, R.layout.siterow,
model);
site_list.setAdapter(adapter);
etSitename = (EditText) findViewById(R.id.dialogsitename);
etAddress = (EditText) findViewById(R.id.dialogaddress);
etUsername = (EditText) findViewById(R.id.dialogusername);
etPassword = (EditText) findViewById(R.id.dialogpassword);
etPort = (EditText) findViewById(R.id.dialogport);
cbPassive = (CheckBox) findViewById(R.id.dialogpassive);
close = (Button) findViewById(R.id.closeBtn);
connect = (Button) findViewById(R.id.connectBtn);
clr = (Button) findViewById(R.id.clrBtn);
test = (Button) findViewById(R.id.testBtn);
savesite = (Button) findViewById(R.id.saveSite);
addListeners();
openDb();
displayRecords();
}
public void addListeners() {
connect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent returnResult = new Intent();
returnResult.putExtra("ftpname", _name);
returnResult.putExtra("ftpaddress", _address);
returnResult.putExtra("ftpusername", _username);
returnResult.putExtra("ftppassword", _password);
returnResult.putExtra("ftpport", _port);
setResult(RESULT_OK, returnResult);
finish();
}
});
test.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
_name = etSitename.getText().toString();
_address = etAddress.getText().toString();
_username = etUsername.getText().toString();
_password = etPassword.getText().toString();
_port = Integer.parseInt(etPort.getText().toString());
if (cbPassive.isChecked()) {
_passive = 1;
} else {
_passive = 0;
}
boolean status = ftpConnect(_address, _username, _password,
_port);
ftpDisconnect();
if (status == true) {
Toast.makeText(SiteManager.this, "Connection Succesful",
Toast.LENGTH_LONG).show();
savesite.setVisibility(0);
} else {
Toast.makeText(SiteManager.this,
"Connection Failed:" + status, Toast.LENGTH_LONG)
.show();
}
}
});
savesite.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
_name = etSitename.getText().toString();
_address = etAddress.getText().toString();
_username = etUsername.getText().toString();
_password = etPassword.getText().toString();
_port = Integer.parseInt(etPort.getText().toString());
if (cbPassive.isChecked()) {
_passive = 1;
} else {
_passive = 0;
}
addRecord();
adapter.notifyDataSetChanged();
}
});
close.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
clr.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
clearAll();
}
});
site_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
final FTPSite item = (FTPSite) parent
.getItemAtPosition(position);
String tmpname = item.getName();
String tmpaddress = item.getAddress();
String tmpuser = item.getUsername();
String tmppass = item.getPassword();
int tmpport = item.getPort();
String tmp_port = Integer.toString(tmpport);
int tmppassive = item.isPassive();
etSitename.setText(tmpname);
etAddress.setText(tmpaddress);
etUsername.setText(tmpuser);
etPassword.setText(tmppass);
etPort.setText(tmp_port);
if (tmppassive == 1) {
cbPassive.setChecked(true);
} else {
cbPassive.setChecked(false);
}
}
});
}
public void addRecord() {
long newId = myDb.insertRow(_name, _username, _address,_password,
_port, _passive);
Cursor cursor = myDb.getRow(newId);
displayRecordSet(cursor);
}
private void openDb() {
myDb = new DBAdapter(this);
myDb.open();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
closeDb();
}
private void closeDb() {
myDb.close();
}
public void displayRecords() {
Cursor cursor = myDb.getAllRows();
displayRecordSet(cursor);
}
protected void displayRecordSet(Cursor c) {
// String msg = "";
if (c.moveToFirst()) {
do {
// int id = c.getInt(0);
_name = c.getString(1);
_address = c.getString(2);
_username = c.getString(3);
_password = c.getString(4);
_port = c.getInt(5);
FTPSite sitesFromDB = new FTPSite();
sitesFromDB.setName(_name);
sitesFromDB.setAddress(_address);
sitesFromDB.setUsername(_username);
sitesFromDB.setAddress(_password);
sitesFromDB.setPort(_port);
sitesFromDB.setPassive(_passive);
model.add(sitesFromDB);
adapter.notifyDataSetChanged();
} while (c.moveToNext());
}
c.close();
}
public void clearAll() {
myDb.deleteAll();
adapter.notifyDataSetChanged();
}
public boolean ftpConnect(String host, String username, String password,
int port) {
try {
mFTPClient = new FTPClient();
// connecting to the host
mFTPClient.connect(host, port);
// now check the reply code, if positive mean connection success
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
// login using username & password
boolean status = mFTPClient.login(username, password);
mFTPClient.enterLocalPassiveMode();
return status;
}
} catch (Exception e) {
// Log.d(TAG, "Error: could not connect to host " + host );
}
return false;
}
public boolean ftpDisconnect() {
try {
mFTPClient.logout();
mFTPClient.disconnect();
return true;
} catch (Exception e) {
// Log.d(TAG,
// "Error occurred while disconnecting from ftp server.");
}
return false;
}
class SiteAdapter extends ArrayAdapter<FTPSite> {
private final List<FTPSite> objects;
private final Context context;
public SiteAdapter(Context context, int resource,
int textViewResourceId, List<FTPSite> objects) {
super(context, R.id.ftpsitename, R.layout.siterow, objects);
this.context = context;
this.objects = objects;
}
/** #return The number of items in the */
public int getCount() {
return objects.size();
}
public boolean areAllItemsSelectable() {
return false;
}
/** Use the array index as a unique id. */
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.siterow, parent, false);
TextView textView = (TextView) rowView
.findViewById(R.id.ftpsitename);
textView.setText(objects.get(position).getName());
return (rowView);
}
}
I think you should try to use :
int keyNameIndex = c.getColumnIndex(DBAdapter.KEY_NAME);
_name = c.getString(keyNameIndex);
Instead of using direct number.I am not sure it cause the bug, but it gonna be better exercise. Hope it's help.
There is mismatch in your arguments see below
public long insertRow(String name, String address, String user,
String pass, int port, int passive) {
public void addRecord() {
long newId = myDb.insertRow(_name, _username, _address,_password,
_port, _passive);
Cursor cursor = myDb.getRow(newId);
displayRecordSet(cursor);
}
you are passing username to address and address to user
This is embarrassing. I had sitesFromDB.setAddress(_password); instead of sitesFromDB.setPassword(_password);
This is the code:
TodoTable.java:
public class TodoTable {
// Database table
public static final String TABLE_TODO = "todo";
public static final String COLUMN_ID_U = "_id";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_SUMMARY = "summary";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_SATZE = "satze";
// Database creation SQL statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_TODO
+ "("
+ COLUMN_ID_U + " integer primary key autoincrement, "
+ COLUMN_CATEGORY + " text not null, "
+ COLUMN_SUMMARY + " text not null, "
+ COLUMN_DESCRIPTION + " text not null, "
+ COLUMN_SATZE + " text not null"
+ ");";
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
Log.w(TodoTable.class.getName(), "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);
onCreate(database);
}}
TodoDetailAktivity.java:
public class TodoDetailActivity extends Activity {
private Spinner mCategory;
private EditText mTitleText;
private EditText mBodyText;
private EditText mSatzText;
private EditText mPauseText;
private EditText mWDHText;
private EditText mGewichtText;
private Uri todoUri;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.todo_edit);
mCategory = (Spinner) findViewById(R.id.category);
mTitleText = (EditText) findViewById(R.id.todo_edit_summary);
mBodyText = (EditText) findViewById(R.id.todo_edit_description);
mSatzText = (EditText) findViewById(R.id.editTextsatz);
Button confirmButton = (Button) findViewById(R.id.todo_edit_button);
Bundle extras = getIntent().getExtras();
// Check from the saved Instance
todoUri = (bundle == null) ? null : (Uri) bundle
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
// Or passed from the other activity
if (extras != null) {
todoUri = extras
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
fillData(todoUri);
}
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(mTitleText.getText().toString())) {
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
}
private void fillData(Uri uri) {
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
}
mTitleText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
mBodyText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
mSatzText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));
// Always close the cursor
cursor.close();
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String category = (String) mCategory.getSelectedItem();
String summary = mTitleText.getText().toString();
String description = mBodyText.getText().toString();
String satze = mSatzText.getText().toString();
// Only save if either summary or description
// is available
if (description.length() == 0 && summary.length() == 0 && satze.length() == 0) {
return;
}
ContentValues values = new ContentValues();
values.put(TodoTable.COLUMN_CATEGORY, category);
values.put(TodoTable.COLUMN_SUMMARY, summary);
values.put(TodoTable.COLUMN_DESCRIPTION, description);
values.put(TodoTable.COLUMN_SATZE, satze);
if (todoUri == null) {
// New todo
todoUri = getContentResolver().insert(MyTodoContentProvider.CONTENT_URI, values);
} else {
// Update todo
getContentResolver().update(todoUri, values, null, null);
}
}
private void makeToast() {
Toast.makeText(TodoDetailActivity.this, "Please maintain a summary",
Toast.LENGTH_LONG).show();
}}
TodosOverviewAktivity.java:
/*
* TodosOverviewActivity displays the existing todo items
* in a list
*
* You can create new ones via the ActionBar entry "Insert"
* You can delete existing ones via a long press on the item
*/
#TargetApi(11)
public class TodosOverviewActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
// private Cursor cursor;
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.todo_list);
this.getListView().setDividerHeight(1);
fillData();
registerForContextMenu(getListView());
}
// Create the menu based on the XML defintion
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.listmenu, menu);
return true;
}
// Reaction to the menu selection
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.insert:
createTodo();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/"
+ info.id);
getContentResolver().delete(uri, null, null);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
private void createTodo() {
Intent i = new Intent(this, TodoDetailActivity.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
// Opens the second activity if an entry is clicked
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
// Activity returns an result if called with startActivityForResult
startActivityForResult(i, ACTIVITY_EDIT);
}
// Called with the result of the other activity
// requestCode was the origin request code send to the activity
// resultCode is the return code, 0 is everything is ok
// intend can be used to get data
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
}
private void fillData() {
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY };
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from,
to, 0);
setListAdapter(adapter);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
// Creates a new loader after the initLoader () call
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { TodoTable.COLUMN_ID_U, TodoTable.COLUMN_SUMMARY };
CursorLoader cursorLoader = new CursorLoader(this,
MyTodoContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}}
MyTodoContentProvider.java:
public class MyTodoContentProvider extends ContentProvider {
// database
private TodoDatabaseHelper database;
// Used for the UriMacher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";
private static final String BASE_PATH = "todos";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/todos";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/todo";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
}
#Override
public boolean onCreate() {
database = new TodoDatabaseHelper(getContext());
return false;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Uisng SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
// Check if the caller has requested a column which does not exists
checkColumns(projection);
// Set the table
queryBuilder.setTables(TodoTable.TABLE_TODO);
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case TODOS:
break;
case TODO_ID:
// Adding the ID to the original query
queryBuilder.appendWhere(TodoTable.COLUMN_ID_U + "="
+ uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
// Make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
long id = 0;
switch (uriType) {
case TODOS:
id = sqlDB.insert(TodoTable.TABLE_TODO, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case TODOS:
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, selection,
selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
TodoTable.COLUMN_ID_U + "=" + id,
null);
} else {
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
TodoTable.COLUMN_ID_U + "=" + id
+ " and " + selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case TODOS:
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
selection,
selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
TodoTable.COLUMN_ID_U + "=" + id,
null);
} else {
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
TodoTable.COLUMN_ID_U + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection) {
String[] available = { TodoTable.COLUMN_CATEGORY,
TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_SATZE, TodoTable.COLUMN_ID_U };
if (projection != null) {
HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
// Check if all columns which are requested are available
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
}
TodoDatabaseHelper.java:
public class TodoDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "todotable.db";
private static final int DATABASE_VERSION = 1;
public TodoDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Method is called during creation of the database
#Override
public void onCreate(SQLiteDatabase database) {
TodoTable.onCreate(database);
}
// Method is called during an upgrade of the database,
// e.g. if you increase the database version
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
TodoTable.onUpgrade(database, oldVersion, newVersion);
}
}
The most of code I have copied from: http://www.vogella.com/articles/AndroidSQLite/article.html#todo
But I get the errormessage (LogCat):
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.de.vogella.android.todos/com.example.de.vogella.android.todos.TodoDetailActivity}: java.lang.IllegalArgumentException: column 'satze' does not exist
Can anybody find a mistake in the code?
Thanks
Here is your bug:
private void fillData(Uri uri) {
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY }; //add satze here!
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
}
mTitleText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
mBodyText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
mSatzText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));//you don't have satze in projection!
// Always close the cursor
cursor.close();
}
}
You are trying to read TodoTable.COLUMN_SATZE but you forgot about it in projection:
Please change this line:
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
into this:
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY, TodoTable.COLUMN_SATZE };
In your CREATE TABLE statement you need spaces between your column names and column types.