SQLite数据库中的java访问数据片段
我创建了一个应用程序来设置提醒。为此,我使用了两个片段:一个用于显示提醒列表,另一个用于创建和编辑特定提醒
编辑提醒时,显示SQLite数据库中已保存的数据时出现问题(保存似乎可以正常工作)。通过使用参数从提醒列表中发送提醒,我成功地显示了提醒的标题。但是,我认为从编辑片段直接访问数据库更有意义。我已经尝试了不同的方法,但是我认为我没有正确地访问RememberProvider类。我试图在ReminderProvider类中创建一个用于处理数据库的方法getTitel,但是我需要创建一个类的实例,这就是我丢失的地方,因为我没有正确地实例化它(我得到一个NPE)。 我还想访问数据库以显示以前保存的日期和时间(我还不能用参数解决这个问题)
我对通知有同样的问题:我在指定的时间收到通知,但通知没有显示提醒的标题。然后我可以将提醒访问到编辑片段中,但是我也看不到已经保存的数据——这也是我想直接从数据库加载它的另一个原因
我在这里搜索了很多,但没有找到答案(或者无法将其转移到我的案例中)。我还是一个初学者,所以我会感谢任何帮助。谢谢(如果这是一个非常愚蠢的问题,我很抱歉…)
我的ReminderEditFragment和ReminderProvider类代码如下(我还有以下类:显示所有提醒的ReminderListFragment、处理ListFragment的ReminderListActivity、ReminderManager、OnArmReceiver、OnBootReceiver、ReminderService、als以及日期和时间选择器的片段)
提醒编辑片段:
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);
}
}
提醒提供者:
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();
}
}
}
# 1 楼答案
我设法解决了这个问题,方法不是使用构造函数,而是使用content_uri为三个字段中的每一个添加查询方法,并将其添加到RememberEditFragment类中:
也许这对有类似问题的人有帮助