在片段中访问SQLite数据库中的数据

时间:2019-01-04 17:40:47

标签: java sqlite android-fragments

我创建了一个设置提醒的应用。为此,我使用了两个片段:一个用于显示提醒列表,另一个用于创建和编辑特定提醒。

当我编辑提醒时,出现问题,显示从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();
    }
  }

}

1 个答案:

答案 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;
}

也许这可以帮助遇到类似问题的人。