Data Not Returning


#1

Hello!

I’m having a blast trying to work through this book, but have recently came up on an issue I can’t seem to resolve by myself. After Listing 12.11, I’ve tried running the program to see the dates changed and updated…but do not. I’m able to see the DatePicker, but it does not update whatsoever. I believe I’ve followed the instructions to a T and have checked against the solutions, so any help or comments are appreciated!!

Here is my relevant code as it is…
CrimeFragment.java

[code]import java.util.Date;
import java.util.UUID;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;

public class CrimeFragment extends Fragment {
public static final String EXTRA_CRIME_ID =
com.bignerdranch.android.criminalintent.crime.id”;

private static final String DIALOG_DATE = "date";
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(EXTRA_CRIME_ID, crimeID);
	
	CrimeFragment fragment = new CrimeFragment();
	fragment.setArguments(args);
	 
	return fragment;
}


@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	UUID crimeID = (UUID)getArguments().getSerializable(EXTRA_CRIME_ID);
	
	mCrime = CrimeLab.get(getActivity()).getCrime(crimeID); //used to fetch Crime from CrimeLab. CrimeLab.get(...) method requires a Context object, so CrimeFragment passes the CrimeActivity
	}

private void updateDate() {
	mDateButton.setText(mCrime.getDate().toString());
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
	View v = inflater.inflate(R.layout.fragment_crime, parent, false);
	
	mTitleField = (EditText)v.findViewById(R.id.crime_title);
	mTitleField.setText(mCrime.getTitle());
	mTitleField.addTextChangedListener(new TextWatcher() {
		public void onTextChanged(CharSequence c, int start, int before, int count) {
		mCrime.setTitle(c.toString());
	}
	
	public void beforeTextChanged(CharSequence c, int start, int count, int after) {
		//left blank
	}
	
	public void afterTextChanged(Editable c) {
		//left blank
	}
	});
	

	
	mDateButton = (Button)v.findViewById(R.id.crime_date);
	updateDate();
	
	mDateButton.setOnClickListener(new View.OnClickListener() {
		public void onClick(View v) {
			FragmentManager fm = getActivity()
					.getSupportFragmentManager();
			DatePickerFragment dialog = DatePickerFragment
					.newInstance(mCrime.getDate());
			dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
			dialog.show(fm, DIALOG_DATE);
			
		}
	});
	

	
	mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
	mSolvedCheckBox.setChecked(mCrime.isSolved());
	mSolvedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
		public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
			//Set the crime's solved property
			mCrime.setSolved(isChecked);
		}
		});
				
	return v;
}



@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
	if(resultCode != Activity.RESULT_OK) return;
	if(resultCode == REQUEST_DATE) {
		Date date = (Date)data
			.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
		mCrime.setDate(date);
		updateDate();
	}
}

}[/code]

and DatePickerFragment

[code]import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;

public class DatePickerFragment extends DialogFragment {
public static final String EXTRA_DATE = “com.bignerdranch.android.criminal.date”;

private Date mDate;

public static DatePickerFragment newInstance(Date date) {
	Bundle args = new Bundle();
	args.putSerializable(EXTRA_DATE, date);
	
	DatePickerFragment fragment = new DatePickerFragment();
	fragment.setArguments(args);
	
	return fragment;
}

private void sendResult(int resultCode) {
	if(getTargetFragment() == null)
		return;
	
	Intent i = new Intent();
	i.putExtra(EXTRA_DATE, mDate);
	
	getTargetFragment()
	.onActivityResult(getTargetRequestCode(), resultCode, i);
	
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
	mDate = (Date)getArguments().getSerializable(EXTRA_DATE);
	
	//Create a Calendar to get the year, month, and day
	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);
	
	
	View v = getActivity().getLayoutInflater()
			.inflate(R.layout.dialog_date, null);
	
	DatePicker datePicker = (DatePicker)v.findViewById(R.id.dialog_date_datePicker);
	datePicker.init(year, month, day, new OnDateChangedListener() {
		public void onDateChanged(DatePicker view, int year, int month, int day) {
			//Translate year, month, day into a Date object using a calendar
			mDate = new GregorianCalendar(year, month, day).getTime();
			
			//Update argument to preserve selected value on rotation
			getArguments().putSerializable(EXTRA_DATE, mDate);
		}
	});
	
	return new AlertDialog.Builder(getActivity()) //Pass a Context into the AlertDialog.Builder constructor which returns and instance of AlertDialog.Builder
		.setView(v)
		.setTitle(R.string.date_picker_title)
		.setPositiveButton(
				android.R.string.ok, 
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						sendResult(Activity.RESULT_OK);
			}
		})
		.create();
}

}
[/code]
Let me know if you need to see any other classes. I appreciate any help. Thanks in advance!


#2

public class CrimeFragment extends Fragment {
public static final String EXTRA_CRIME_ID =
com.bignerdranch.android.criminalintent.crime.id”;

you have crime.id instead of crime_id
I don’t fully understand this but I believe the underscore is required for a valid statement


#3

Thanks for looking it over, SecondCareer. I corrected it to an underscore, but it’s still not producing a change, which is curious. Good catch though. The frustration continues!


#4

That’s all that jumped out at me. FWIW I did get the entire chapter to work by following the examples, so I did not have any strange errors with dates. Working on the challenges now.


#5

I would suggest putting in some breakpoints to make sure onActivityResult() is getting called and that is has the data you are expecting.


#6

Hi, sorry this is not a help but I am having exactly the same problem… did you every figure this out?


#7

Hey guys, I was having the same issue. After setting breakpoints and debugging the program, I found that the new date I was selecting in the dialog was being carried with the intent and back into CriminalFragment. In fact, it was even used to set the “date” object inside CriminalFragment. However, after the call to setDate, mDate’s value remained unchanged.

What happened was, I originally used Eclipse to generate the getters and setters for my Crime class. Forgot to tell it to ignore the “m” in the beginner of the instance variable names, and at some point I had gone through and manually corrected them…or so I thought. I missed a statement in the setDate method, so essentially instead of the proper implementation which is:

public void setDate(Date date) {
this.mDate = date;
}

I had instead:

public void setDate(Date date) {
this.mDate = mDate;
}

There was a yellow warning in Eclipse saying it would have no effect, but I guess I just never noticed it. So make sure you check and make sure your getters and setters are actually defined correctly!


#8

hey raysyd, I think you have the same problem as me:

in CrimeFragment.java you have:

@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode != Activity.RESULT_OK) return; if(resultCode == REQUEST_DATE) { Date date = (Date)data .getSerializableExtra(DatePickerFragment.EXTRA_DATE); mCrime.setDate(date); updateDate(); } }
resultCode is never the same as REQUEST_DATE. That part of your code will never reach.

You should change the line

to

That’s it!