title: Null Pointer Exception when trying to compress Bitmap, can't take photo and upload to server
body: <p>I am getting a <code>NullPointerException</code> when trying to take a photo on camera application and upload it on to the server side, but some devices it works fine, and some getting issues. i don't know what is the issues, in some devices it works once and getting crashed.</p>
  <p>the issues are identified by using firebase <code>CrashAnalytics</code>.</p>
  <p>the fragment class.</p>
  <pre><code>class PhotoUploadFragment : BaseFragment() {
  
      private lateinit var viewModel: SelectOptionViewModel
  
      //define caseId type
      private var caseId: String? = &quot;&quot;
  
      //define caseNo type
      private var caseNo: String? = &quot;&quot;
  
      //define image clarity
      private var imageClarity: String? = &quot;&quot;
  
      //define image width
      private var imageWidth: String? = &quot;&quot;
  
      //define image height
      private var imageHeight: String? = &quot;&quot;
  
      //location
      lateinit var mFusedLocationClient: FusedLocationProviderClient
  
      //random id
      val PERMISSION_ID = 42
  
      //Initialize lat and long  to get loc address
      var longitude = 0.0
      var latitude = 0.0
  
      //Capture bitmap image
      var capturedBitmap = BitmapFactory.decodeStream(null)
  
      //Set timestamp when giving name while saving image
      var addrTimeStamp = &quot;&quot;
  
      //Initialize location address
      var locationAddress = &quot;&quot;
  
      companion object {
          private var args: Bundle? = null
  
          //pass the argument that needs to be displayed
          fun newInstance(case_id: String, case_number: String): Fragment {
  //            fun newInstance(case_id: String, case_number: String): Fragment {
              args = Bundle()
              //pass the value caseId
              args!!.putString(CASE_ID, case_id)
              //pass the value caseNo
              args!!.putString(CASE_NO, case_number)
              val fragment = PhotoUploadFragment()
              fragment.arguments = args
              return fragment
          }
      }
  
      override fun onCreateView(
          inflater: LayoutInflater,
          container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View {
          //setup view model
          viewModel = ViewModelProviders.of(this)[SelectOptionViewModel::class.java]
  //        homeViewModel = ViewModelProviders.of(this)[HomeViewModel::class.java]
          val view: View = inflater.inflate(
              layout.fragment_tab_photo_upload,
              container,
              false
          )
          //get caseId
          caseId = arguments?.getString(CASE_ID)
  
          //get caseNo
          caseNo = arguments?.getString(CASE_NO)
          if (caseNo == null || caseNo == &quot;&quot;) {
              caseNo = &quot;Nil&quot;
          }
  
          //get imageClarity
          imageClarity = PrefsHelper().getPref&lt;String&gt;(Constants.IMAGE_CLARITY)
  
          //get imageWidth
          imageWidth = PrefsHelper().getPref&lt;String&gt;(Constants.IMAGE_WIDTH)
  
          //get imageHeight
          imageHeight = PrefsHelper().getPref&lt;String&gt;(Constants.IMAGE_HEIGHT)
  
          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.imageUploadresponseLiveData.value = null
  
          //to enable upload btn only after image is taken
          photo_upload_button_upload.isEnabled = false
  
          getLastLocation()
          setUpListeners()
          setupObservers()
      }
  
      private fun setupObservers() {
          viewModel.imageUploadresponseLiveData.observe(this, androidx.lifecycle.Observer {
              if (it != null) {
                  //photo upload success
                  if (it.success == 1 &amp;&amp; it.result.success == 1) {
                      Toast.makeText(context, &quot;Image uploaded successfully.&quot;, Toast.LENGTH_SHORT)
                          .show()
                      //delete file after upload
                      val root = Environment.getExternalStorageDirectory().toString()
                      val myDir = File(root + &quot;/CV App/nomedia/images/&quot;)
                      myDir.deleteRecursively()
                      photo_upload_imageview_photo.setImageBitmap(null)
                      //to enable upload btn only after image is taken
                      photo_upload_button_upload.isEnabled = false
                  }
                  //photo upload fail
                  else {
                      Toast.makeText(
                          context,
                          &quot;Failed to update image. Please try again.&quot;,
                          Toast.LENGTH_SHORT
                      ).show()
                  }
              }
          })
          //observe API call status
          viewModel.imageUploadAPICallStatus.observe(this, androidx.lifecycle.Observer {
              processStatus(it)
          })
      }
  
  
      private fun setUpListeners() {
  
          photo_upload_button_open.setOnClickListener {
              //Check camera permission
              if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) {
                  if (checkSelfPermission(
                          this.activity!!,
                          Manifest.permission.CAMERA
                      ) != PackageManager.PERMISSION_GRANTED
                  ) {
                      ActivityCompat.requestPermissions(
                          this.activity!!,
                          arrayOf(Manifest.permission.CAMERA),
                          1
                      )
                  }
  
              }
              //Check storage permission
              if (ActivityCompat.checkSelfPermission(
                      this.activity!!,
                      Manifest.permission.WRITE_EXTERNAL_STORAGE
                  ) != PackageManager.PERMISSION_GRANTED
              ) {
  
                  ActivityCompat.requestPermissions(
                      this.activity!!,
                      arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_PERM_WRITE_STORAGE
                  )
  
              }
              //if permission is allowed,open camera
              else {
                  startCamera()
              }
  
              photo_upload_button_upload.setOnClickListener {
                  showDialogUpload()
              }
  
          }
      }
  
  
      private fun startCamera() {
  
          Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { cameraIntent -&gt;
              // Ensure that there's a camera activity to handle the intent
              cameraIntent.resolveActivity(context!!.packageManager)?.also {
                  // Create the File where the photo should go
                  val photoFile: File? = try {
                      createImageFile()
                  } catch (ex: IOException) {
                      // Error occurred while creating the File
                      //...
                      null
                  }
                  //    Continue only if the File was successfully created
                  photoFile?.also {
                      val photoURI: Uri = FileProvider.getUriForFile(
                          this.activity!!,
                          &quot;com.xyzshopapp.fileprovider&quot;,
                          it
                      )
                      cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                      cameraIntent.putExtra(&quot;return-data&quot;, true)
                      this.startActivityForResult(cameraIntent, ACTION_IMAGE_CAPTURE)
                  }
              }
          }
      }
  
  
      /**
       * Create external image file, this file will be passed to Camera for saving the captured image
       */
      @Throws(IOException::class)
      private fun createImageFile(): File {
  
          // Create an image file name
          val timeStamp: String = SimpleDateFormat(&quot;yyyyMMdd_HHmmss&quot;).format(Date())
          //Set timestamp to addrTimeStamp
          addrTimeStamp = timeStamp
          val root = Environment.getExternalStorageDirectory().toString()
          val myDir = File(&quot;$root/CV App/nomedia/images&quot;)
  
          myDir.mkdirs()
  
          return File.createTempFile(
              &quot;JPG_${addrTimeStamp}_&quot;, /* prefix */
              &quot;.jpg&quot;, /* suffix */
              myDir /* directory */
          ).apply {
              // Save a file: path for use with ACTION_VIEW intents
              fileTemp = this
              //Save the complete file path to string
              imageFileName = this.toURI().path.toString()
  
          }
      }
  
      //show thumbnail
      override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
          super.onActivityResult(requestCode, resultCode, data)
  
          if (resultCode == Activity.RESULT_OK ) {
              when (requestCode) {
                  ACTION_IMAGE_CAPTURE -&gt; {
                      val imageQuality = imageClarity
                      val byteArrayOutputStream = ByteArrayOutputStream()
  
                      //Decode file to bitmap
                      capturedBitmap = BitmapFactory.decodeFile(imageFileName)
  
  
                      val a = capturedBitmap
                      val destinationHeight = imageHeight
                      val destinationWidth = imageWidth
                      var imageToScale = capturedBitmap
  
                      //test
                      var uncompressed = capturedBitmap
                      if (destinationHeight != null) {
                          if (destinationWidth != null) {
                              if (destinationHeight.toInt() &gt; 0 &amp;&amp; destinationWidth.toInt() &gt; 0 &amp;&amp; imageToScale != null) {
                                  val width = imageToScale.width
                                  val height = imageToScale.height
  
                                  //Calculate the max changing amount and decide which dimension to use
                                  val widthRatio = destinationWidth.toFloat() / width.toFloat()
                                  val heightRatio = destinationHeight.toFloat() / height.toFloat()
  
                                  //Use the ratio that will fit the image into the desired sizes
                                  var finalWidth = floor((width * widthRatio).toDouble()).toInt()
                                  var finalHeight = floor((height * widthRatio).toDouble()).toInt()
                                  if (finalWidth &gt; destinationWidth.toInt() || finalHeight &gt; destinationHeight.toInt()) {
                                      finalWidth = floor((width * heightRatio).toDouble()).toInt()
                                      finalHeight = floor((height * heightRatio).toDouble()).toInt()
                                  }
  
                                  //Scale given bitmap to fit into the desired area
                                  imageToScale = Bitmap.createScaledBitmap(imageToScale, finalWidth, finalHeight, false)
  
                                  //Created a bitmap with desired sizes
                                  val scaledImage =
                                      Bitmap.createBitmap(destinationWidth.toInt(), destinationHeight.toInt(), Bitmap.Config.ARGB_8888)
                                  uncompressed = imageToScale
                              }
                          }
                      }
  
                      //compress by quality
                      if (imageQuality != null) {
                          uncompressed.compress(
                              Bitmap.CompressFormat.JPEG,
                              imageQuality.toInt(),
                              byteArrayOutputStream
                          )
                         /*try{
  
                         }catch (e:Exception)
                         {
                             println(&quot;this is exception $e&quot;)
                         }*/
  
                      }
                      val byteArray = byteArrayOutputStream.toByteArray()
                      //Encode bitmap to file
                      val compressedImageFile = FileOutputStream(imageFileName)
                      compressedImageFile.write(byteArray)
                      compressedImageFile.flush()
                      compressedImageFile.close()
                      //Set image in thumbnail
                      photo_upload_imageview_photo.setImageBitmap(a)
                      //to enable upload btn only after image is taken
                      photo_upload_button_upload.isEnabled = true
                  }
                  else -&gt; {
                      Toast.makeText(context, &quot;Unrecognized request code.&quot;, Toast.LENGTH_SHORT).show()
                  }
              }
  
          }
  
      }
  
      //popup box for uploading photo
      fun showDialogUpload() {
          val dialog = Dialog(context!!)
          dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
          dialog.setCancelable(true)
          dialog.setContentView(layout.photo_upload)
  
          val photo_upload_submit =
              dialog.findViewById(com.xyz.shopapp.R.id.image_button_submit) as Button
          val spinner =
              dialog.findViewById(com.xyz.shopapp.R.id.photo_upload_spinner_image_name) as Spinner
          //get array of image names
          val imageName = (PrefsHelper().getPref&lt;String&gt;(&quot;ImageName&quot;))
  
          //convert array to string
          val gson = Gson()
          val imageNameList = gson.fromJson(imageName, Array&lt;String&gt;::class.java).asList()
  
          //dropdown menu
          if (spinner != null) {
              val adapter =
                  ArrayAdapter&lt;String&gt;(context!!, android.R.layout.simple_spinner_item, imageNameList)
              // Set layout to use when the list of choices appear
              adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
              // Set Adapter to Spinner
              spinner.adapter = adapter
  
              //get image name
              var itemSpinnerSelected = &quot;&quot;
              spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
                  override fun onItemSelected(
                      parent: AdapterView&lt;*&gt;,
                      view: View,
                      position: Int,
                      id: Long
                  ) {
                      // Get the selected item
                      itemSpinnerSelected = &quot;${parent.getItemAtPosition(position)}&quot;
                  }
  
                  override fun onNothingSelected(parent: AdapterView&lt;*&gt;) {
                      // Another interface callback
                  }
              }
  
              photo_upload_submit.setOnClickListener {
  
                  if (getAddress()) {
                      viewModel.submitImageData(
                          caseId, caseNo,
                          imageFileName, latitude, longitude, itemSpinnerSelected, locationAddress
                      )
  //                    viewModel.submitImageData(
  //                        caseId, caseNo,
  //                        imageFileName, latitude, longitude, itemSpinnerSelected, locationAddress
  //                    )
  //                viewModel.submitImageData(caseId,caseNo,rootDir + &quot;/CV App/nomedia/images/avc6937492103605367617.jpg&quot;,latitude,longitude,itemSpinnerSelected, locationAddress)
  //                dismissDialog()
  //                val progressBar = findViewById(com.xyz.shopapp.R.id.progresbar) as ProgressBar
  //                progressBar.visibility = View.INVISIBLE
  
                  }
                  dialog.dismiss()
              }
  
          }
          dialog.show()
      }
  
      //get location
      //check whether location is enabled for application
      @SuppressLint(&quot;MissingPermission&quot;)
      private fun getLastLocation() {
  //       var latitude = 0.0
          if (checkPermissions()) {
              //if (isLocationEnabled()) {
  
                       mFusedLocationClient.lastLocation.addOnCompleteListener(this.activity!!) { task -&gt;
                           val location: Location? = task.result
  
                           if (location == null) {
                               requestNewLocationData()
                           } else {
                               latitude = location.latitude
                               longitude = location.longitude
                               getAddress()
                           }
                       }
  
              /*mFusedLocationClient.lastLocation.addOnCompleteListener(this.activity!!) { task -&gt;
                  var location: Location? = task.result
  
                  if (location == null) {
                      requestNewLocationData()
                  } else {
                      latitude = location.latitude
                      longitude = location.longitude
                      getAddress()
                  }
              }*/
  //            } else {
  //                Toast.makeText(context, &quot;Turn on your location.&quot;, Toast.LENGTH_LONG).show()
  //                val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
  //                startActivity(intent)
  //            }
  
  
          } else {
              //requestPermissions()
              //Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION
  
              //to get location in first try itself
              val coraseLocationPermission = checkSelfPermission(
                  this.activity!!,
                  Manifest.permission.ACCESS_COARSE_LOCATION
              )
              val accessFineLocation = checkSelfPermission(
                  this.activity!!,
                  Manifest.permission.ACCESS_FINE_LOCATION
              )
  
              if (coraseLocationPermission != PackageManager.PERMISSION_GRANTED &amp;&amp; accessFineLocation != PackageManager.PERMISSION_GRANTED) {
  
                  requestPermissions(
                      arrayOf(
                          Manifest.permission.ACCESS_COARSE_LOCATION,
                          Manifest.permission.ACCESS_FINE_LOCATION
                      ),
                      PERMISSION_ID
                  )
              }
          }
      }
  
      @SuppressLint(&quot;MissingPermission&quot;)
      private fun requestNewLocationData() {
  
  
          val 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) {
              val mLastLocation: Location = locationResult.lastLocation
              latitude = mLastLocation.latitude
              longitude = mLastLocation.longitude
          }
      }
  
  //    private fun isLocationEnabled(): Boolean {
  //        var locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
  //        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
  //            LocationManager.NETWORK_PROVIDER
  //        )
  //    }
  
  
      private fun checkPermissions(): Boolean {
          if (ActivityCompat.checkSelfPermission(
                  this.activity!!,
                  Manifest.permission.ACCESS_COARSE_LOCATION
              ) == PackageManager.PERMISSION_GRANTED &amp;&amp;
              ActivityCompat.checkSelfPermission(
                  this.activity!!,
                  Manifest.permission.ACCESS_FINE_LOCATION
              ) == PackageManager.PERMISSION_GRANTED
          ) {
              return true
          }
          return false
      }
  
      //check location permission
      private fun requestPermissions() {
          ActivityCompat.requestPermissions(
              this.activity!!
              ,
              arrayOf(
                  Manifest.permission.ACCESS_COARSE_LOCATION,
                  Manifest.permission.ACCESS_FINE_LOCATION
              ),
              PERMISSION_ID
          )
      }
  
      //request location permission
      override fun onRequestPermissionsResult(
          requestCode: Int,
          permissions: Array&lt;String&gt;,
          grantResults: IntArray
      ) {
          if (requestCode == PERMISSION_ID) {
              if ((grantResults.isNotEmpty() &amp;&amp; grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
  
                  mFusedLocationClient.lastLocation.addOnCompleteListener(this.activity!!) { task -&gt;
                      val 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&lt;Address&gt; = emptyList()
      private fun getAddress(): Boolean {
  //        showDialog()
          var flag = false
          locationAddress = &quot;&quot;
          try {
              val 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
              val address_size = addresses.size
              if (address_size &gt; 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) {
              val errorMessage = getString(string.service_not_available)
              Log.e(ContentValues.TAG, errorMessage + &quot; saf not avail&quot;, ioException)
          }
  
          dismissDialog()
          return flag
      }
  
      private fun processStatus(resource: ResourceStatus) {
  
          when (resource.status) {
              StatusType.SUCCESS -&gt; {
                  dismissDialog()
  //                Toast.makeText(context, &quot;Photo Uploaded Successfully.&quot;, Toast.LENGTH_SHORT).show()
              }
              StatusType.EMPTY_RESPONSE -&gt; {
                  dismissDialog()
              }
              StatusType.PROGRESSING -&gt; {
                  showDialog()
              }
              StatusType.SWIPE_RELOADING -&gt; {
  
              }
              StatusType.ERROR -&gt; {
  //                var fail_status = &quot;Failed to update image. Please try again.&quot;
  //                Toast.makeText(context, fail_status, Toast.LENGTH_SHORT).show()
                  dismissDialog()
  
              }
              StatusType.LOADING_MORE -&gt; {
                  // CommonUtils().showSnackbar(binding.root, &quot;Loading more..&quot;)
              }
              StatusType.NO_NETWORK -&gt; {
                  val internet_failure = &quot;Please check your internet connection.&quot;
                  Toast.makeText(context, internet_failure, Toast.LENGTH_SHORT).show()
              }
              StatusType.SESSION_EXPIRED -&gt; {
  //                var session_expired = &quot;Invalid credentials. Login failed&quot;
  //                Toast.makeText(this, session_expired, Toast.LENGTH_SHORT).show()
              }
          }
      }
  
  
      ///
  
  
  }   
  
  
  </code></pre>
  <p>The line which causes the error is</p>
  <pre><code>uncompressed.compress(Bitmap.CompressFormat.JPEG,imageQuality.toInt(),byteArrayOutputStream)
  </code></pre>
  <p>error log shown in firebase crashAnalytics console:</p>
  <pre><code>Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
         at com.axionz.shopapp.ui.tabfragment.PhotoUploadFragment.onActivityResult(PhotoUploadFragment.kt:353)
         at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170)
         at android.app.Activity.dispatchActivityResult(Activity.java:8464)
         at android.app.ActivityThread.deliverResults(ActivityThread.java:5355)
         at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4755)
         at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4810)
         at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
         at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:187)
         at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:102)
         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
         at android.os.Handler.dispatchMessage(Handler.java:106)
         at android.os.Looper.loop(Looper.java:254)
         at android.app.ActivityThread.main(ActivityThread.java:8243)
         at java.lang.reflect.Method.invoke(Method.java)
         at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)
   
  </code></pre>