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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.