3

hey I'm a bit of a noob at creating Android apps , this is only my second one. I need to create an app to scan barcodes and save the info onto a database.

I created a product database using zxing barcode scanner and Sqllite database as in this article Zxing app and SQLite database. However when i click on the add product button after the product form is filled. A message box saying my app has unfortunately stopped pops up.The scanning and filling works but I don't think the database operations works.

Here are my pages for adding product form and the database operations.

StartMenu.java

package com.example.barcodedatabaseapp;

import java.math.BigDecimal;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class StartMenu extends Activity {

    static final class ProductData {
        String barcode;
        String format;
        String title;
        String Others;
        BigDecimal Price;
        }

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_menu);
        Button addButton=(Button) findViewById(R.id.button1);
        addButton.setOnClickListener(new OnClickListener(){
                public void onClick(View v)
                {
                startActivity(new Intent(StartMenu.this,AddProduct.class));
                }

            });

    }


}

AddProduct.java

package com.example.barcodedatabaseapp;

import java.math.BigDecimal;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.example.barcodeda  tabaseapp.StartMenu.ProductData;

public class AddProduct extends Activity implements OnClickListener {           

    private static final int REQUEST_BARCODE = 0;
    private static final ProductData mProductData = new ProductData();
    EditText mBarcodeEdit;
    EditText mFormatEdit;
    EditText mTitleEdit;
    EditText mPriceEdit;
    private Button mScanButton;
    private Button mAddButton;
    ProductDatabase mProductDb;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_product);
    mBarcodeEdit = (EditText) findViewById(R.id.barcodeEdit);
        mFormatEdit = (EditText) findViewById(R.id.codeFormatEdit);
        mTitleEdit = (EditText) findViewById(R.id.titleEdit);
        mPriceEdit = (EditText) findViewById(R.id.priceEdit);
        mScanButton = (Button) findViewById(R.id.scanButton);
        mScanButton.setOnClickListener(this);
        mAddButton = (Button) findViewById(R.id.addButton2);
        mAddButton.setOnClickListener(this);

}
  public void onClick(View v) {

               switch (v.getId()) {
                case R.id.scanButton:
                    Intent intent = new Intent("com.google.zxing.client.android.SCAN");
                    intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
                    startActivityForResult(intent, REQUEST_BARCODE);
                    break;


                case R.id.addButton2:
                    String barcode = mBarcodeEdit.getText().toString();
                    String format = mFormatEdit.getText().toString();
                    String title = mTitleEdit.getText().toString();
                    String price = mPriceEdit.getText().toString();

                    String errors = validateFields(barcode, format, title, price);
                    if (errors.length() > 0) {
                        showInfoDialog(this, "Please fix errors", errors);
                    } else {
                        mProductData.barcode = barcode;
                        mProductData.format = format;
                        mProductData.title = title;
                        mProductData.Price = new BigDecimal(price);

                  mProductDb.insert(mProductData);
                        showInfoDialog(this, "Success", "Product saved successfully");
                        resetForm();
                    }
                    break;
                }   
  }

    private void showInfoDialog(Context context, String title, String information) {
        new AlertDialog.Builder (context)
        .setMessage(information)
        .setTitle(title)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {


            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

            }
        }).show();  
    }
    private void resetForm() {
                      mBarcodeEdit.getText().clear();
          mFormatEdit.getText().clear();
          mTitleEdit.getText().clear();
          mPriceEdit.getText().clear();
    }
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == REQUEST_BARCODE) {
            if (resultCode == RESULT_OK) {
                String barcode = intent.getStringExtra("SCAN_RESULT");
                mBarcodeEdit.setText(barcode);

                String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
                mFormatEdit.setText(format);
            } else if (resultCode == RESULT_CANCELED) {
                finish();
            }
        }
    }

private static String validateFields(String barcode, String format, 
    String title, String price) {
    StringBuilder errors = new StringBuilder();

    if (barcode.matches("^\\s*$")) {
        errors.append("Barcode required\n");
    }

    if (format.matches("^\\s*$")) {
        errors.append("Format required\n");
    }

    if (title.matches("^\\s*$")) {
        errors.append("Title required\n");
    }

    if (!price.matches("^-?\\d+(.\\d+)?$")) {
        errors.append("Need numeric price\n");
    }

    return errors.toString();
    }
}

ProductDatabase.java

package com.example.barcodedatabaseapp;

import java.math.BigDecimal;

import com.example.barcodedatabaseapp.StartMenu.ProductData;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class ProductDatabase {
          private static final String PRODUCT_TABLE="products";
          private static final String DATABASE_NAME="spot_pay.db";
          private static final int DATABASE_VERSION=1;
              private static final BigDecimal ONE_HUNDRED =new BigDecimal(100);

          private SQLiteDatabase db;

          private static class ProductDatabaseHelper extends SQLiteOpenHelper {

                private static final String TAG = null;

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

                }

                @Override
                public void onCreate(SQLiteDatabase db) {            
                       StringBuilder sql = new StringBuilder();

                        sql.append("create table ").append(PRODUCT_TABLE)
                            .append("(  ")
                            .append("   _id integer primary key,")
                            .append("   barcode text,")
                            .append("   format text,")
                            .append("   title text,")
                            .append("   price currency")
                            .append(")  ");

                        db.execSQL(sql.toString());    

                        Log.d(TAG, PRODUCT_TABLE + "table created");       
                }

                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {            
                    db.execSQL("drop table if exists " + PRODUCT_TABLE);                    
                    onCreate(db);
                }

              }



          public ProductDatabase(Context context) {
                ProductDatabaseHelper helper = new ProductDatabaseHelper(context);
                db = helper.getWritableDatabase();
            }

          public boolean insert(ProductData product) {
                ContentValues vals = new ContentValues();
                vals.put("barcode", product.barcode);
                vals.put("format", product.format);
                vals.put("title", product.title);
                vals.put("price", product.Price.multiply(ONE_HUNDRED).longValue());

                return db.insert(PRODUCT_TABLE, null, vals) != -1;
            }
        }

There are warnings regarding hard coded text strings in the xml files but no errors in eclipse.

Here's the logcat, please note my emulator doesn't recognize my webcam, I filled the form from the run I did on my brother's Nexus 10.

06-06 09:26:42.840: E/AndroidRuntime(825): FATAL EXCEPTION: main
06-06 09:26:42.840: E/AndroidRuntime(825): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.zxing.client.android.SCAN (has extras) }
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1622)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.app.Instrumentation.execStartActivity(Instrumentation.java:1417)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.app.Activity.startActivityForResult(Activity.java:3370)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.app.Activity.startActivityForResult(Activity.java:3331)
06-06 09:26:42.840: E/AndroidRuntime(825):  at com.example.barcodedatabaseapp.AddProduct.onClick(AddProduct.java:51)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.view.View.performClick(View.java:4202)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.view.View$PerformClick.run(View.java:17340)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.os.Handler.handleCallback(Handler.java:725)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.os.Looper.loop(Looper.java:137)
06-06 09:26:42.840: E/AndroidRuntime(825):  at android.app.ActivityThread.main(ActivityThread.java:5039)
06-06 09:26:42.840: E/AndroidRuntime(825):  at java.lang.reflect.Method.invokeNative(Native Method)
06-06 09:26:42.840: E/AndroidRuntime(825):  at java.lang.reflect.Method.invoke(Method.java:511)
06-06 09:26:42.840: E/AndroidRuntime(825):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-06 09:26:42.840: E/AndroidRuntime(825):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-06 09:26:42.840: E/AndroidRuntime(825):  at dalvik.system.NativeStart.main(Native Method)

Also

06-06 09:28:38.579: E/AndroidRuntime(864): FATAL EXCEPTION: main
06-06 09:28:38.579: E/AndroidRuntime(864): java.lang.NullPointerException
06-06 09:28:38.579: E/AndroidRuntime(864):  at com.example.barcodedatabaseapp.AddProduct.onClick(AddProduct.java:70)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.view.View.performClick(View.java:4202)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.view.View$PerformClick.run(View.java:17340)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.os.Handler.handleCallback(Handler.java:725)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.os.Looper.loop(Looper.java:137)
06-06 09:28:38.579: E/AndroidRuntime(864):  at android.app.ActivityThread.main(ActivityThread.java:5039)
06-06 09:28:38.579: E/AndroidRuntime(864):  at java.lang.reflect.Method.invokeNative(Native Method)
06-06 09:28:38.579: E/AndroidRuntime(864):  at java.lang.reflect.Method.invoke(Method.java:511)
06-06 09:28:38.579: E/AndroidRuntime(864):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-06 09:28:38.579: E/AndroidRuntime(864):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-06 09:28:38.579: E/AndroidRuntime(864):  at dalvik.system.NativeStart.main(Native Method)
Community
  • 1
  • 1
  • 1
    What does the LogCat say? – CaseyB Jun 05 '13 at 15:16
  • I'm not running this on the emulator since it doesn't recognize my webcam which is required for the scanner. I'm running it on my Nexus 10 tablet, where the symptoms are as I said. – ndiaAnirudh Nair Jun 06 '13 at 07:56
  • 1
    Running on an actual device is always better! It looks like you're not using the ZXIng library. It's really easy to bring in. Have a look at this link: https://code.google.com/p/zxing/wiki/ScanningViaIntent – CaseyB Jun 06 '13 at 14:27
  • @CaseyB:I posted the logcat sections, also after going through my code, I think it has something to do with the else block of AddProduct.java and the insert statements – ndiaAnirudh Nair Jun 06 '13 at 14:34
  • @CaseyB : I'm using the Zxing library, it scans the code and fills the 1st 2 fields. I tested it out on the tabet like I said, it uses Zxing camera screen so I know that works. – ndiaAnirudh Nair Jun 06 '13 at 14:40

1 Answers1

2

You didn't initialize mProductDb in your Activity's onCreate.

mProductDb = new ProductDatabase(this);
Nachi
  • 4,218
  • 2
  • 37
  • 58
  • Thanks, i knew it was something simple like that, couldn't figure out what though. I can view the database when I use SQLiteBrowser and the emulator, but I want to see the file on my S III mini phone or Nexus 10 tablet, I'll have to connect them while running eclipse's avd (for the phone) right? Then the usual steps. Plus I want to show this database data as a form or list if possible. Got any advice for that? – ndiaAnirudh Nair Jun 07 '13 at 06:29
  • According to the person who I'm under, I now need code that checks whether the scanned item has already been entered into the database and if so a message pops up without adding to the database, I'm looking for the SQLite command that would do this with the table created already. – ndiaAnirudh Nair Jun 12 '13 at 16:17
  • 1
    Please make a new question for this on StackOverflow. – Nachi Jun 13 '13 at 07:23