2nd Challenge


#1

Hi,

I think we should add another logic to delete a photo file in deleteCrime(Crime) of CrimeLab when a crime itself is deleted.

Thanks,


#2

I have the same thought, indeed.

I messed a bit with the code to get back to a more or less consistent state after adding the feature to delete a photo from a crime instance (taking rid of the original file inside the filesystem) and I came up with this solution:

On CrimeFragment I added a method for deleting the photo

    private void deletePhoto() {
		if (mCrime.getPhoto() != null){
	          String path = getActivity().getFileStreamPath(mCrime.getPhoto().getFilename()).getAbsolutePath();
	          File f = new File(path);
	          f.delete();
	          mCrime.setPhoto(null);
		}
    }

Then, I call the method inside the class each time we need to take rid of the photo associated to the crime instance:

  • When replacing it
  • When deleting it (in my solution via a contextual menu)
  • When deleting the crime (in my solution via a contextual action)

So I have respectively:

On onActivityResult(int, int Intent) (replacing the photo with a new one)

...

} else if (requestCode == REQUEST_PHOTO) {
            //If there's already a photo for the crime, deletes it from the filesystem
            deletePhoto();
            // create a new Photo object and attach it to the crime
            String filename = data.getStringExtra(CrimeCameraFragment.EXTRA_PHOTO_FILENAME);
            if (filename != null) {
                Photo p = new Photo(filename);
                mCrime.setPhoto(p);
                showPhoto();
            }
}

...

on onContextItemSelected(MenuItem) (when deleting the photo via contextual menu and updating the view of the thumbnail):

   /**
     * Inflates the custom contextual menu for deleting the photo from the crime view
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        getActivity().getMenuInflater().inflate(R.menu.crime_item_context, menu);
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {

       switch (item.getItemId()) {
       case R.id.menu_item_delete_photo:
    	  deletePhoto();
	      showPhoto();
	      return true;
       }
       return super.onContextItemSelected(item);
    }

on onOptionsItemSelected(MenuItem) (when deleting the entire crime instance from the CrimeFragment’s view) we call directly the deleteCrime(Crime) method from the CrimeLab so I modified the lab like this:

    public void deleteCrime(Crime c) {
    	//If there are photos associated to the crime instance, first takes care of them in the filesystem
    	if(c.getPhoto() != null) {
    		String path = mAppContext.getFileStreamPath(c.getPhoto().getFilename()).getAbsolutePath();
    		File f = new File(path);
	        f.delete();
	        c.setPhoto(null);
    	}
        mCrimes.remove(c);
        saveCrimes();
    }

This last changing takes rid of the photo inside the filesystem also when we decide to delete a crime from the CrimeListFragment’s view, so we don’t keep useless photos in storage.

Actually I wanted to solve the entire problem by just adding a public void removePhoto() to the Crime class and call it inside CrimeFragment and CrimeLab but I couldn’t find a way to retrieve the absolute path of the photo since I couldn’t use getActivity() or getApplicationContext().