i am new to android programming and i am working on a project from the big nerd ranch guide to android programming. i posted about a problem i was having a few days ago and it turns out that i had made some pretty obvious mistakes in the debugging process. this was pointed out to me on this site. unfortunately i am still not clear on a solution to my problem. what happens is when i click an item in my recyclerview the app gives me a pop up stating that it has stopped. what is supposed to happen is a new activity containing a single fragment should be launched. after stepping through my code in the debugger i found a null pointer excetption when i call my newIntent() method. however from what i can see it looks like all the variables are defined and it is only when i click step into all the way down to where the Bundle() constructor that i see a message "Method threw 'java.lang.NullPointerException' exception. Cannot evaluate android.os.Bundle.toString()". so im guessing that this is called by the Intent() constructor somewhere? apperantly it is line 50 in Bundle.java that throws the exception.
as for my code i am posting it here as well. this is the CrimeListActivity.java:
and here is the CrimeListFragment:
package com.bignerdranch.android.criminalintent;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.menu.ExpandedMenuView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.IllegalFormatCodePointException;
import java.util.List;
public class CrimeListFragment extends Fragment{
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
mCrimeRecyclerView = (RecyclerView) view.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}//end onCreate
private void updateUI(){
CrimeLab crimeLab = CrimeLab.get(getActivity()); //workds here but not in crimeFragment
List<Crime> crimes = crimeLab.getCrimes();
if (mAdapter == null){
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
}else {
mAdapter.notifyDataSetChanged();
}
}//end updateUI()
private class CrimeHolder extends RecyclerView.ViewHolder implements
View.OnClickListener{
private TextView mTitleTextView;
private TextView mDateTextView;
private Crime mCrime;
private ImageView mSolvedImageView;
@Override
public void onClick(View view){
try {
Intent intent = CrimePagerActivity.newIntent(getActivity(), mCrime.getId()); // this is the line i set the breakpoint and stepped into
startActivity(intent);
}catch(Exception e){
Log.d("ONCLICK", e.toString());
}
}//end onCLick()
public CrimeHolder(LayoutInflater inflater, ViewGroup parent){
super(inflater.inflate(R.layout.list_item_crime, parent, false));
itemView.setOnClickListener(this);
mTitleTextView = (TextView) itemView.findViewById(R.id.crime_title);
mDateTextView = (TextView) itemView.findViewById(R.id.crime_date);
mSolvedImageView = (ImageView) itemView.findViewById(R.id.crime_solved);
}//end constructor
public void bind(Crime crime){
mCrime = crime;
mTitleTextView.setText(crime.getTitle());
mDateTextView.setText(mCrime.getDate().toString());
mSolvedImageView.setVisibility(crime.isSolved() ? View.VISIBLE : View.GONE);
}//end bind()
}//end CrimeHolder inner Class
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder>{
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes){
mCrimes = crimes;
}//end constructor
@Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType){
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new CrimeHolder(layoutInflater, parent);
}// end onCreateViewHolder
@Override
public void onBindViewHolder(CrimeHolder holder, int position){
Crime crime = mCrimes.get(position);
holder.bind(crime);
}
@Override
public int getItemCount(){
return mCrimes.size();
}
}//end CrimeAdapter inner Class
}//end CrimeListFragment class
and here is the Crime class and the CrimeLab Class
package com.bignerdranch.android.criminalintent;
import java.util.Date;
import java.util.UUID;
public class Crime {
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public Date getDate() {
return mDate;
}
public boolean isSolved() {
return mSolved;
}
public void setTitle(String title) {
mTitle = title;
}
public void setDate(Date date) {
mDate = date;
}
public void setSolved(boolean solved) {
mSolved = solved;
}
private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved;
public Crime(){
mId = UUID.randomUUID();
mDate = new Date();
}
}
package com.bignerdranch.android.criminalintent;
import android.content.Context;
import java.util.ArrayList;
import java.util.List ;
import java.util.UUID;
public class CrimeLab {
private static CrimeLab sCrimeLab;
private List<Crime> mCrimes;
public static CrimeLab get(Context context){
if(sCrimeLab == null){
sCrimeLab = new CrimeLab(context);
}
return sCrimeLab;
}//end get()
private CrimeLab(Context context){
}//end constructor
public List<Crime> getCrimes(){
mCrimes = new ArrayList<>();
for (int i = 0; i < 100; i++){
Crime crime = new Crime();
crime.setTitle("Crime #" + i);
crime.setSolved(i % 2 == 0); //every other crime will be checked!
mCrimes.add(crime);
}
return mCrimes;
}//end getCrimes
public Crime getCrime(UUID id){
for (Crime crime : mCrimes){
if (crime.getId().equals(id)){
return crime;
}
}
return null;
}//end getCrime()
}//end CrimeLab class
and last but not least the CrimePagerActivity class:
public class CrimePagerActivity extends AppCompatActivity {
private static final String EXTRA_CRIME_ID =
"com.bignerdranch.android.criminalintent.crime_id";
private ViewPager mViewPager;
private List<Crime> mCrimes;
public static Intent newIntent(Context packageContext, UUID crimeId){
Intent intent = new Intent(packageContext, CrimePagerActivity.class);
intent.putExtra(EXTRA_CRIME_ID, crimeId);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime_pager);
UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);
mViewPager = (ViewPager) findViewById(R.id.crime_view_pager);
mCrimes = CrimeLab.get(this).getCrimes();
FragmentManager fragmentManager = getSupportFragmentManager();
mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
@Override
public Fragment getItem(int position) {
Crime crime = mCrimes.get(position);
return CrimeFragment.newInstance(crime.getId());
}
@Override
public int getCount() {
return mCrimes.size();
}
});
}// end onCreate()
}//end crimePagerAtivity class
when i step into the call to CrimePagerActivity.newIntent() i eventually get to the line where the method is defined, but when i keep stepping into the code i eventually get to the line in Bundle.java where Bundle() calls super() and apparently that is where the nullpointerexception is thrown. not sure if i am just making some dumb mistake somewhere but i just cant figure it out. please let me know if you can find any mistakes or point me in the right direction. thanks.
here is the stack trace:
05-02 19:32:42.220 8395-8395/com.bignerdranch.android.criminalintent E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bignerdranch.android.criminalintent, PID: 8395
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.bignerdranch.android.criminalintent.Crime.getTitle()' on a null object reference
at com.bignerdranch.android.criminalintent.CrimeFragment.onCreateView(CrimeFragment.java:51)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19857)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:689)
at android.view.View.measure(View.java:19857)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2275)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1366)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
here is the CrimeFragment Class as well:
package com.bignerdranch.android.criminalintent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.LayoutInflaterCompat;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
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.EditText;
import java.util.UUID;
import static com.bignerdranch.android.criminalintent.CrimePagerActivity.EXTRA_CRIME_ID;
public class CrimeFragment extends Fragment{
private static final String ARG_CRIME_ID = "crimeId";
private Crime mCrime;
private UUID crimeId;
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);
args.getSerializable(EXTRA_CRIME_ID);
CrimeFragment fragment = new CrimeFragment();
fragment.setArguments(args);
return fragment;
}*/
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
UUID crimeID = (UUID) getActivity().getIntent().getSerializableExtra(EXTRA_CRIME_ID);
mCrime = CrimeLab.get(getActivity()).getCrime(crimeID);
}//end onCreate()
@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()); // <-------- NULL pointer here
mTitleField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mCrime.setTitle(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});//end textChangedListener
mSolvedCheckBox = (CheckBox) v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setChecked(mCrime.isSolved());
mSolvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCrime.setSolved(isChecked);
}
});//end checkedchangedlistener
mDateButton = (Button) v.findViewById(R.id.crime_date);
mDateButton.setText(mCrime.getDate().toString());
mDateButton.setEnabled(false);
return v;
}//end onCreateView()
}//end class
here is the log containing the mCrimes List data:
05-03 18:48:27.663 5991-5991/com.bignerdranch.android.criminalintent D/mCrimes: [com.bignerdranch.android.criminalintent.Crime@3a456fd, com.bignerdranch.android.criminalintent.Crime@4284ff2, com.bignerdranch.android.criminalintent.Crime@4b1f643, com.bignerdranch.android.criminalintent.Crime@3a074c0, com.bignerdranch.android.criminalintent.Crime@b6465f9, com.bignerdranch.android.criminalintent.Crime@867793e, com.bignerdranch.android.criminalintent.Crime@ef3b39f, com.bignerdranch.android.criminalintent.Crime@a781cec, com.bignerdranch.android.criminalintent.Crime@87c68b5, com.bignerdranch.android.criminalintent.Crime@5ddeb4a, com.bignerdranch.android.criminalintent.Crime@269eabb, com.bignerdranch.android.criminalintent.Crime@4401bd8, com.bignerdranch.android.criminalintent.Crime@8d7db31, com.bignerdranch.android.criminalintent.Crime@1977216, com.bignerdranch.android.criminalintent.Crime@5427797, com.bignerdranch.android.criminalintent.Crime@3871d84, com.bignerdranch.android.criminalintent.Crime@39df96d, com.bignerdranch.android.criminalintent.Crime@39099a2, com.bignerdranch.android.criminalintent.Crime@8acf633, com.bignerdranch.android.criminalintent.Crime@31a8df0, com.bignerdranch.android.criminalintent.Crime@12dbf69, com.bignerdranch.android.criminalintent.Crime@502adee, com.bignerdranch.android.criminalintent.Crime@736c28f, com.bignerdranch.android.criminalintent.Crime@b32991c, com.bignerdranch.android.criminalintent.Crime@6d9e925, com.bignerdranch.android.criminalintent.Crime@76fbafa, com.bignerdranch.android.criminalintent.Crime@ce6f8ab, com.bignerdranch.android.criminalintent.Crime@d5e2b08, com.bignerdranch.android.criminalintent.Crime@264f2a1, com.bignerdranch.android.criminalintent.Crime@6e8cc6, com.bignerdranch.android.criminalintent.Crime@51a7487, com.bignerdranch.android.criminalintent.Crime@32eefb4, com.bignerdranch.android.criminalintent.Crime@13d17dd, com.bignerdranch.android.criminalintent.Crime@636af52, com.bignerdranch.android.criminalintent.Crime@a1fd223, com.bignerdranch.android.criminalintent.Crime@ba55320, com.bignerdranch.android.criminalintent.Crime@f7854d9, com.bignerdranch.android.criminalintent.Crime@8ec6e9e, com.bignerdranch.android.criminalintent.Crime@2936d7f, com.bignerdranch.android.criminalintent.Crime@35c814c, com.bignerdranch.android.criminalintent.Crime@a906595, com.bignerdranch.android.criminalintent.Crime@4acd6aa, com.bignerdranch.android.criminalintent.Crime@87b629b, com.bignerdranch.android.criminalintent.Crime@3766638, com.bignerdranch.android.criminalintent.Crime@3dec611, com.bignerdranch.android.criminalintent.Crime@859b376, com.bignerdranch.android.criminalintent.Crime@6238d77, com.bignerdranch.android.criminalintent.Crime@347ade4, com.bignerdranch.android.criminalintent.Crime@ed8b24d, com.bignerdranch.android.criminalintent.Crime@d259102, com.bignerdranch.android.criminalintent.Crime@4b98a13, com.bignerdranch.android.criminalintent.Crime@8c3c450, com.bignerdranch.android.criminalintent.Crime@70b2649, com.bignerdranch.android.criminalintent.Crime@adfbb4e, com.bignerdranch.android.criminalintent.Crime@8a8b46f, com.bignerdranch.android.criminalintent.Crime@3a8d57c, com.bignerdranch.android.criminalintent.Crime@9d6de05, com.bignerdranch.android.criminalintent.Crime@5003e5a, com.bignerdranch.android.criminalintent.Crime@7b6288b, com.bignerdranch.android.criminalintent.Crime@f6bcd68, com.bignerdranch.android.criminalintent.Crime@fec5581, com.bignerdranch.android.criminalintent.Crime@c73e626, com.bignerdranch.android.criminalintent.Crime@4dcc267, com.bignerdranch.android.criminalintent.Crime@7e45814, com.bignerdranch.android.criminalintent.Crime@287c8bd, com.bignerdranch.android.criminalintent.Crime@2283eb2, com.bignerdranch.android.criminalintent.Crime@de91e03, com.bignerdranch.android.criminalintent.Crime@cb8e180, com.bignerdranch.android.criminalintent.Crime@86d33b9, com.bignerdranch.android.criminalintent.Crime@65793fe, com.bignerdranch.android.criminalintent.Crime@6d5975f, com.bignerdranch.android.criminalintent.Crime@f8a95ac, com.bignerdranch.android.criminalintent.Crime@6a45275, com.bignerdranch.android.criminalintent.Cri
05-03 18:48:35.962 5991-5991/com.bignerdranch.android.criminalintent D/mCrimes: [com.bignerdranch.android.criminalintent.Crime@823ce6c, com.bignerdranch.android.criminalintent.Crime@3abfc35, com.bignerdranch.android.criminalintent.Crime@d10b8ca, com.bignerdranch.android.criminalintent.Crime@ea86a3b, com.bignerdranch.android.criminalintent.Crime@2b56558, com.bignerdranch.android.criminalintent.Crime@62d26b1, com.bignerdranch.android.criminalintent.Crime@e99796, com.bignerdranch.android.criminalintent.Crime@3a96f17, com.bignerdranch.android.criminalintent.Crime@1c77f04, com.bignerdranch.android.criminalintent.Crime@bbc7ced, com.bignerdranch.android.criminalintent.Crime@99f9722, com.bignerdranch.android.criminalintent.Crime@f4be5b3, com.bignerdranch.android.criminalintent.Crime@ebf8770, com.bignerdranch.android.criminalintent.Crime@370fae9, com.bignerdranch.android.criminalintent.Crime@cc4036e, com.bignerdranch.android.criminalintent.Crime@d952a0f, com.bignerdranch.android.criminalintent.Crime@1edaa9c, com.bignerdranch.android.criminalintent.Crime@cd55ca5, com.bignerdranch.android.criminalintent.Crime@5b0e87a, com.bignerdranch.android.criminalintent.Crime@b84582b, com.bignerdranch.android.criminalintent.Crime@678d488, com.bignerdranch.android.criminalintent.Crime@b641e21, com.bignerdranch.android.criminalintent.Crime@9551246, com.bignerdranch.android.criminalintent.Crime@cee4c07, com.bignerdranch.android.criminalintent.Crime@10ab134, com.bignerdranch.android.criminalintent.Crime@5c37b5d, com.bignerdranch.android.criminalintent.Crime@ac00cd2, com.bignerdranch.android.criminalintent.Crime@419a1a3, com.bignerdranch.android.criminalintent.Crime@53baca0, com.bignerdranch.android.criminalintent.Crime@cc17059, com.bignerdranch.android.criminalintent.Crime@c6e241e, com.bignerdranch.android.criminalintent.Crime@71ab4ff, com.bignerdranch.android.criminalintent.Crime@5bef2cc, com.bignerdranch.android.criminalintent.Crime@60fb915, com.bignerdranch.android.criminalintent.Crime@a54642a, com.bignerdranch.android.criminalintent.Crime@eefa21b, com.bignerdranch.android.criminalintent.Crime@b4e6fb8, com.bignerdranch.android.criminalintent.Crime@6bfd191, com.bignerdranch.android.criminalintent.Crime@8ac98f6, com.bignerdranch.android.criminalintent.Crime@c5c44f7, com.bignerdranch.android.criminalintent.Crime@e56cf64, com.bignerdranch.android.criminalintent.Crime@97ef5cd, com.bignerdranch.android.criminalintent.Crime@3814e82, com.bignerdranch.android.criminalintent.Crime@e863993, com.bignerdranch.android.criminalintent.Crime@f637dd0, com.bignerdranch.android.criminalintent.Crime@c9221c9, com.bignerdranch.android.criminalintent.Crime@af9d0ce, com.bignerdranch.android.criminalintent.Crime@750dbef, com.bignerdranch.android.criminalintent.Crime@a4aa6fc, com.bignerdranch.android.criminalintent.Crime@3921185, com.bignerdranch.android.criminalintent.Crime@8662bda, com.bignerdranch.android.criminalintent.Crime@979480b, com.bignerdranch.android.criminalintent.Crime@1936e8, com.bignerdranch.android.criminalintent.Crime@8e74101, com.bignerdranch.android.criminalintent.Crime@80b2ba6, com.bignerdranch.android.criminalintent.Crime@c7259e7, com.bignerdranch.android.criminalintent.Crime@3bed994, com.bignerdranch.android.criminalintent.Crime@b05ec3d, com.bignerdranch.android.criminalintent.Crime@3ae5c32, com.bignerdranch.android.criminalintent.Crime@200ad83, com.bignerdranch.android.criminalintent.Crime@579fb00, com.bignerdranch.android.criminalintent.Crime@16a0f39, com.bignerdranch.android.criminalintent.Crime@9e2097e, com.bignerdranch.android.criminalintent.Crime@9969edf, com.bignerdranch.android.criminalintent.Crime@903c72c, com.bignerdranch.android.criminalintent.Crime@55365f5, com.bignerdranch.android.criminalintent.Crime@e113f8a, com.bignerdranch.android.criminalintent.Crime@d7049fb, com.bignerdranch.android.criminalintent.Crime@27c2a18, com.bignerdranch.android.criminalintent.Crime@a416c71, com.bignerdranch.android.criminalintent.Crime@d4bca56, com.bignerdranch.android.criminalintent.Crime@56f8ad7, com.bignerdranch.android.criminalintent.Crime@615cfc4, com.bignerdranch.android.criminalintent.Crim