when trying to upload a sign, getting this java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

Viewed 112

getting crash trying to upload a sign

Caused by: java.io.IOException: No such file or directory when clicking the submit button

error logs are shown below


    class SignatureUploadFragment : BaseFragment() {
            private lateinit var viewModel: SelectOptionViewModel
            private lateinit var homeViewModel: HomeViewModel
        
            //location
            lateinit var mFusedLocationClient: FusedLocationProviderClient
        
            //random id
            val PERMISSION_ID = 42
        
            //Define caseId type
            private var caseId: String? = ""
        
            //Initialize lat and long  to get loc address
            var longitude = 0.0
            var latitude = 0.0
        
            //Initialize location address
            var locationAddress = ""
        
            //Set timestamp when giving name while saving signature image
            var addrTimeStamp = ""
        
            //Convert file to string
            var signatureFileName: String = ""
        
            companion object {
                var args: Bundle? = null
        
                //pass the argument that needs to be displayed
                fun newInstance(case_id: String): Fragment {
                    args = Bundle()
                    //pass the value caseId
                    args!!.putString(CASE_ID, case_id)
                    val fragment = SignatureUploadFragment()
                    fragment.arguments = args
                    return fragment
                }
            }
    
 

   override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        //setup view models
        viewModel = ViewModelProviders.of(this)[SelectOptionViewModel::class.java]
        homeViewModel = ViewModelProviders.of(this)[HomeViewModel::class.java]
        val view: View = inflater.inflate(R.layout.signature_upload, container, false)
        //get caseId
        caseId = arguments?.getString(CASE_ID)

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this.activity!!)
        return view
    }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            //to clear all the data inside the fragment to avoid multiple API calls
            viewModel.signatureUploadresponseLiveData.value = null
            viewModel.caseCompleteresponseLiveData.value = null
    
            getLastLocation()
            setUpListeners()
            setupObserversCaseComplete()
            setupObserversSubmitSignature()
        }
    
    
        /**
         * Write all LiveData observers in this method
         */
    
        private fun setupObserversCaseComplete() {
    //        if (isMenuVisible) {
    
            viewModel.caseCompleteresponseLiveData.observe(this, Observer {
                if (it != null) {
                    //user case complete success
                    if (it.success == 1 && it.result.success == 1) {
                        //Go back to case listing page
                        val intent = Intent(context, HomeActivity::class.java)
                        startActivity(intent)
                        Toast.makeText(
                            context,
                            "Case completed successfully.",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                    //user case complete fail
                    else {
                        Toast.makeText(
                            context,
                            it.result.message,
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
    
            })
    
            //observe API call status
            viewModel.caseCompleteAPICallStatus.observe(this, Observer {
                processStatus(it)
            })
    
        }
    
        /**
         * Write all LiveData observers in this method
         */
        private fun setupObserversSubmitSignature() {
            viewModel.signatureUploadresponseLiveData.observe(this, Observer {
                if (it != null) {
                    //signature upload success
                    if (it.success == 1 && it.result.success == 1) {
                        Toast.makeText(context, "Signature uploaded successfully.", Toast.LENGTH_SHORT)
                            .show()
                    //delete file after upload
                        val root = Environment.getExternalStorageDirectory().toString()
                        val myDir = File(root + "/Zion App/nomedia/Signature Images/")
                        myDir.deleteRecursively()
                    }
                    //signature upload fail
                    else {
                        Toast.makeText(
                            context,
                            "Failed to update signature. Please try again.",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
    
            })
            //observe API call status
            viewModel.signatureUploadAPICallStatus.observe(this, Observer {
                processStatus(it)
            })
    
        }
    
        private fun setUpListeners() {
            signature_button_complete.setOnClickListener {
                showDialogComplete(caseId)
            }
    
            /**
             * Create external image file, this file will be passed to Camera for saving the captured image
             */
            @Throws(IOException::class)
            fun createSignatureImageFile(): File {
    
                // Create an image file name
                var timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
                //Set timestamp to addrTimeStamp
                addrTimeStamp = timeStamp
                val root = Environment.getExternalStorageDirectory().toString()
                val myDir = File("$root/Zion App/nomedia/Signature Images")
    
                myDir.mkdirs()
    
                return File.createTempFile(
                    "JPG_${addrTimeStamp}_", /* prefix */
                    ".jpg", /* suffix */
                    myDir /* directory */
                ).apply {
                    // Save a file: path for use with ACTION_VIEW intents
                    fileTemp = this
                    //Save the complete file path to string
                    signatureFileName = this.toURI().path.toString()
    
                }
            }
    
            signature_button_submit.setOnClickListener() {
                //to check if signature pad is empty or not
                if (signature_view.isBitmapEmpty) {
                    Toast.makeText(context, "Please sign here.", Toast.LENGTH_SHORT).show()
                } else {
                    val signatureBitmap = signature_view.signatureBitmap
    
    //                val signatureBitmap = signature_view.signatureBitmap
                    createSignatureImageFile()
    
                    var imageQuality = 70
                    val byteArrayOutputStream = ByteArrayOutputStream()
    //                var capturedBitmap = BitmapFactory.decodeFile(signatureFileName)
                    var uncompressed = signatureBitmap
    
                    var newHeight = 800.00; // default height in pixels
                    var newWidth = 533.00; // default width in pixels
                    var oldHeight = uncompressed.getHeight().toDouble()
                    var oldWidth = uncompressed.getWidth().toDouble()
                    var aspRatio = 2.00 //default
    
                    if (oldHeight > 0 && oldWidth > 0) {
                        if (oldWidth > oldHeight) {
                            aspRatio = (oldWidth / oldHeight)
                            newHeight = newWidth / aspRatio
                            newWidth = newHeight * aspRatio
                        } else if (oldWidth < oldHeight) {
                            aspRatio = (oldHeight / oldWidth)
                            newHeight = newHeight / aspRatio
                            newWidth = newWidth * aspRatio
                        } else {
                            aspRatio = (oldHeight / oldWidth)
                            newHeight = newWidth / aspRatio
                            newWidth = newHeight * aspRatio
                        }
                    }
    //                scale it to 533w * 800h
                    uncompressed = Bitmap.createScaledBitmap(
                        uncompressed,
                        newWidth.toInt(),
                        newHeight.toInt(),
                        true
                    )
                    //compress by quality
                    uncompressed.compress(
                        Bitmap.CompressFormat.JPEG,
                        imageQuality,
                        byteArrayOutputStream
                    )
                    val byteArray = byteArrayOutputStream.toByteArray()
                    val compressedSignatureFile = FileOutputStream(signatureFileName)
                    compressedSignatureFile.write(byteArray)
                    compressedSignatureFile.flush()
                    compressedSignatureFile.close()
    //                val encoded = Base64.encodeToString(byteArray, Base64.DEFAULT)
                    signature_view.signatureBitmap
    
                    var imageType = "sign"
    
                    if (getAddress()) {
                        viewModel.submitSignatureData(
                            caseId,
                            imageType,
                            signatureFileName,
                            latitude,
                            longitude,
                            locationAddress
                        )
    //                dismissDialog()
    //                    val progressBar  = dialog?.findViewById(com.xyz.zion.R.id.progresbar) as ProgressBar
    //                    progressBar.visibility = View.INVISIBLE
                    }
    
                }
    
            }
    
            signature_button_clear.setOnClickListener {
                signature_view.clearCanvas()
            }
        }
    
    
        //popup box for complete case
        fun showDialogComplete(caseId: String?) {
            val dialog = Dialog(context)
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
            dialog.setCancelable(true)
            dialog.setContentView(com.xyz.zionapp.R.layout.popup_menu_complete_case)
            var remarkBox =
                dialog.findViewById(com.xyz.zionapp.R.id.submit_edittext_remark) as EditText
            val submitBtn =
                dialog.findViewById(com.xyz.zionapp.R.id.submit_button_submit_case) as Button
            submitBtn.setOnClickListener {
    
                var remarks = remarkBox.text.trim().toString();
                var caseStatus = "completed"
                if (remarks == "") {
                    Toast.makeText(context, "Please enter your remarks.", Toast.LENGTH_SHORT).show()
                } else {
                    //initiate API call using ViewModel method
                    viewModel.submitCase(caseId, caseStatus, remarks)
    //                Toast.makeText(context, "Case completed successfully.", Toast.LENGTH_SHORT).show()
    
                    dialog.dismiss()
                }
            }
            dialog.show()
        }
    
        //get location
        //check whether location is enabled for application
        @SuppressLint("MissingPermission")
        private fun getLastLocation() {
    //       var latitude = 0.0
            if (checkPermissions()) {
                //if (isLocationEnabled()) {
    
                mFusedLocationClient.lastLocation.addOnCompleteListener(this.activity!!) { task ->
                    var location: Location? = task.result
    
                    if (location == null) {
                        requestNewLocationData()
                    } else {
                        latitude = location.latitude
                        longitude = location.longitude
                        getAddress()
                        // Call API
                    }
                }
            } else {
                //requestPermissions()
                //Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION
    
                //to get location in first try itself
                var coraseLocationPermission = ContextCompat.checkSelfPermission(
                    this.activity!!,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                );
                var accessFineLocation = ContextCompat.checkSelfPermission(
                    this.activity!!,
                    Manifest.permission.ACCESS_FINE_LOCATION
                );
    
                if (coraseLocationPermission != PackageManager.PERMISSION_GRANTED && accessFineLocation != PackageManager.PERMISSION_GRANTED) {
    
                    requestPermissions(
                        arrayOf(
                            Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ),
                        PERMISSION_ID
                    );
                }
            }
        }
    
        @SuppressLint("MissingPermission")
        private fun requestNewLocationData() {
            var mLocationRequest = LocationRequest()
            mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            mLocationRequest.interval = 0
            mLocationRequest.fastestInterval = 0
            mLocationRequest.numUpdates = 1
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this.activity!!)
            mFusedLocationClient!!.requestLocationUpdates(
                mLocationRequest, mLocationCallback,
                Looper.myLooper()
            )
        }
    
        private val mLocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                var mLastLocation: Location = locationResult.lastLocation
                latitude = mLastLocation.latitude
                longitude = mLastLocation.longitude
            }
        }
    
    
        //check location permission
        private fun checkPermissions(): Boolean {
            if (ActivityCompat.checkSelfPermission(
                    this.activity!!,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) == PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(
                    this.activity!!,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                return true
            }
            return false
        }
    
        //request location permission
        private fun requestPermissions() {
            ActivityCompat.requestPermissions(
                this.activity!!
                ,
                arrayOf(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ),
                PERMISSION_ID
            )
        }
    
    
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<String>,
            grantResults: IntArray
        ) {
            if (requestCode == PERMISSION_ID) {
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
    
                    mFusedLocationClient.lastLocation.addOnCompleteListener(this.activity!!) { task ->
                        var location: Location? = task.result
    
                        if (location == null) {
                            requestNewLocationData()
                        } else {
                            latitude = location.latitude
                            longitude = location.longitude
                            // Call API
                        }
                    }
                    requestNewLocationData()
                } else {
                    getLastLocation();
                }
            }
        }
    
        //get address from location
        var addresses: List<Address> = emptyList()
    
        private fun getAddress(): Boolean {
    //    showDialog()
            var flag = false
            locationAddress = ""
            try {
                var geocoder = Geocoder(context, Locale.getDefault())
                addresses = geocoder.getFromLocation(
                    latitude,
                    longitude, 1
                ) // Here 1 represent max location result to returned, by documents it recommended 1 to 5
                //null checking
                var address_size = addresses.size
                if (address_size > 0) {
                    locationAddress = addresses.get(0)
                        .getAddressLine(0) // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                    flag = true
                }
    
            } catch (ioException: IOException) {
                var errorMessage = getString(R.string.service_not_available)
                Log.e(TAG, errorMessage + " saf not avail", ioException)
            }
    
            dismissDialog()
            return flag
        }
    
        private fun processStatus(resource: ResourceStatus) {
    
            when (resource.status) {
                StatusType.SUCCESS -> {
                    dismissDialog()
    //                Toast.makeText(context, resource.message, Toast.LENGTH_SHORT).show()
                }
                StatusType.EMPTY_RESPONSE -> {
                    dismissDialog()
                }
                StatusType.PROGRESSING -> {
                    showDialog()
                }
                StatusType.SWIPE_RELOADING -> {
    
                }
                StatusType.ERROR -> {
                    var fail_status = "Failed to update signature. Please try again."
                    Toast.makeText(context, fail_status, Toast.LENGTH_SHORT).show()
                    dismissDialog()
    
                }
                StatusType.LOADING_MORE -> {
                    // CommonUtils().showSnackbar(binding.root, "Loading more..")
                }
                StatusType.NO_NETWORK -> {
                    var internet_failure = "Please check your internet connection."
                    Toast.makeText(context, internet_failure, Toast.LENGTH_SHORT).show()
                }
                StatusType.SESSION_EXPIRED -> {
    //                var session_expired = "Invalid credentials. Login failed"
    //                Toast.makeText(this, session_expired, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

Issues are on the line

 "return File.createTempFile(
                "JPG_${addrTimeStamp}_", /* prefix */
                ".jpg", /* suffix */
                myDir /* directory */
            ). "

and this function "createSignatureImageFile()."


    Fatal Exception: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:642)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)

error logs "java.lang.reflect.InvocationTargetException"


    Caused by java.lang.reflect.InvocationTargetException
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)

error logs "java.io.IOException no such file or directory"


    Caused by java.io.IOException: No such file or directory
           at java.io.UnixFileSystem.createFileExclusively0(UnixFileSystem.java)
           at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
           at java.io.File.createTempFile(File.java:2018)
           at com.xyz.Zionapp.ui.signature_upload_fragment.SignatureUploadFragment$setUpListeners$2.invoke(SignatureUploadFragment.kt:238)
           at com.xyz.app.ui.signature_upload_fragment.SignatureUploadFragment$setUpListeners$3.onClick(SignatureUploadFragment.kt:259)

1 Answers

In the line above the line that creates the error, you are calling myDir.parentFile.mkdirs(), creating all directories up to the parent folder of myDir, but you are using myDir as the directory where you want to create the temp file.

You have to replace the call by myDir.mkdirs() to make sure that the folder myDir itself exists. Then you can place a temporary file there.

Related