The Manatee Works Barcode Scanner SDK is implemented as a software library that provides a lightweight, yet powerful barcode detection and decoding API optimized for mobile platforms. The core routines are implemented in a static C library for high performance and portability, and where necessary, native wrappers are provided for the various platforms (e.g., a Java implementation class for Android).

The Barcode Scanner library supports the following barcode symbologies and sub-types.

Steps for creating the application

  1. Download and install the latest Android Studio using on-screen instructions.
  2. Download the demo application from the attached file:  ManateeWorks Application
    Unzip it and open Android Studio and Import the project. After importing the project always Clear/Rebuild.

    Android Studio - How To Import Project

    image 1 - How to import your project

  3. We need to give the application permissions to use our camera. To do this we add:
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.CAMERA" />

    This application works offline and you don’t need an internet connection. 
    This is just an example from the manifest that is already written in our application, which gives camera permissions and in order to work you probably don’t need to change anything.
    Manifest:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.manateeworks.manateeworks">
    
       <uses-feature android:name="android.hardware.camera" />
       <uses-permission android:name="android.permission.CAMERA" />
    
       <application
           android:allowBackup="true"
           android:icon="@drawable/ic_launcher"
           android:label="@string/app_name"
           android:supportsRtl="true"
           android:theme="@style/AppTheme">
           <activity android:name=".MainActivity">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
    
                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
           </activity>
           <activity android:name=".ListActivity" />
           <activity
               android:name=".ActivityCapture"
               android:label="Scanner"
               android:screenOrientation="portrait"
               android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
       </application>
    
    </manifest>
    
  4. Register your license key
    Our SDK barcode needs to have a valid license in order to work. Basically, without a license, the scanner still works, but it obfuscates the results by injecting * chars in the resulting string. For this purpose, to be able to see the full glory of the scanner,  first you need to create your Manatee Works developer account  and generate your 30 day trial license.
    After you've obtained the license key, open the activity capture and enter the code below in row 135:
    int registerResult = BarcodeScanner.MWBregisterSDK("SDK KEY", this);

    Where you need to change “SDK KEY” to your free trial registration license key.
     

Overview and features of the application

First activity is Splash (MainActivity), it lasts for 3 seconds and then automatically the class bellow transports you to the list activity (List activity). This is the function that transports you to the another activity (ListActivity).

 

Android Intent can be defined as a simple message objects which is used to communicate from 1 activity to another.

Intents define intention of an Application . They are also used to transfer data between activities.

An Android Intent can be used to perform the following 3 tasks :

  1. Open another Activity or Service from the current Activity
  2. Pass data between Activities and Services
  3. Delegate responsibility to another application. For example, you can use Intents to open the browser application to display a URL.
final int SPLASH_DISPLAY_LENGTH = 3000;
new Handler().postDelayed(new Runnable() {
           @Override
           public void run() {
 
               Intent intent = new Intent(MainActivity.this, ListActivity.class);
               intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
               startActivity(intent);
               finish();
           }
       }, SPLASH_DISPLAY_LENGTH);

List activity is the first activity that you see after the splash is finished. Below the list view, you can find an Edit Text Field where you can put the name of the item that you would like to add to your list, shown below in our Item List:

Every Item has a Name, Barcode type and Barcode result. We can add new, edit or delete an item.

Now, let's add some buttons to control Scanning, and some bonus content, a Google Talk button that will let us dictate the name of our items, instead of typing them in:


public boolean onOptionsItemSelected(MenuItem item) {
       switch (item.getItemId()) {
           case scun:
               Intent intent = new Intent(ListActivity.this, ActivityCapture.class);
               intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
               startActivityForResult(intent, REQ_CODE_SCANNER);
               break;
           case R.id.google_talk:
 
               promptSpeechInput();
 
               break;
           default:
               return false;
       }
       return true;
   }

 

Button - is a Push-button which can be pressed, or tapped, by the user to perform an action.

EditText - is an overlay over TextView that configures itself to be editable. It is the predefined subclass of TextView that includes rich editing capabilities.

Overview of the solution

The first button on the action bar in the application, from right to left, is the Google Talk button. You can use speech recognition to dictate and add items to the list. 

All this is executed from the function below: 

private void promptSpeechInput() {
       Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
       intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
               RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
       intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
       intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
               getString(R.string.speech_prompt));
 
       try {
           startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
       } catch (ActivityNotFoundException a) {
           Toast.makeText(getApplicationContext(),
                   getString(R.string.speech_not_supported),
                   Toast.LENGTH_SHORT).show();
       }
   }
 

 

image 2 - Google Voice in Action

That is all nice and well, but nothing to do with barcodes yet, so let's move to the fun part: The Scanning button. If you've built the app it should be shown on the screen to the top right as a barcode image (next to Google Talk Button).
This part of the code brings you to ActivityCapture, and returns result as new Item with Type and Barcode, which are then added to the Item List. The Item’s Name is added later with an Edit Text field, which is found at the bottom of the item list: “Add new item”. 

EditText  is the place where you can add the name for the items and is added to the list see below code:

// edittxt is the place from where you can add the name for the items and is added to the list
editTxt.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(
                ListActivity.this.editTxt.getWindowToken(), 0);
        if ((event.getAction() == KeyEvent.ACTION_DOWN)
                && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {

            ListObject object = new ListObject();
            object.name = editTxt.getText().toString();
            arrayList.add(object);
            saveArray();
            adapter.notifyDataSetChanged();
            editTxt.setText("");
            editTxt.clearFocus();


        }
        return false;
    }

});

The ArrayList class extends AbstractList and implements the List interface. ArrayList supports dynamic arrays that can grow as needed. Standard Java arrays are of a fixed length. After arrays are created, they cannot grow or shrink, which means that you must know in advance how many elements an array will hold.

private ArrayList<ListObject> arrayList;

image 2 - Google Voice in Action

This part of the code shows how to send data from ActivityCapture (Manateeworks Barcode Scanner) to the MainActivity class.


Intent returnIntent = new Intent();
               returnIntent.putExtra("type", typeName);
               returnIntent.putExtra("code", s);
               setResult(Activity.RESULT_OK, returnIntent);
               finish();

The result of scanning is contained in onActivityResult.  

When we start another activity from current activity to get the result for it, we call the method startActivityForResult(intent, RESPONSE_CODE);. It redirects to another activity like opens camera, gallery, etc. After taking an image from the gallery or camera we return to the current activity and the first method that is called is onActivityResult(int requestCode, int resultCode, Intent data).

@Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
       // google talk code
       switch (requestCode) {
           case REQ_CODE_SPEECH_INPUT: {
               if (resultCode == RESULT_OK && null != data) {
 
                   ArrayList result = data
                           .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                   editTxt.setText(result.get(0));
 
                   getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
 
 
               }
               break;
           }
           // callback from scanner and add the resoult to the item
           case REQ_CODE_SCANNER: {
               if (resultCode == RESULT_OK) {
                   if (data.hasExtra("position")) {
                       String type = data.getStringExtra("type");
                       String code = data.getStringExtra("code");
                       int position = data.getIntExtra("position", 0);
 
                       ListObject object = arrayList.get(position);
                       object.type = type;
                       object.code = code;
 
                       saveArray();
                       adapter.notifyDataSetChanged();
 
                       //  callback from scanner and add new item in the list with code in the item
                   } else {
                       String type = data.getStringExtra("type");
                       String code = data.getStringExtra("code");
 
                       ListObject object = new ListObject();
                       object.name = editTxt.getText().toString();
                       object.code = code;
                       object.type = type;
 
                       arrayList.add(object);
                       saveArray();
                       adapter.notifyDataSetChanged();
                   }
               }
               break;
           }
 
       }
   }

Now obviously you won't need some items, not all barcodes are created equal, so some will get trashed. To enable this in our application, we have:

holder.delete.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
 
                   AlertDialog.Builder adb = new AlertDialog.Builder(ListActivity.this);
                   adb.setMessage("Are you sure you want to delete " + arrayList.get(finalPosition).name);
                   adb.setNegativeButton("Cancel", null);
                   adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
                       public void onClick(DialogInterface dialog, int which) {
 
                           arrayList.remove(finalPosition);
                           adapter.notifyDataSetChanged();
                           saveArray();
                       }
                   });
                   adb.show();
               }
           });

The ViewHolder (holder) design pattern enables you to access each list item view without the need for the look up, saving valuable processor cycles. Specifically, it avoids frequent call of findViewById() during ListView scrolling, and that will make it smooth.

ViewHolders belong to the adapter. Adapters should feel free to use their own custom ViewHolder implementations to store data that makes binding view contents easier.

Edit button – We saw how we can delete an item, let's see how we edit one:

holder.editname.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
 
                   final AlertDialog.Builder adb = new AlertDialog.Builder(ListActivity.this);
                   adb.setMessage("Are you sure you want to edit the name for " + arrayList.get(finalPosition).name);
                   final EditText input = new EditText(ListActivity.this);
                   InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                   imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                   input.requestFocus();
 
                   adb.setView(input, 100, 50, 100, 0);
                   adb.setNegativeButton("Cancel", new AlertDialog.OnClickListener() {
                       @Override
                       public void onClick(DialogInterface dialog, int which) {
                           InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                           imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                       }
                   });
 
                   InputMethodManager immm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                   immm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                   adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
                       public void onClick(DialogInterface dialog, int which) {
 
 
                           ListObject object = arrayList.get(finalPosition);
                           object.name = input.getText().toString();
                           saveArray();
                           adapter.notifyDataSetChanged();
                           input.setText("");
 
 
                           Toast.makeText(getApplicationContext(), "The name is changed", Toast.LENGTH_SHORT).show();
                           InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                           imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
                       }
                   });
                   adb.show()
               }
           });

 

Add barcodes to your items list – We want to associate an item with a barcode, this is done so that later we can "scrath off" an item from the list by scanning their barcode.

holder.imgCode.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   AlertDialog.Builder adb = new AlertDialog.Builder(ListActivity.this);
                   adb.setMessage("Add barcode for this item " + arrayList.get(finalPosition).name);
                   adb.setNegativeButton("Cancel", null);
                   adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
                       public void onClick(DialogInterface dialog, int which) {
 
                           Intent intent = new Intent(ListActivity.this, ActivityCapture.class);
                           intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                           intent.putExtra("position", finalPosition);
                           startActivityForResult(intent, REQ_CODE_SCANNER);
 
                       }
                   });
                   adb.show();
               }

Finally, after reviewing the buttons, the following code shows how we can Save the Item List.

When the application is closed you don’t lose the items.

// save the list in the SharedPreferences so when you close the application you dont lose the items in the list
   public boolean saveArray() {
       SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
       SharedPreferences.Editor mEdit1 = sp.edit();
 
       mEdit1.putInt("Status_size", arrayList.size());
 
       for (int i = 0; i < arrayList.size(); i++) {
           mEdit1.remove("Status_" + i);
           try {
               JSONObject cacheJSON = new JSONObject();
 
               cacheJSON.put("name", arrayList.get(i).name);
               cacheJSON.put("code", arrayList.get(i).code);
               cacheJSON.put("type", arrayList.get(i).type);
 
               mEdit1.putString("Status_" + i, cacheJSON.toString());
           } catch (JSONException e) {
               e.printStackTrace();
           }
       }
 
       return mEdit1.commit();
 
   }

 
// load the list with items whe you open the application
   public void loadArray(Context mContext) {
       SharedPreferences mSharedPreference1 = PreferenceManager.getDefaultSharedPreferences(mContext);
       arrayList.clear();
       int size = mSharedPreference1.getInt("Status_size", 0);
 
       for (int i = 0; i < size; i++) {
           try {
               JSONObject cacheJSON = new JSONObject(mSharedPreference1.getString("Status_" + i, null));
               ListObject object = new ListObject();
               object.name = cacheJSON.getString("name");
               object.code = cacheJSON.getString("code");
               object.type = cacheJSON.getString("type");
 
               arrayList.add(object);
 
           } catch (JSONException e) {
               e.printStackTrace();
           }
       }
 
   }

 

image 3 - Adding a new item to the list

 

Conclusion

If you followed the tutorial correctly you should have a working android application where you can change everyting you like and modify the applicitation to suit your needs.

Here we explain in short steps How To make your own Shopping Barcode Scanner application in Android Studio.
2017-02-20
2017-10-23
How To make your own Shopping application in Android Studio
How To make your own Shopping application in Android Studio
ManateeWorks
info@manateeworks.com
Mobile apps need to be increasingly more engaging to succeed. Manatee Works can help. Our mobile barcode scanner SDK is available on all major mobile development platforms.
ManateeWorks