-2

I'm working on implementing a e-commerce app, wherein i'm trying to add the selected item into the cart(here my database) using sqlite. I'm getting null pointer exception. My app crashes when i click on add to cart button.

Here's my logcat

04-04 00:52:22.626 17150-17150/com.example.rahul.smartshopping E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.example.rahul.smartshopping, PID: 17150
                                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
                                                                                 at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:269)
                                                                                 at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
                                                                                 at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
                                                                                 at com.example.rahul.smartshopping.helper.DatabaseHandler.getQuantity(DatabaseHandler.java:168)
                                                                                 at com.example.rahul.smartshopping.fragments.SearchResultsAdapter$MyPersonalClickListener.onClick(SearchFragment.java:455)
                                                                                 at android.view.View.performClick(View.java:5205)
                                                                                 at android.view.View$PerformClick.run(View.java:21162)
                                                                                 at android.os.Handler.handleCallback(Handler.java:739)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                 at android.os.Looper.loop(Looper.java:148)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5422)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Here's my Database Handler:

package com.example.rahul.smartshopping.helper;

public class DatabaseHandler extends SQLiteOpenHelper {

// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "mart";

// Cart table name
private static final String TABLE_CART = "cart";

// Cart Table Columns names
private static final String PRODUCT_ID = "product_id";
private static final String PRODUCT_NAME = "product_name";
private static final String PRODUCT_CATEGORY_ID = "category_id";
private static final String PRODUCT_PRICE = "product_price";
private static final String PRODUCT_QUANTITY = "product_quantity";
private static final String PRODUCT_WEIGHT = "product_weight";
private static final String PRODUCT_TOTAL_PRICE = "product_total_price";

public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_CART_TABLE = "CREATE TABLE " + TABLE_CART + "("
            + PRODUCT_ID + " LONG PRIMARY KEY," + PRODUCT_NAME + " TEXT," + PRODUCT_CATEGORY_ID + " INTEGER,"
            + PRODUCT_PRICE + " DOUBLE," + PRODUCT_QUANTITY + " INTEGER, " + PRODUCT_WEIGHT + "DOUBLE, " + PRODUCT_TOTAL_PRICE + "DOUBLE " + ")";
    db.execSQL(CREATE_CART_TABLE);
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_CART);

    // Create tables again
    onCreate(db);
}

/**
 * All CRUD(Create, Read, Update, Delete) Operations
 */

// Adding new contact
public void addProduct(CartConfig cart) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(PRODUCT_ID, cart.getProductID()); // Product Id
    values.put(PRODUCT_NAME, cart.getProductName()); // Product Name
    values.put(PRODUCT_CATEGORY_ID, cart.getProductCategoryID());
    values.put(PRODUCT_PRICE, cart.getProductPrice());
    values.put(PRODUCT_QUANTITY, cart.getProductQuantity());
    values.put(PRODUCT_WEIGHT, cart.getProductWeight());
    values.put(PRODUCT_TOTAL_PRICE, cart.getProductTotalPrice());

    // Inserting Row
    db.insert(TABLE_CART, null, values);
    db.close(); // Closing database connection
}

// Getting single product
CartConfig getProduct(long id) {
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(TABLE_CART, new String[] { PRODUCT_ID,
                    PRODUCT_NAME, PRODUCT_CATEGORY_ID, PRODUCT_PRICE, PRODUCT_QUANTITY, PRODUCT_WEIGHT, PRODUCT_TOTAL_PRICE }, PRODUCT_ID + "=?",
            new String[] { String.valueOf(id) }, null, null, null, null);
    if (cursor != null)
        cursor.moveToFirst();

    CartConfig cart = new CartConfig( Long.parseLong(cursor.getString(0)), cursor.getString(1),
            Integer.parseInt(cursor.getString(2)), Double.parseDouble(cursor.getString(3)), Integer.parseInt(cursor.getString(4)),
            Double.parseDouble(cursor.getString(5)), Double.parseDouble(cursor.getString(6)));
    // return contact
    return cart;
}

// Getting All Products
public List<CartConfig> getAllProducts() {
    List<CartConfig> productList = new ArrayList<CartConfig>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_CART;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            CartConfig cart = new CartConfig();
            cart.setProductID(Long.parseLong(cursor.getString(0)));
            cart.setProductName(cursor.getString(1));
            cart.setProductCategoryID(Integer.parseInt(cursor.getString(2)));
            cart.setProductPrice(Double.parseDouble(cursor.getString(3)));
            cart.setProductQuantity(Integer.parseInt(cursor.getString(4)));
            cart.setProductWeight(Double.parseDouble(cursor.getString(5)));
            cart.setProductTotalPrice(Double.parseDouble(cursor.getString(6)));
            // Adding product to list
            productList.add(cart);
        } while (cursor.moveToNext());
    }

    // return product list
    return productList;
}

// Updating single Product
public int updateProduct(CartConfig cart) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(PRODUCT_ID, cart.getProductID()); // Product Id
    values.put(PRODUCT_NAME, cart.getProductName()); // Product Name
    values.put(PRODUCT_CATEGORY_ID, cart.getProductCategoryID());
    values.put(PRODUCT_PRICE, cart.getProductPrice());
    values.put(PRODUCT_QUANTITY, cart.getProductQuantity());
    values.put(PRODUCT_WEIGHT, cart.getProductWeight());
    values.put(PRODUCT_TOTAL_PRICE, cart.getProductTotalPrice());

    // updating row
    return db.update(TABLE_CART, values, PRODUCT_ID + " = ?",
            new String[] { String.valueOf(cart.getProductID()) });
}

// Deleting single product
public void deleteProduct(CartConfig cart) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_CART, PRODUCT_ID + " = ?",
            new String[]{String.valueOf(cart.getProductID())});
    db.close();
}


// Getting Products Count
public int getProductsCount() {
    String countQuery = "SELECT  * FROM " + TABLE_CART;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(countQuery, null);
    cursor.close();

    // return count
    return cursor.getCount();
}

public Cursor getQuantity(long id) {
    SQLiteDatabase db = this.getReadableDatabase();
    String quantity = "SELECT " + PRODUCT_QUANTITY +"FROM " + TABLE_CART + " WHERE " + PRODUCT_ID +" = " + id;
    Cursor c = db.rawQuery(quantity, null);
    db.close();
    return c;
}

public void updateQuantity(int tempQty, Double price, Double tempValue, long id) {
    SQLiteDatabase db = this.getWritableDatabase();
    String update = "UPDATE " + TABLE_CART + "SET " + tempQty+1 + "," + PRODUCT_TOTAL_PRICE + " = " + price + tempValue +
            "WHERE " + PRODUCT_ID + " = " + id;
}

}

Here's my Search Fragment.java class

package com.example.rahul.smartshopping.fragments;

public class SearchFragment extends Fragment {

View myFragmentView;
SearchView search;
ImageButton buttonBarcode;
ImageButton buttonAudio;
Typeface type;
ListView searchResults;
String found = "N";

//This arraylist will have data as pulled from server. This will keep cumulating.
ArrayList<Product> productResults = new ArrayList<Product>();
//Based on the search string, only filtered products will be moved here from productResults
ArrayList<Product> filteredProductResults = new ArrayList<Product>();

public SearchFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Context context = getActivity();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    //get the context of the HomeScreen Activity
    final WelcomeActivity activity = (WelcomeActivity) getActivity();

    //define a typeface for formatting text fields and listview.

    type = Typeface.createFromAsset(activity.getAssets(), "fonts/book.ttf");
    myFragmentView = inflater.inflate(R.layout.fragment_search, container, false);

    search = (SearchView) myFragmentView.findViewById(R.id.searchView1);
    search.setQueryHint("Start typing to search...");

    searchResults = (ListView) myFragmentView.findViewById(R.id.listview_search);
    buttonBarcode = (ImageButton) myFragmentView.findViewById(R.id.imageButton2);
    buttonAudio = (ImageButton) myFragmentView.findViewById(R.id.imageButton1);

    //this part of the code is to handle the situation when user enters any search criteria, how should the
    //application behave?

    buttonBarcode.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            startActivityForResult(new Intent(activity, Barcode.class),1);
        }
    });

    buttonAudio.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            // Specify free form input
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
            intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"Please start speaking");
            intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH);
            startActivityForResult(intent, 2);
        }
    });


    //this part of the code is to handle the situation when user enters any search criteria, how should the
    //application behave?

    search.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            // TODO Auto-generated method stub

            //Toast.makeText(activity, String.valueOf(hasFocus),Toast.LENGTH_SHORT).show();
        }
    });

    search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

        @Override
        public boolean onQueryTextSubmit(String query) {
            // TODO Auto-generated method stub

            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {

            if (newText.length() > 3) {

                searchResults.setVisibility(myFragmentView.VISIBLE);
                myAsyncTask m = (myAsyncTask) new myAsyncTask().execute(newText);
            } else {

                searchResults.setVisibility(myFragmentView.INVISIBLE);
            }


            return false;
        }

    });
    return myFragmentView;
}

//this captures the result from barcode and populates in the searchView.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    //this requestCode is for handling the barcode activity.
    if(requestCode==1)
    {
        String barcode=data.getStringExtra("BARCODE");
        if (barcode.equals("NULL"))
        {
            //that means barcode could not be identified or user pressed the back button
            //do nothing
        }
        else
        {
            search.setQuery(barcode, true);
            search.setIconifiedByDefault(false);
        }
    }

    //this requestCode is for speechRecognizer. Only this part of the code needs to be added for
    //the implementation of voice to text functionality.

    if (requestCode == 2) {
        ArrayList<String> results;
        results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
        //Toast.makeText(this, results.get(0), Toast.LENGTH_SHORT).show();

        //if the name has an ' then the SQL is failing. Hence replacing them.
        String text = results.get(0).replace("'","");
        search.setQuery(text, true);
        search.setIconifiedByDefault(false);
    }

}

//this filters products from productResults and copies to filteredProductResults based on search text

public void filterProductArray(String newText) {

    String pName;

    filteredProductResults.clear();
    for (int i = 0; i < productResults.size(); i++) {
        pName = productResults.get(i).getProductName().toLowerCase();
        if (pName.contains(newText.toLowerCase()) ||
                productResults.get(i).getProductBarcode().contains(newText)) {
            filteredProductResults.add(productResults.get(i));

        }
    }

}

//in this myAsyncTask, we are fetching data from server for the search string entered by user.
class myAsyncTask extends AsyncTask<String, Void, String> {
    JSONParser jParser;
    JSONArray productList;
    String url = new String();
    String textSearch;
    ProgressDialog pd;


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        productList = new JSONArray();
        jParser = new JSONParser();
        pd = new ProgressDialog(getActivity());
        pd.setCancelable(false);
        pd.setMessage("Searching...");
        pd.getWindow().setGravity(Gravity.CENTER);
        pd.show();
        Log.e("On PreExecute", "Hey");
    }

    @Override
    protected String doInBackground(String... sText) {

        url = "http://192.168.0.5:8080/android/db_search_product.php?pname='" + sText[0] + "'";
        Log.e("URL", "" + url);
        String returnResult = getProductList(url);
        this.textSearch = sText[0];
        Log.e("Return result", "" + returnResult);
        return returnResult;

    }

    public String getProductList(String url) {

        Product tempProduct = new Product();
        String matchFound = "N";
        //productResults is an arraylist with all product details for the search criteria
        //productResults.clear();
        Log.e("get Product details", "Hey");
        try {
            Log.e("try block", "");
            JSONObject json = jParser.getJSONFromUrl(url);
            Log.e("JSONObject", "" + json.toString());

            productList = json.getJSONArray("product");
            Log.e("productList", "" + productList.toString());

            //parse date for dateList
            for (int i = 0; i < productList.length(); i++) {
                tempProduct = new Product();

                JSONObject obj = productList.getJSONObject(i);

                /*tempProduct.setProductCode(obj.getString("ProductCode"));
                tempProduct.setProductName(obj.getString("ProductName"));
                tempProduct.setProductGrammage(obj.getString("ProductGrammage"));
                tempProduct.setProductBarcode(obj.getString("ProductBarcode"));
                tempProduct.setProductDivision(obj.getString("ProductCatCode"));
                tempProduct.setProductDepartment(obj.getString("ProductSubCode"));
                tempProduct.setProductMRP(obj.getString("ProductMRP"));
                tempProduct.setProductBBPrice(obj.getString("ProductBBPrice"));*/
                //my values
                Log.e("Product id",""+obj.getString("product_id"));
                Log.e("Category id",""+obj.getString("category_id"));
                Log.e("Product name", ""+obj.getString("product_name"));
                tempProduct.setProductID(obj.getString("product_id"));
                tempProduct.setProductName(obj.getString("product_name"));
                tempProduct.setCategoryID(obj.getString("category_id"));
                tempProduct.setProductPrice(obj.getString("price"));
                tempProduct.setProductWeight(obj.getString("weight"));
                Log.e("Temp product", "" + tempProduct.toString());

                Log.e("PID", ""+tempProduct.getProductID());
                Log.e("CID", "" + tempProduct.getCategoryID());
                Log.e("PName", "" + tempProduct.getProductName());

                //check if this product is already there in productResults, if yes, then don't add it again.
                matchFound = "N";

                for (int j = 0; j < productResults.size(); j++) {

                    if (productResults.get(j).getProductID().equals(tempProduct.getProductID())) {
                        matchFound = "Y";
                    }
                }

                if (matchFound == "N") {
                    productResults.add(tempProduct);
                }

            }

            return ("OK");

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("Exception", e.toString());
            return ("Exception Caught");
        }
    }

    @Override
    protected void onPostExecute(String result) {

        Log.e("On PostExecute", "Hey");

        super.onPostExecute(result);

        if (result.equalsIgnoreCase("Exception Caught")) {
            Toast.makeText(getActivity(), "Unable to connect to server,please try later", Toast.LENGTH_LONG).show();

            pd.dismiss();
        } else {


            //calling this method to filter the search results from productResults and move them to
            //filteredProductResults
            filterProductArray(textSearch);
            searchResults.setAdapter(new SearchResultsAdapter(getActivity(), filteredProductResults));
            pd.dismiss();
        }
    }

}

}

class SearchResultsAdapter extends BaseAdapter {
    private LayoutInflater layoutInflater;

    private ArrayList<Product> productDetails = new ArrayList<Product>();
    int count;
    Typeface type;
    Context context;

    //constructor method
    public SearchResultsAdapter(Context context, ArrayList<Product> product_details) {

        layoutInflater = LayoutInflater.from(context);

        this.productDetails = product_details;
        this.count = product_details.size();
        this.context = context;
        type = Typeface.createFromAsset(context.getAssets(), "fonts/book.ttf");

    }

    @Override
    public int getCount() {
        return count;
    }

    @Override
    public Object getItem(int arg0) {
        return productDetails.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        Product tempProduct = productDetails.get(position);

        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.list_search, null);
            holder = new ViewHolder();
            holder.product_name = (TextView) convertView.findViewById(R.id.product_name);
            holder.product_mrp = (TextView) convertView.findViewById(R.id.product_mrp);
            holder.product_mrpvalue = (TextView) convertView.findViewById(R.id.product_mrpvalue);
            holder.product_weight = (TextView) convertView.findViewById(R.id.product_weight);
            holder.product_weight_value = (TextView) convertView.findViewById(R.id.product_weight_value);
            holder.product_category_id = (TextView) convertView.findViewById(R.id.product_category_id);
            holder.getProduct_category_id_value = (TextView) convertView.findViewById(R.id.product_category_id_value);
            holder.addToCart = (Button) convertView.findViewById(R.id.add_cart);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }


        holder.product_name.setText(tempProduct.getProductName());
        holder.product_name.setTypeface(type);

        holder.product_mrp.setTypeface(type);

        holder.product_mrpvalue.setText(tempProduct.getProductPrice());
        holder.product_mrpvalue.setTypeface(type);

        holder.product_weight.setTypeface(type);

        holder.product_weight_value.setText(tempProduct.getProductWeight());
        holder.product_weight_value.setTypeface(type);

        holder.product_category_id.setTypeface(type);

        holder.getProduct_category_id_value.setText(tempProduct.getCategoryID());
        holder.getProduct_category_id_value.setTypeface(type);

        holder.addToCart.setOnClickListener(new MyPersonalClickListener("button_addtocart", tempProduct, context));

        return convertView;
    }

This is a customized listener

    public class MyPersonalClickListener extends Activity implements View.OnClickListener
    {

        String button_name;
        Product prod_name;
        int tempQty;
        double tempValue;
        SQLiteDatabase sqLite;
        DatabaseHandler db;
        Context context;

        //constructor method
        public MyPersonalClickListener(String button_name, Product prod_name, Context context)
        {
            this.prod_name = prod_name;
            this.button_name = button_name;
            this.context = context;
        }

        @Override
        public void onClick(View v)
        {

            // in this section, we are going to add items to cart
            //if the item is already there in cart, then increase the quantity by 1, else add the item to cart
            //if the quantity of the item has reached 10, then do nothing ---this is just a specific logic where
            //i did not want any item with quantity more than 10, but if you choose not to, then just comment out
            //the code.
            //sqLite=context.openOrCreateDatabase("mart", context.MODE_PRIVATE, null);
            db = new DatabaseHandler(this);
            Log.e("ProductID", "" + prod_name.getProductID());

            //Cursor cc = sqLite.rawQuery("SELECT quantity FROM CART WHERE product_id ="+Long.parseLong(prod_name.getCategoryID()), null);
            Cursor cc = db.getQuantity(Long.parseLong(prod_name.getCategoryID()));

            if (cc.getCount()== 0)
            {
                //product not already there in cart..add to cart
                /*sqLite.execSQL("INSERT INTO CART (product_id, category_id, product_name, quantity"+
                        ", price, total_price, weight) VALUES("+
                        prod_name.getProductID()+",'"+ prod_name.getCategoryID()+ "','" +
                        prod_name.getProductName()+"','"+ 1 +"',"+
                        Integer.parseInt(prod_name.getProductPrice())+","+ Integer.parseInt(prod_name.getProductPrice())+","+
                        Integer.parseInt(prod_name.getProductWeight())+")");*/
                db.addProduct(new CartConfig(Long.parseLong(prod_name.getProductID()), prod_name.getProductName(),
                        Integer.parseInt(prod_name.getCategoryID()), Double.parseDouble(prod_name.getProductPrice()),
                        1,Double.parseDouble(prod_name.getProductWeight()),
                        Double.parseDouble(prod_name.getProductValue())));

                Toast.makeText(context,"Item "+prod_name.getProductName()+" added to Cart", Toast.LENGTH_LONG).show();
            }
            else
            {

                //product already there in cart
                if(cc.moveToFirst())
                {
                    do{
                        tempQty=cc.getInt(0);
                        tempValue = cc.getInt(1);
                    }while(cc.moveToNext());
                }

                if (tempQty < 10)
                {
                    /*sqLite.execSQL("UPDATE CART SET quantity = "+ (tempQty+1)+",total_price = "+
                            (Integer.parseInt(prod_name.getProductPrice())+tempValue)+" WHERE product_id ="+
                            prod_name.getProductID());*/
                    db.updateQuantity(tempQty, Double.parseDouble(prod_name.getProductPrice()), tempValue, Long.parseLong(prod_name.getCategoryID()));

                    Toast.makeText(context,"Item "+prod_name.getProductName()+" added to Cart", Toast.LENGTH_LONG).show();
                }
            }

            sqLite.close();

        }

    }

    static class ViewHolder {
        TextView product_name;
        TextView product_mrp;
        TextView product_mrpvalue;
        //TextView product_bb;
        //TextView product_bbvalue;
        //TextView product_savings;
        //TextView product_savingsvalue;
        //TextView qty;
        //TextView product_value;
        TextView product_weight;
        TextView product_weight_value;
        TextView product_category_id;
        TextView getProduct_category_id_value;
        Button addToCart;

    }
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245

1 Answers1

3

This is your problem:

new MyPersonalClickListener(...)

and

class MyPersonalClickListener extends Activity

You cannot instantiate activities with new. They don't get correctly set up and you cannot use such instances for things you'd want an Activity for, such as to be used as Context.

Remove the extends Activity and use the context member variable you're already passing in where you need a Context such as passing to your DatabaseHandler constructor.

laalto
  • 150,114
  • 66
  • 286
  • 303