1

I am creating an inventory app.It has a fab button an menu button with two items.Everything works fine but whenever I am trying to insert a new product through the item from the menu.It doesn't add immediately.

First I have to go back from the application or kill it and after when I enter again the the new product with the dummy value is recorded there.I want to resolve the issue that when I add a new product it immediately add the data with values and I don't have to go back every time to see it is inserted.Also If added a new product using fab button the data I added previously using the insert item is being added and displayed. I have seen the notification uri and there is no error showing in the LOGCAT

ProductProvider.java

package com.example.bahubali.inventoryapp.data;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;



public class ProductProvider extends ContentProvider {

    //Tag for the log messages
    public static final String LOG_TAG = ProductProvider.class.getSimpleName();

    //Database helper that will provide access to the database.
    private ProductDbHelper mDbHelper;
    /** URI matcher code for the content URI for the product table */
    public static final int PRODUCTS = 100;

    /** URI matcher code for the content URI for a single product in the pets table */
    public static final int PRODUCT_ID = 101;



    /** URI matcher object to match a context URI to a corresponding code.
     * The input passed into the constructor represents the code to return for the root URI.
     * It's common to use NO_MATCH as the input for this case.
     */
    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    // Static initializer. This is run the first time anything is called from this class.
    static {
        // The calls to addURI() go here, for all of the content URI patterns that the provider
        // should recognize. All paths added to the UriMatcher have a corresponding code to return
        // when a match is found.

        sUriMatcher.addURI(ProductContract.CONTENT_AUTHORITY, ProductContract.PATH_PRODUCTS, PRODUCTS);

        // The content URI of the form "content://com.example.android.pets/pets/#" will map to the
        // integer code {@link #PETS_ID}. This URI is used to provide access to ONE single row
        // of the pets table.

     
        sUriMatcher.addURI(ProductContract.CONTENT_AUTHORITY, ProductContract.PATH_PRODUCTS + "/#", PRODUCT_ID);
    }


    /**
     * Initialize the provider and the database helper object.
     */
    @Override
    public boolean onCreate()
    {
        /*
         * Creates a new helper object. This method always returns quickly.
         * until SQLiteOpenHelper.getWritableDatabase is called
         */
        mDbHelper = new ProductDbHelper(getContext());
        return true;
    }

    /*
    *Perform the query to the given URI.Use the given projection,selection,selectionArgs, and sort
    * order.
     */
    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        // Get readable database
        SQLiteDatabase database = mDbHelper.getReadableDatabase();

        // This cursor will hold the result of the query
        Cursor cursor ;

        // Figure out if the URI matcher can match the URI to a specific code
        int match = sUriMatcher.match(uri);

        switch (match) {
            case PRODUCTS:
                // For the PRODUCTS code, query the pets table directly with the given
                // projection, selection, selection arguments, and sort order. The cursor
                // could contain multiple rows of the products table.
                //  Perform database query on pets
                cursor = database.query(ProductContract.ProductEntry.TABLE_NAME,
                        projection,selection,selectionArgs,null,null,sortOrder);
                break;

            case PRODUCT_ID:
                // For the PRODUCT_ID code, extract out the ID from the URI.
                // For an example URI such as "content://com.example.android.products/products/3",
                // the selection will be "_id=?" and the selection argument will be a
                // String array containing the actual ID of 3 in this case.
                //
                // For every "?" in the selection, we need to have an element in the selection
                // arguments that will fill in the "?". Since we have 1 question mark in the
                // selection, we have 1 String in the selection arguments' String array.
                selection = PRODUCT_ID + "=?";
                selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };

                // This will perform a query on the products table where the _id equals 3 to return a
                // Cursor containing that row of the table.
                cursor = database.query(ProductContract.ProductEntry.TABLE_NAME, 
                                                                    projection,
                                                                        selection,
                                                                    selectionArgs,
                                                                    null,
                                                                    null,   
                                                                    sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Cannot query unknown URI " + uri);
        }
        //Set notification URI to the cursor,
        //So we know what content URI the cursor was created for.
        cursor.setNotificationUri(getContext().getContentResolver(),uri);
        //If the data at this URI changes, then we need to update the cursor.
        return cursor;
    }

    /*
    *Insert a new data into the provider with the given Constructor.
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri,
                      @Nullable ContentValues contentValues) {
        final int match = sUriMatcher.match(uri);
        switch (match){
            case PRODUCTS:
                return insertProduct(uri,contentValues);

                default:
                    throw new IllegalArgumentException("Insertion is not supported for " +uri);
        }
    }

    /*
    Insert a product in the database with the given content values.Return the new content URI
    for that specific row in the database.
     */
    private Uri insertProduct(Uri uri, ContentValues contentValues){

        //Check that the name is not null
        String name = contentValues.getAsString(ProductContract.ProductEntry.COLUMN_PRODUCT_NAME);
        if (name == null){
            throw new IllegalArgumentException("Product requires a name");
        }

        //Check that the price is not null
        Integer price = contentValues.getAsInteger(ProductContract.ProductEntry.COLUMN_PRODUCT_PRICE);
        if (price != null && price < 0 ){
            throw new IllegalArgumentException("Product requires  valid price");
        }

        //Get writeable database
        SQLiteDatabase  database = mDbHelper.getWritableDatabase();

        //Insert the new product with the given values
        long id = database.insert(ProductContract.ProductEntry.TABLE_NAME,null,contentValues);

        //If the Id is -1, then the insertion failed.Log on an error to return null
        if (id == -1){
            Log.e(LOG_TAG,"Failed to insert a row" + uri);
            return null;
        }


        //Notify all listeners that the data has changed for the product content URI
        getContext().getContentResolver().notifyChange(uri,null);


        return ContentUris.withAppendedId(uri,id);
    }

    /*
   *Updates the data at the given selection and the selection arguments, with the new content
   * values.
    */
    @Override
    public int update(@NonNull Uri uri,
                      @Nullable ContentValues contentValues,
                      @Nullable String selection,
                      @Nullable String[] selectionArgs) {

        final int match = sUriMatcher.match(uri);
        switch (match) {
            case PRODUCTS:
                return updateProduct(uri, contentValues, selection, selectionArgs);
            case PRODUCT_ID:
                // For the PRODUCT_D code, extract out the ID from the URI,
                // so we know which row to update. Selection will be "_id=?" and selection
                // arguments will be a String array containing the actual ID.
                selection = ProductContract.ProductEntry._ID + "=?";
                selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
                return updateProduct(uri, contentValues, selection, selectionArgs);
            default:
                throw new IllegalArgumentException("Update is not supported for " + uri);
        }
    }

    /**
     * Update products in the database with the given content values. Apply the changes to the rows
     * specified in the selection and selection arguments (which could be 0 or 1 or more pets).
     * Return the number of rows that were successfully updated.
     */
    private int updateProduct(Uri uri,ContentValues contentValues,String selection,String[] selectionArgs){

        // If the {@link ProductEntry#COLUMN_PRODUCT_NAME} key is present,
        // check that the name value is not null.
        if (contentValues.containsKey(ProductContract.ProductEntry.COLUMN_PRODUCT_NAME)) {
            String name = contentValues.getAsString(ProductContract.ProductEntry.COLUMN_PRODUCT_NAME);
            if (name == null) {
                throw new IllegalArgumentException("Product requires a name");
            }
        }

        // If the {@link ProductEntry#COLUMN_PRODUCT_PRICE} key is present,
        // check that the price value is valid.
        if (contentValues.containsKey(ProductContract.ProductEntry.COLUMN_PRODUCT_PRICE)) {
            // Check that the weight is greater than or equal to 0 kg
            Integer price = contentValues.getAsInteger(ProductContract.ProductEntry.COLUMN_PRODUCT_PRICE);
            if (price!= null && price < 0) {
                throw new IllegalArgumentException("Product requires valid weight");
            }
        }

        // If there are no values to update, then don't try to update the database
        if (contentValues.size() == 0) {
            return 0;
        }

        // Otherwise, get writeable database to update the data
        SQLiteDatabase database = mDbHelper.getWritableDatabase();

        //perform the update on the database and the get the number of rows affected
        int rowsUpdated = database.update(ProductContract.ProductEntry.TABLE_NAME,contentValues,selection
                ,selectionArgs);

        //If 1 or more rows were updated, then notify all the listeners that the data at the
        //given URI has changed
        if (rowsUpdated != 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        //Return the no. of rows updated
        return rowsUpdated;
    }

    /*
    *Delete the data at the given selection and selection arguments.
     */
    @Override
    public int delete(@NonNull Uri uri,
                      @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        // Get writeable database
        SQLiteDatabase database = mDbHelper.getWritableDatabase();

        //Track the no. of rows  that were deleted
        int rowsDeleted;

        final int match = sUriMatcher.match(uri);
        switch (match) {
            case PRODUCTS:
                // Delete all rows that match the selection and selection args
              rowsDeleted = database.delete(ProductContract.ProductEntry.TABLE_NAME,selection,selectionArgs);
                break;
            case PRODUCT_ID:
                // Delete a single row given by the ID in the URI
                selection = ProductContract.ProductEntry._ID + "=?";
                selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
                rowsDeleted = database.delete(ProductContract.ProductEntry.TABLE_NAME,selection,selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Deletion is not supported for " + uri);
        }
        //If 1 or more rows were  deleted, then notify all listeners that the data at the given
        //given uri has changed
        if (rowsDeleted != 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        return rowsDeleted;
    }

    /*
   *Return the  MIME type of data for the content URI.
    */
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match){
            case PRODUCTS:
                return ProductContract.ProductEntry.CONTENT_LIST_TYPE;
            case PRODUCT_ID:
                return ProductContract.ProductEntry.CONTENT_ITEM_TYPE;
            default:
                throw new IllegalStateException("UNKNOWN URI" + uri + " with match" + match);
        }
    }

 }



   
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Vishal
  • 41
  • 11
  • I can not see the Insert routine but where are you closing the cursor and the database db.close(); cursor.close(); – Vector Oct 25 '17 at 06:26
  • Hey @Grendel I am not closing them, is it necessary? Since I implement the content Uri, I learned from the nanodegree that it is not req. or maybe I am wrong can you clarify that and also insert Routine? Are you talking about the insert and insert product method? – Vishal Oct 27 '17 at 05:12
  • take a look at this link https://stackoverflow.com/questions/2225221/closing-database-connections-in-java – Vector Oct 27 '17 at 16:37

0 Answers0