Hi
I’ve trying to figure out what is my error but I couldn’t find it.
I have created an additional Dialog to let the user chose whether to change date or time.
But when I try to change the Date I can’t send the result back.
In order to call the Activity which will host the DateDialog I use startActivityForResult from the aditional dialog and I set the result by using getActivity().setResult(resultCode, intent);
followed by getActivity().finish();
in order to finish the activity.
The dateDialog is displayed properly, I show all the code involved:
Crime Fragment(Here I only modified how I call the OptionFragment which let me chose what to change : date/time)
public class CrimeFragment extends Fragment {
private static final String ARG_CRIME_ID = "crime_id";
private static final String DIALOG_DATE = "DiaglogDate";
private static final int REQUEST_DATE = 0;
private Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox;
public static CrimeFragment newInstance(UUID crimeId) {
Bundle args = new Bundle();
args.putSerializable(ARG_CRIME_ID, crimeId);
CrimeFragment fragment = new CrimeFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID uuidCorrectWay = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
mCrime = CrimeLab.get(getActivity())
.getCrime(uuidCorrectWay);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_crime, container, false);
mTitleField = (EditText) v.findViewById(R.id.crime_title);
mTitleField.setText(mCrime.getTitle());
mTitleField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mCrime.setTitle(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
// This one too is left blank.
}
});
mDateButton = (Button) v.findViewById(R.id.crime_date);
updateDate();
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager fragmentManager = getFragmentManager();
// OptionDialog
OptionDialogFragment optionDialogFragment = OptionDialogFragment.newInstance(mCrime.getDate());
optionDialogFragment.setTargetFragment(CrimeFragment.this,REQUEST_OPTION);
optionDialogFragment.show(fragmentManager,TAG_OPTION);
}
});
mSolvedCheckBox = (CheckBox) v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setChecked(mCrime.isSolved());
mSolvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
mCrime.setSolved(b);
}
});
return v;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
Date date;
switch (requestCode){
case REQUEST_DATE:
date = DatePickerFragment.getDate(data);
mCrime.setDate(date);
updateDate();
break;
case REQUEST_OPTION:
date = OptionDialogFragment.getDate(data);
mCrime.setDate(date);
updateDate();
break;
}
}
private void updateDate() {
mDateButton.setText(mCrime.getDate().toString());
}
private static final String TAG_OPTION = "com.bignerdranch.criminalintent.crimefragment.option";
private final int REQUEST_OPTION = 1;
OptionDialog Is the custom dialog used to choose to change Time or Date
public class OptionDialogFragment extends DialogFragment {
private static final String ARG_DATE = "date";
public static OptionDialogFragment newInstance(Date date) {
Bundle bundle = new Bundle();
bundle.putSerializable(ARG_DATE, date);
OptionDialogFragment optionDialogFragment = new OptionDialogFragment();
optionDialogFragment.setArguments(bundle);
return optionDialogFragment;
}
private static final int REQUEST_TIME = 0;
private static final int REQUEST_DATE = 1;
private static final String TAG_DIALOG_TIME = "com.bignerdranch.criminalintent.optiondialog.time";
private static final String TAG_DIALOG_DATE = "com.bignerdranch.criminalintent.optiondialog.date";
private Date mDate;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
mDate = (Date) getArguments().getSerializable(ARG_DATE);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("What do you want to Edit?")
.setPositiveButton("Time", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
TimePickerFragment timePickerFragment = TimePickerFragment.newInstance(mDate);
timePickerFragment.setTargetFragment(OptionDialogFragment.this, REQUEST_TIME);
FragmentManager fragmentManager = getFragmentManager();
timePickerFragment.show(fragmentManager, TAG_DIALOG_TIME);
}
})
.setNeutralButton("Date", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// Challenge 2 Call DatePickerActivity
Intent intent = DatePickerActivity.newIntent(getContext(),mDate);
startActivityForResult(intent,REQUEST_DATE_ACTIVITY);
}
});
return builder.create();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
if (data == null) {
return;
}
switch (requestCode) {
case REQUEST_TIME:
mDate = TimePickerFragment.getDate(data);
break;
case REQUEST_DATE:
mDate = DatePickerFragment.getDate(data);
break;
case REQUEST_DATE_ACTIVITY:
mDate = DatePickerFragment.getDate(data);
break;
default:
Log.d(TAG, "No idea which activity called");
}
sendResult(mDate);
}
private void sendResult(Date date) {
Intent data = new Intent();
data.putExtra(EXTRA_RETURN_DATE, date);
getTargetFragment()
.onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, data);
}
private static final String TAG = OptionDialogFragment.class.getName();
private static final String EXTRA_RETURN_DATE = "com.bignerdranch.criminalintent.finaldate";
private static final int REQUEST_DATE_ACTIVITY = 2;
public static Date getDate(Intent data){
return (Date) data.getSerializableExtra(EXTRA_RETURN_DATE);
}
}
DatePickerActivity which host the date fragment show below
public class DatePickerActivity extends SingleFragmentActivity {
private static final String EXTRA_DATE = "com.bignerdranch.criminalintent.extra.date.activity";
public static Intent newIntent(Context context, Date date) {
Intent intent = new Intent(context, DatePickerActivity.class);
intent.putExtra(EXTRA_DATE, date);
return intent;
}
@Override
protected Fragment createFragment() {
Date date = (Date) getIntent().getSerializableExtra(EXTRA_DATE);
return DatePickerFragment.newInstance(date);
}
}
And finally the DatePickerFragment used to modify the date.
public class DatePickerFragment extends DialogFragment {
private static final String ARG_DATE = "date";
public static final String EXTRA_DATE = "com.bignerdranch.criminalintent.date";
private DatePicker mDatePicker;
private Button mOkButton;
private Date mDate;
public static DatePickerFragment newInstance(Date date) {
Bundle args = new Bundle();
args.putSerializable(ARG_DATE, date);
DatePickerFragment datePickerFragment = new DatePickerFragment();
datePickerFragment.setArguments(args);
return datePickerFragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
mDate = (Date) getArguments().getSerializable(ARG_DATE);
View view = inflater.inflate(R.layout.dialog_date, container, false);
final Calendar calendar = Calendar.getInstance();
calendar.setTime(mDate);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
mDatePicker = (DatePicker) view.findViewById(R.id.dialog_date_picker);
mDatePicker.init(year, month, day, null);
mOkButton = (Button) view.findViewById(R.id.ok_date_button);
mOkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int year = mDatePicker.getYear();
int month = mDatePicker.getMonth();
int day = mDatePicker.getDayOfMonth();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
calendar.set(year, month, day, hour, minute);
sendResult(Activity.RESULT_OK, calendar.getTime());
}
});
return view;
}
private void sendResult(int resultCode, Date date) {
Intent intent = new Intent();
intent.putExtra(EXTRA_DATE, date);
if (getTargetFragment() == null) {
// Created from Activity
getActivity()
.setResult(
resultCode
, intent);
getActivity().finish();
} else {
// Created as Fragment not from Activity
Log.d(TAG,"TargetFragment =" + getTargetFragment().toString());
getTargetFragment() // Here we Obtain the Fragment who invoked this one
.onActivityResult // Here we call the method onActivityResult of the fragment
(getTargetRequestCode() // Obtain the TargetRequestCode
, resultCode // ResultCode
, intent); // intent
}
}
private static final String TAG = DatePickerFragment.class.toString();
private static final String DIALOG_TIME = "dialog_time";
private static final int REQUEST_TIME = 1;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
Log.d(TAG, "Result != ok");
return;
}
if (requestCode == REQUEST_TIME) {
// EXTRACT USEFUL DATA FROM INTENT
mDate = TimePickerFragment.getDate(data);
sendResult(Activity.RESULT_OK, mDate);
}
}
public static Date getDate(Intent data) {
return (Date) data.getSerializableExtra(EXTRA_DATE);
}
}
I have tried using several break points in different parts of the program but after DatePickerFragment uses setResult and finishing the host activity neither onActivityResult from OptionDialogFragment nor CrimeFragment is called even though I try implementing calling super.onActivityResult, I haven’t include it because I tested after.
With the code shown I can set up a different time.
I believe the problem is in how I call DatePickerActivity from OptionDialog or how I setResult but unfortunately I can’t find the issue.