Today I wanted to create a AttachmentMenuDialog which will be reusable in an Activity or Fragment. Like the name says, it's a DialogFragment which will be used to add file attachments to your Activity/Fragment.

In the image below you see that I have two Activities who are opening the AttachmentMenuDialog. The only difference is that ActivityOne is opening the fragment directly and ActivityTwo is opening from another fragment.

I struggled with the problem that it worked in one of the both Activities. So when I fix it for ActivityOne, it broke at ActivityTwo and vice versa.

 

Inside AttachmentMenuDialog I have three buttons:

  • Add a file from the storage (File intent)
  • Take a picture with the camera (Camera intent)
  • Create a PDF document inside PDFActivity

Adding a file from storage and taking a picture was no problems at all, but getting the PDF document as a result from the PDFActivity was not so easy as it should be.

On the PDF button I had this onClickListener:

AttachmentMenuDialog.java:

pdfButton.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View view) {
		Intent intent = new Intent(getContext(), PDFActivity.class);
                //REQUEST_CODE_PDF = 1234
		startActivityForResult(intent, REQUEST_CODE_PDF);
	}
});

This should work like expected you think? Well it's not. Not on this way at least. The PDFActivity is opened, and when I create a PDF, I would like to have the result back inside my Activity. Like the scheme above I would like to have the PDF document inside ActivityOne or ActivityTwo.

The problem is that when you open the activity by using the fragments startActivityForResult, you will lose the requestCode. Your activity regenerates a new one and you will never ever, ever get your result back. After running the debugger  I found out that the requestCode is always changed to the number 65660. Don't ask me why.

Solution:

You have to start the Activity from your parent activity like this:

getActivity().startActivityForResult(intent, REQUEST_CODE_PDF);

When the PDFActivity is finished, it will execute onActivityResult() from the parent Activity. You will have to delegate it to your fragment if you need it there.

ActivityOne.java

@Override
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
	if (attachmentMenuDialog != null) {
		attachmentMenuDialog.onActivityResult(requestCode, resultCode, data);
	}
}

 

Well the first problem is solved. My PDF document from PDFActivity is passed to my Activity where I expect it, but like I'm not frustrated enough, I faced a new problem. Why the heck is my Activity(ActivityOne) closing  when I create my PDF inside PDFActivity?

In ActivityOne and in ActivityTwo the PDFActivity returned the PDF document inside the onActivityResult method. For some reason ActivityTwo finished/closed automatically when PDFActivity was finished.

Let's take a look at the PDFActivity where I finish the activity

public static final int RESULT_PDF_OK = 5;

public void onTaskComplete(File pdfFile) {
	Intent intent = new Intent();
	intent.putExtra(INTENT_PDF_FILE, pdfFile);
	setResult(RESULT_OK, intent);
	finish();
}

The problem is that I was putting RESULT_OK as status code which is an reserved status for internal usage. Android uses resultcodes untill 1 for internal usage. Like RESULT_OK = -1.  For your own purposes you can safely use custom resultCodes which are bigger than 1.

I think that because I opened the whole Fragment/Activity chain by using getActivity().startActivityForResult() that I passed the context of my Activity to the PDFActivity which unintentionally finishes the Activity because the result is RESULT_OK.