简体   繁体   中英

Access data in SQLite Database in fragment

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM