Search code examples
androidandroid-fragmentsandroid-cameraandroid-galleryandroid-camera-intent

onActivityResult is not called after returning from Gallery or Camera


I need to open Camera or Gallery to upload photo into my App and then work with it. Problem is that after calling startActivityForResult(), when I take a photo and click X or OK button it will return me to my app, but onActivityResult is not called at all. Any reason why it is not working? Because this mechanism worked like 1 year ago. I reused it from other project. The only difference is that I'm using Fragments in this project. I implemented override of onActivityResult for both MainActivity and Fragment, but none of those methods were called as I came back from Gallery/Camera.

Code:

Gallery:

private fun openGallery() {
    val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    fragment?.activity?.let{it.startActivityForResult(intent, 
    GALLERY_REQUEST_CODE)}?:kotlin.run{App.showToast("Internal Error")}
}

Camera:

private fun openCamera() {
        val tempFile = createImageFile()
        photoPath = tempFile.absolutePath
        photoUri = FileProvider.getUriForFile(a, app.packageName + ".fileprovider", tempFile)

        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
        if (intent.resolveActivity(a.packageManager) != null) {
            fragment?.activity?.let{it.startActivityForResult(intent, CAMERA_REQUEST_CODE)}?:kotlin.run{App.showToast("Internal Error")}
        }
}

Fragment and MainActivity:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when(requestCode){
            CAMERA_REQUEST_CODE -> {
                maybeProcessPhoto(requestCode, resultCode, data)
            }
            GALLERY_REQUEST_CODE -> {
               maybeProcessPhoto(requestCode, resultCode, data)
            }
            else -> super.onActivityResult(requestCode, resultCode, data)
        }
}

UPDATE:

Problem was that I called startActivityForResult from custom made class, which is like Block managing photo editing. I just sent Fragment object to its constructor upon initialization and called fragment?.startActivityForResult() which didnt return anything to onActivityResult. I had to sent there function as parameter and in that function I had to call startActivityForResult. Which from my point of view is exactly same because both calls were on Fragment object, but it looks like you can open new activity from referenced Fragment but result will not return. You have to directly call startActivityForResult from Fragment itself to get result.

Example:

class CameraBlock(
        private val app: App,
        private val a: Activity,
        private val f: Fragment? = null,
        private val onIntent: (Intent, Int)->Unit
){


  private fun openGallery(){
     val intent = Intent(Intent.ACTION_PICK, 
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    //DOESNT WORK
    f?.let{it.startActivityForResult(intent, 
    GALLERY_REQUEST_CODE)}?:kotlin.run{App.showToast("Internal Error")}
    
    //THIS WORKS
    onIntent.invoke(intent, GALLERY_REQUEST_CODE)
  }
}

Fragment:

override fun onCreateView(li: LayoutInflater, container: ViewGroup?, si: Bundle?): View? {
        return (li.inflate(R.layout.photo_select, container, false) as ViewGroup).apply {
            openGalleryButton = CameraBlock(
                    app = app,
                    a = parentActivity,
                    f = this@PhotoFragment,
                    onIntent = ::openIntent
            )

        }
    }
 
private fun openIntent(int: Intent, code: Int){
        startActivityForResult(int, code)
    }

Solution

  • val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    startActivityForResult(intent, GALLERY_REQUEST_CODE)
    

    In fragment :

    @Override
      public void onActivityResult(int requestCode, int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }