Android icon indicating copy to clipboard operation
Android copied to clipboard

App Crashing

Open NatBob opened this issue 4 years ago • 4 comments

java.lang.RuntimeException: An error occurred while executing doInBackground() at androidx.loader.content.ModernAsyncTask$3.done(ModernAsyncTask.java:164) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383) at java.util.concurrent.FutureTask.setException(FutureTask.java:252) at java.util.concurrent.FutureTask.run(FutureTask.java:271) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) Caused by: java.lang.NullPointerException: uri at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:128) at android.content.ContentResolver.query(ContentResolver.java:737) at android.content.ContentResolver.query(ContentResolver.java:704) at androidx.core.content.ContentResolverCompat.query(ContentResolverCompat.java:81) at androidx.loader.content.CursorLoader.loadInBackground(CursorLoader.java:63) at androidx.loader.content.CursorLoader.loadInBackground(CursorLoader.java:41) at androidx.loader.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:307) at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:60) at androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:48) at androidx.loader.content.ModernAsyncTask$2.call(ModernAsyncTask.java:141) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)  at java.lang.Thread.run(Thread.java:764) 

NatBob avatar Apr 29 '21 12:04 NatBob

Hello @NatBob Thanks for your report, Can you please provide some information

AppName: Android OS Version:

When is the crash happen? when you do what?

AmrDeveloper avatar Apr 30 '21 20:04 AmrDeveloper

The Crash Happens on trying to open Editor Activity. The App has 4 Activities but only crashes when I want to open this, since I included image functionality Editor Activity Code: package com.example.kopagas;

import android.Manifest; import android.content.ContentValues; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Spinner; import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NavUtils; import androidx.loader.app.LoaderManager; import androidx.loader.content.CursorLoader; import androidx.loader.content.Loader;

import com.example.kopagas.kopadata.UserContract.brandsEntry; import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.io.IOException;

public class EditorActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { private Uri mCurrentBrandUri; private static final int STOCK_LOADER=0;

    /** EditText field to enter the pet's name */
    private EditText mNameEditText;

    /** EditText field to enter the pet's breed */
    private EditText mOutletEditText;

    /** EditText field to enter the pet's weight */
    private EditText mPriceEditText;

    /** EditText field to enter the pet's gender */
    private Spinner mSizeSpinner;

    /**
     * Gender of the pet. The possible values are:
     * 0 for unknown gender, 1 for male, 2 for female.
     */
    private int mSize = brandsEntry.MEDIUM_CYLINDER;
    private ImageView imageView;
    byte[] imageByteArray;
    Bitmap bitmap;

    FloatingActionButton button;
    Button editButton;

/**
 * Boolean flag that keeps track of whether the gas has been edited (true) or not (false)
 */
private boolean ShelveHasChanged = false;

/**
 * OnTouchListener that listens for any user touches on a View, implying that they are modifying
 * the view, and we change the medicineHasChanged boolean to true.
 */
private View.OnTouchListener mTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        ShelveHasChanged = true;
        return false;
    }
};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editor);


        /**
        // Find all relevant views that we will need to read user input from
        mNameEditText = (EditText) findViewById(R.id.edit_gas_name);
        mOutletEditText = (EditText) findViewById(R.id.edit_gas_outlet);
        mPriceEditText = (EditText) findViewById(R.id.edit_gas_price);
        mSizeSpinner = (Spinner) findViewById(R.id.spinner_gas_size);
        imageView = (ImageView) findViewById(R.id.my_avatar);
        button = (FloatingActionButton) findViewById(R.id.fab);
        editButton = (Button) findViewById(R.id.edit_button);
         */
        initializeUIElements();

        setupSpinner();
        //Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        //setSupportActionBar(toolbar);
        /**
        imageView = (ImageView) findViewById(R.id.my_avatar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectImage(EditorActivity.this);
            }
        });
         */
        // Initialize all views..


        // Examine the intent that was used to launch this activity,
        // in order to figure out if we're creating a new brand or editing an existing one.
        Intent intent = getIntent();
        mCurrentBrandUri = intent.getData();

        // If the intent DOES NOT contain a brand content URI, then we know that we are
        // creating a new brand.
        if (mCurrentBrandUri == null) {
            // This is a new brand, so change the app bar to say "Add a Brand"
            // I know we are coming from the FAB button being pressed
            setTitle(getString(R.string.detail_activity_title_new_gas));

            // Hide the Order Button if the gas is going to be added and not stored yet.
            editButton.setVisibility(View.GONE);

            // Invalidate the options menu, so the "Delete" menu option can be hidden.
            // (It doesn't make sense to delete a medicine that hasn't been created yet.)
            invalidateOptionsMenu();
        } else {
            // Otherwise this is an existing medicine, so change app bar to say "Edit Medicine"
            // I know we are coming from clicking a medicine in the Main Activity.
            setTitle(getString(R.string.detail_activity_title_edit_gas));
        }
        getSupportLoaderManager().initLoader(STOCK_LOADER, null, this);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //selectImage();
                getImageFromGallery();
            }
        });
    }

/**
 * This method initializes all UI elements used in the Activity
 */
public void initializeUIElements() {
    mNameEditText = (EditText) findViewById(R.id.edit_gas_name);
    mPriceEditText = (EditText) findViewById(R.id.edit_gas_price);
    imageView = (ImageView) findViewById(R.id.my_avatar);
    mOutletEditText = (EditText) findViewById(R.id.edit_gas_outlet);
    mSizeSpinner = (Spinner) findViewById(R.id.spinner_gas_size);
    //mOutletEditText = (EditText) findViewById(R.id.edit_gas_outlet);
    button = (FloatingActionButton) findViewById(R.id.fab);
    editButton = (Button) findViewById(R.id.edit_button);
    //Button increaseButton = (Button) findViewById(R.id.increaseButton);
    //Button decreaseButton = (Button) findViewById(R.id.decreaseButton);

    // Setup OnTouchListeners on all the input fields, so we can determine if the user
    // has touched or modified them. This will let us know if there are unsaved changes
    // or not, if the user tries to leave the editor without saving.
    mNameEditText.setOnTouchListener(mTouchListener);
    mPriceEditText.setOnTouchListener(mTouchListener);
    button.setOnTouchListener(mTouchListener);
    mSizeSpinner.setOnTouchListener(mTouchListener);
    mOutletEditText.setOnTouchListener(mTouchListener);
    //phoneEditText.setOnTouchListener(mTouchListener);
    //increaseButton.setOnTouchListener(mTouchListener);
    //decreaseButton.setOnTouchListener(mTouchListener);
}

// Get Image from Gallery
private void getImageFromGallery() {
    int READ_EXTERNAL_STORAGE = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (EditorActivity.this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            EditorActivity.this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);
            return;
        }
    }

    try {
        Intent intent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.INTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(intent, 100);
    } catch (Exception exp) {
        Log.i("Error", exp.toString());
    }

}

/**
private void selectImage(Context context) {
    final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("Choose your profile picture");

    builder.setItems(options, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int item) {

            if (options[item].equals("Take Photo")) {
                Intent takePicture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(takePicture, 0);

            } else if (options[item].equals("Choose from Gallery")) {
                Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(pickPhoto , 1);

            } else if (options[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == 100 && resultCode == RESULT_OK) {

        Uri selectedImage = data.getData();
        imageView.setImageURI(selectedImage);

        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
            imageByteArray = DbBitmapUtility.getBytes(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


/**
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode != RESULT_CANCELED) {
        switch (requestCode) {
            case 0:
                if (resultCode == RESULT_OK && data != null) {
                    Bitmap selectedImage = (Bitmap) data.getExtras().get("data");
                    imageView.setImageBitmap(selectedImage);
                }

                break;
            case 1:
                if (resultCode == RESULT_OK && data != null) {
                    Uri selectedImage = data.getData();
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    if (selectedImage != null) {
                        Cursor cursor = getContentResolver().query(selectedImage,
                                filePathColumn, null, null, null);
                        if (cursor != null) {
                            cursor.moveToFirst();

                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            String picturePath = cursor.getString(columnIndex);
                            imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
                            cursor.close();
                        }
                    }

                }
                break;
        }
    }
}
*/

    /**
     * Setup the dropdown spinner that allows the user to select the gender of the livestock.
     */
    private void setupSpinner() {
        // Create adapter for spinner. The list options are from the String array it will use
        // the spinner will use the default layout
        ArrayAdapter genderSpinnerAdapter = ArrayAdapter.createFromResource(this,
                R.array.array_gender_options, android.R.layout.simple_spinner_item);

        // Specify dropdown layout style - simple list view with 1 item per line
        genderSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);

        // Apply the adapter to the spinner
        mSizeSpinner.setAdapter(genderSpinnerAdapter);

        // Set the integer mSelected to the constant values
        mSizeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String selection = (String) parent.getItemAtPosition(position);
                if (!TextUtils.isEmpty(selection)) {
                    if (selection.equals(getString(R.string.big_cylinder))) {

                        mSize = brandsEntry.BIG_CYLINDER; // 13kg
                    } else if (selection.equals(getString(R.string.medium_cylinder))) {
                        mSize = brandsEntry.MEDIUM_CYLINDER; // 6kg
                    } else {
                        mSize = brandsEntry.SMALL_CYLINDER; // 3kg
                    }
                }
            }

            // Because AdapterView is an abstract class, onNothingSelected must be defined
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                mSize = 0; // Unknown
            }
        });
    }


private void insertAction() {
    String nameString = mNameEditText.getText().toString().trim();
    String outletString = mOutletEditText.getText().toString().trim();
    String mSize = mSizeSpinner.getSelectedItem().toString().trim();
    String priceString = mPriceEditText.getText().toString().trim();
    //String String = mPriceEditText.getText().toString().trim();
    //int mSize = Integer.parseInt(sizeString);
    int price = Integer.parseInt(priceString);

    //GasDbHelper mGasDbHelper = new GasDbHelper(this);

    //SQLiteDatabase database = mGasDbHelper.getWritableDatabase();
    //Uri newUri = getContentResolver().insert(DairyEntry.CONTENT_URI, values);
    // Default Image if the user has no image for the medicine.
    byte[] defaultImage = DbBitmapUtility.getImage(this, R.drawable.safegas);
    //byte[] imageByteArray = imageView.getImageBitMap().toBitMap().trim();

    // Create a ContentValues object where column names are the keys,
    // and medicine attributes from the editor are the values.
    ContentValues values = new ContentValues();
    if (imageByteArray == null) {
        values.put(brandsEntry.COLUMN_IMAGE, defaultImage);
    } else {
        values.put(brandsEntry.COLUMN_IMAGE, imageByteArray);
    }

    values.put(brandsEntry.COLUMN_NAME, nameString);
    values.put(brandsEntry.VENDOR_OUTLET, outletString);
    values.put(brandsEntry.COLUMN_SIZE, mSize);
    values.put(brandsEntry.COLUMN_PRICE, price);


    // Insert a new pet into the provider, returning the content URI for the new pet.
    //Long newRowId = database.insert(brandsEntry.TABLE_NAME, null, values);
    Uri newUri = getContentResolver().insert(brandsEntry.CONTENT_URI, values);

    // Show a toast message depending on whether or not the insertion was successful
    if (newUri == null) {
        // If the new content URI is null, then there was an error with insertion.
        Toast.makeText(this, getString(R.string.editor_insert_failed),
                Toast.LENGTH_SHORT).show();
    } else {
        // Otherwise, the insertion was successful and we can display a toast.
        Toast.makeText(this, getString(R.string.editor_insert_successful),
                Toast.LENGTH_LONG).show();
    }
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu options from the res/menu/menu_editor.xml file.
    // This adds menu items to the app bar.
    getMenuInflater().inflate(R.menu.menu_editor, menu);
    return true;
}

@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 new livestock into databaseinsertBrand();
            //close editor and return to catalog activity
            insertAction();
            displayBrands();
            //finish();
            return true;
        // Respond to a click on the "Delete" menu option
        case R.id.action_delete:
            // Do nothing for now
            return true;
        // Respond to a click on the "Up" arrow button in the app bar
        case android.R.id.home:
            // Navigate back to parent activity (CatalogActivity)
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

private void displayBrands(){
    Intent vendorIntent= new Intent(EditorActivity.this, Brands.class);
    startActivity(vendorIntent);
    Log.i("MainActivity","Login to OkoaGas");
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // Since the editor shows all brand attributes, define a projection that contains
    // all columns from the Brands table
    String[] projection = {
            brandsEntry._ID,
            brandsEntry.COLUMN_NAME,
            brandsEntry.COLUMN_SIZE,
            brandsEntry.COLUMN_PRICE,
            //brandsEntry.COLUMN_SIZE,
            brandsEntry.VENDOR_OUTLET,
            brandsEntry.COLUMN_IMAGE,
    };

    // This loader will execute the ContentProvider's query method on a background thread
    return new CursorLoader(this,   // Parent activity context
            mCurrentBrandUri,         // Query the content URI for the current medicine
            projection,             // Columns to include in the resulting Cursor
            null,                   // No selection clause
            null,                   // No selection arguments
            null);                  // Default sort order
}

//String phone;

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    // Bail early if the cursor is null or there is less than 1 row in the cursor
    if (cursor == null || cursor.getCount() < 1) {
        return;
    }

    // Proceed with moving to the first row of the cursor and reading data from it
    // (This should be the only row in the cursor)
    if (cursor.moveToFirst()) {
        // Find the columns of medicine attributes that we're interested in
        int nameColumnIndex = cursor.getColumnIndex(brandsEntry.COLUMN_NAME);
        int priceColumnIndex = cursor.getColumnIndex(brandsEntry.COLUMN_PRICE);
        int imageColumnIndex = cursor.getColumnIndex(brandsEntry.COLUMN_IMAGE);
        int sizeColumnIndex = cursor.getColumnIndex(brandsEntry.COLUMN_SIZE);
        int supplierColumnIndex = cursor.getColumnIndex(brandsEntry.VENDOR_OUTLET);
        //int phoneColumnIndex = cursor.getColumnIndex(MedicineEntry.COLUMN_PHONE);

        // Extract out the value from the Cursor for the given column index
        String name = cursor.getString(nameColumnIndex);
        double price = cursor.getDouble(priceColumnIndex);
        imageByteArray = cursor.getBlob(imageColumnIndex);
        Bitmap image = DbBitmapUtility.getImage(imageByteArray);
        int size = cursor.getInt(sizeColumnIndex);
        String outlet = cursor.getString(supplierColumnIndex);
        //phone = cursor.getString(phoneColumnIndex);

        // Update the views on the screen with the values from the database
        mNameEditText.setText(name);
        mPriceEditText.setText(Double.toString(price));
        imageView.setImageBitmap(image);
        //mSizeSpinner.setText(String.valueOf(size));
        mSizeSpinner.setSelection(size);
        mOutletEditText.setText(outlet);
        //phoneEditText.setText(phone);
        //mWeightEditText.setText(Integer.toString(weight));
        //mGenderSpinner.setSelection(gender);
        // Gender is a dropdown spinner, so map the constant value from the database
        // into one of the dropdown options (0 is Unknown, 1 is Male, 2 is Female).
        // Then call setSelection() so that option is displayed on screen as the current selection.
        switch (size) {
            case brandsEntry.SMALL_CYLINDER:
                mSizeSpinner.setSelection(3);
                break;
            case brandsEntry.MEDIUM_CYLINDER:
                mSizeSpinner.setSelection(6);
                break;
            default:
                mSizeSpinner.setSelection(12);
                break;
        }
    }
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    // If the loader is invalidated, clear out all the data from the input fields.
    mNameEditText.setText("");
    mPriceEditText.setText("");
    imageView.setImageResource(0);
    mSizeSpinner.setSelection(0);
    mOutletEditText.setText("");
    //phoneEditText.setText("");
}

}

Android OS Version: 4.1.1

NatBob avatar May 02 '21 19:05 NatBob

This is ud845-Pets app right but you edit it? https://github.com/AmrDeveloper/Android/tree/master/Basics%20Nanodegree/ud845-Pets

AmrDeveloper avatar May 04 '21 19:05 AmrDeveloper

No it's the inventory app but borrowing some functionalities from the pets app.

However, I actually found where the error was emanating and fixed it. Thanks

On Tue, May 4, 2021, 22:02 Amr Hesham @.***> wrote:

This is ud845-Pets app right but you edit it?

https://github.com/AmrDeveloper/Android/tree/master/Basics%20Nanodegree/ud845-Pets

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AmrDeveloper/Android/issues/1#issuecomment-832172664, or unsubscribe https://github.com/notifications/unsubscribe-auth/APLDETYFUI5YX5MS5T4Z5TLTMBACZANCNFSM43Z2T4CQ .

NatBob avatar May 05 '21 09:05 NatBob