Search code examples
androidandroid-lifecycle

Android SQLITE Image issue: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference


the problem: if user doesn't upload any image, app crashes, as cannot store previous image...

Overview: my application consists of Category and Editor activities.

  • Editor activity has a button to upload image and save the activity.
  • Category activity displays image from Editor activity.
  • Problem here --> once the user returns back to edit details in Editor activity, app crashes with below error:

Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference

If user uploads an image again - same or different, doesn't matter, the app works well.

The goal is to keep the image if the user doesn't want to upload a new one, just like the app keeps the values for EditText fields:

 private void saveInventory() {

// Read from input fields
// Use trim to eliminate leading or trailing white space
String nameString = mNameEditText.getText().toString().trim();
String infoString = mAdditionalInfoEditText.getText().toString().trim();
String priceString = mPriceEditText.getText().toString().trim();
String quantityString = mQuantityTextView.getText().toString().trim();
String image = actualUri.toString(); <---- error here

Image is selected in this method:

  @Override
    public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
        // The ACTION_OPEN_DOCUMENT intent was sent with the request code READ_REQUEST_CODE.
        // If the request code seen here doesn't match, it's the response to some other intent,
        // and the below code shouldn't run at all.

        if (requestCode == SELECT_AN_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) {
            // The document selected by the user won't be returned in the intent.
            // Instead, a URI to that document will be contained in the return intent
            // provided to this method as a parameter.  Pull that uri using "resultData.getData()"

            if (resultData != null) {
                actualUri = resultData.getData();
                mPhotoImageView.setImageURI(actualUri);

            }
        }
    }

I believe that saving the activity state and restoring it might solve the problem (code below), but I don't know where to paste it in my code....

    // Save the activity state when it's going to stop.
   // @Override
   // protected void onSaveInstanceState(Bundle outState) {
      //  super.onSaveInstanceState(outState);

       // outState.putParcelable("actualUri", actualUri);
   // }

    // Recover the saved state when the activity is recreated.
   // @Override
  //  protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    //    super.onRestoreInstanceState(savedInstanceState);

     //   actualUri= savedInstanceState.getParcelable("actualUri");

   // }

Probably someone knows how to keep same image upon saving the editor activity. Thank you.

P.S. The finish activity quits the editor, and returns to Catalog. All data is saved in Database - apart from image.

    @Override public boolean onOptionsItemSelected(MenuItem item) { 
// User clicked on a menu option in the app bar overflow menu switch (item.getItemId()) 
{ // Respond to a click on the "Save" menu option case R.id.action_save: 
// Save to database saveInventory(); 
// Exit activity finish(); return true;

Solution

  • I have solved the isssue.

    I had to remove the line that causes an error in 'Save' class, and create a separate validation in this class:

     if (actualUri== null) {
                Toast.makeText(this, getString(R.string.image_required), Toast.LENGTH_SHORT).show();
                return hasAllRequiredValues;
            } else {
                values.put(InventoryEntry.COLUMN_INVENTORY_IMAGE, actualUri.toString());
            }