我创建了一个设置提醒的应用。为此,我使用了两个片段:一个用于显示提醒列表,另一个用于创建和编辑特定提醒。
当我编辑提醒时,出现问题,显示从SQLite数据库保存的数据(保存似乎可以正常工作)。我设法通过使用参数从提醒列表中发送提醒来显示提醒的标题。但是,我认为直接从编辑片段访问数据库更有意义。我已经尝试过其他方法,但是我认为我没有正确访问ReminderProvider类。我试图在ReminderProvider类中创建用于处理数据库的方法getTitel,但是我将需要创建该类的实例,这是我迷路的地方,因为我没有正确地实例化它(我得到一个NPE)。 我还想访问数据库以显示之前保存的日期和时间(我还无法使用参数解决该问题)。
通知我也有同样的问题:我在指定的时间收到通知,但是通知中没有显示提醒的标题。然后,我可以将提醒访问到编辑片段中,但是然后我也看不到已经保存的数据,这也是我想直接从数据库中加载它的另一个原因。
我在这里进行了很多搜索,但没有找到答案(或者无法将其转移到我的案子中)。我仍然是初学者,所以我将不胜感激。谢谢! (并且很抱歉,如果这是一个非常愚蠢的问题...)
我的类ReminderEditFragment和ReminderProvider的代码如下(我还有以下类:ReminderListFragment以显示所有提醒,ReminderListActivity以处理ListFragment,ReminderEditActivity,ReminderManager,OnAlarmReceiver,OnBootReceiver,ReminderService,als以及日期的片段-和时间选择器)
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();
}
}
}
答案 0 :(得分:0)
我设法不是通过使用constructur来解决问题的,而是通过使用content_uri向ReminderEditFragment类添加三个字段中每个字段的查询方法来解决此问题的:
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;
}
也许这可以帮助遇到类似问题的人。