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;
}
}