ANDROID APPLICATION FOR MAINTAINING LABORATORY INVENTORY A Project

advertisement

ANDROID APPLICATION FOR MAINTAINING LABORATORY INVENTORY

A Project

Presented to the faculty of the Department of Computer Science

California State University, Sacramento

Submitted in partial satisfaction of the requirements for the degree of

MASTER OF SCIENCE in

Computer Science by

Upashana Borthakur

FALL

2013

ANDROID APPLICATION FOR MAINTAINING LABORATORY INVENTORY

A Project by

Upashana Borthakur

Approved by:

__________________________________, Committee Chair

Dr. Jinsong Ouyang

__________________________________, Second Reader

Dr. Ying Jin

____________________________

Date ii

Student: Upashana Borthakur

I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the project.

__________________________, Graduate Coordinator ________________

Dr. Nikrouz Faroughi Date

Department of Computer Science iii

Abstract of

ANDROID APPLICATION FOR MAINTAINING LABORATORY INVENTORY by

Upashana Borthakur

The laboratories in top tech companies still use the manual entry of data for tracking the hardware equipments that are used. This android application provides automated laboratory system which can significantly reduce the need of human labor and thus reduce any chances of discrepancies and errors. The employee would be able to book equipments online which the laboratory manager will then check out on the employee’s request. This is a very handy application which every employee can utilize to search and book equipments they require. Apart from this, the laboratory manager will also have the options of keeping track of the number of equipments checked out, equipments pending delivery back at the laboratory, lost equipments and renew equipments for existing users.

The project has been implemented using Java and Android.

_______________________, Committee Chair

Dr. Jinsong Ouyang

_______________________

Date iv

ACKNOWLEDGEMENTS

I would like to thank Dr. Jinsong Ouyang, my advisor for providing me an opportunity to work on this project, which significantly broadened my knowledge on Android

Development. I thank him for continuously providing the feedback, help and support to complete the project successfully.

In addition, I would like to thank Dr. Ying Jin for her willingness to serve on the committee.

Lastly, I would like to thank the entire faculty and staff of the Department of Computer

Science Engineering at California State University, Sacramento. v

TABLE OF CONTENTS

Page

Acknowledgements ..............................................................................................................v

List of Tables……………………………………………………………………………..ix

List of Figures……………………………………………………………………………..x

Chapter

1. INTRODUCTION ...........................................................................................................1

2. PROJECT REQUIREMENTS .........................................................................................2

2.1 User Options .............................................................................................................. 2

2.1.1 Login ................................................................................................................... 3

2.1.2 List of all Equipments......................................................................................... 3

2.1.3 Search Equipment ............................................................................................... 3

2.1.4 My Booked Equipment ....................................................................................... 3

2.1.5 My Waitlist ......................................................................................................... 3

2.1.6 My Assigned equipments ................................................................................... 4

2.2 Laboratory Manager Options .................................................................................... 4

2.2.1 Check In .............................................................................................................. 5

2.2.2 Booked equipments ............................................................................................ 6

vi

2.2.3 Checked Out Equipments ................................................................................... 6

2.2.4 List of all Equipments......................................................................................... 6

2.2.5 Pending Equipments list ..................................................................................... 7

2.2.6 Lost Equipments list ........................................................................................... 7

2.2.7 Renew Equipments list ....................................................................................... 7

2.2.8 Reports ................................................................................................................ 8

3. ANDROID DEVELOPMENT BASICS.……………………………………………....9

3.1 Four Types of application components ................................................................... 10

3.1.1 Activities ........................................................................................................... 10

3.1.2 Services ............................................................................................................. 14

3.1.3 Content providers ............................................................................................. 16

3.1.4 Broadcast receivers ........................................................................................... 17

3.2 Download and setup ADT bundle ........................................................................... 17

3.3 Creating an Android Project that displays ‘Hello World’ ....................................... 18

3.4 Running the application .......................................................................................... 23

3.4.1. On device ......................................................................................................... 23

3.4.2. On Emulator .................................................................................................... 24

4. LABORATORY INVENTORY APP DEVELOPMENT…………………………….27

vii

4.1 OCR Technology..................................................................................................... 27

4.2 Barcode Scanner ...................................................................................................... 30

4.3 Json Parser ............................................................................................................... 32

4.4 Features of the application ...................................................................................... 37

4.4.1 Search Activity ................................................................................................. 37

4.4.2 Check-In Equipments ....................................................................................... 40

4.4.3 Check Out Equipments ..................................................................................... 43

4.4.4 Pending Equipment Activity ............................................................................ 45

4.4.5 Renew Activity ................................................................................................. 48

4.4.6 Lost Equipments ............................................................................................... 51

4.5 Async Task .............................................................................................................. 53

4.6 Enhanced OCR functionality .................................................................................. 55

4.6.1 Camera classes .................................................................................................. 55

4.6.2 Capture Activity ............................................................................................... 59

4.7 Future Work ............................................................................................................ 63

5. CONCLUSION………………………………………………………………………..64

References………………………………………………………………………………..65

viii

LIST OF TABLES

Tables Page

Table 1 Report Format.......................................................................................................8

ix

LIST OF FIGURES

Figures Page

Figure 1 User Side Use Case Diagram ............................................................................... 2

Figure 2 Admin Side Use Case Diagram-PartI ................................................................... 4

Figure 3 Admin Side Use Case Diagram-PartII ................................................................. 5

Figure 4 Activity Lifecycle ............................................................................................... 13

Figure 5 Service Lifecycle ................................................................................................ 15

Figure 6 Creating new android app in eclipse .................................................................. 19

Figure 7 Configure project in eclipse................................................................................ 20

Figure 8 Configure Attributes in eclipse ........................................................................... 21

Figure 9 Android Virtual Device Manager ....................................................................... 24

Figure 10 Android Virtual Device Edit ............................................................................ 25

Figure 11 Search activity snapshot ................................................................................... 38

Figure 12 Check-In Activity snapshot .............................................................................. 42

Figure 13 Check-Out activity snapshot............................................................................. 44

Figure 14 Pending activity snapshot ................................................................................. 46

Figure 15 Send mail snapshot ........................................................................................... 48

Figure 16 Renew activity snapshot ................................................................................... 51

Figure 17 Lost activity snapshot ....................................................................................... 52

x

1

Chapter 1

INTRODUCTION

Manual entry of data can lead to errors and discrepancies in data. Most companies use this method to enter laboratory data which results in loss of time and effort. This application will provide an automated laboratory system which can significantly reduce the need of human labor. The employee would have the luxury to book equipments online without having to go to the lab and check if the equipment is available or not. The lab manager work would be highly simplified since now they would just need to check in and check out the equipment using this application and the application will help them to keep track of the number of equipments checked out, equipments pending delivery back at the laboratory, lost equipments and renew equipments for existing users.

Chapter 2

PROJECT REQUIREMENTS

2.1 User Options

Login

USER

Search for equipment

Click on equipment from list

View status of equipment

Check out other links pertaining to search

Book The equipment

Yes

If available?

No

Add user to waitlist

Check status of requested equipments

Figure 1 User Side Use Case Diagram

Receive notification on available

2

3

2.1.1 Login

The user will be able to log in using their username and password and check for available equipments.

2.1.2 List of all Equipments

When this button is clicked, the list of equipments appears with status and category.

The status of the equipment can say either “Available” or “Not available”

The user can click on the equipments and see the details like barcode, name of equipment, type of equipment, description, quantity, available quantity, wait list of all the equipments.

2.1.3 Search Equipment

The application will generate the list of available equipments as per the user’s search.

The search can be based on equipment name or type. If equipment is available then when the equipment is clicked, a book button will allow to user to book them and also add those equipments to the book equipment list. If the equipment is not available, then user can add them to the waitlist by clicking on waitlist button and will receive notification when the equipment becomes available again.

2.1.4 My Booked Equipment

This list will display all the equipments booked by the employee.

2.1.5 My Waitlist

This list contains all equipments for which the user is waitlisted for.

2.1.6 My Assigned equipments

Once the user approaches the admin and checks out the equipment which was booked by

4 them, then those equipments will appear in this assigned equipments list.

2.2 Laboratory Manager Options

Click on details button to either see the details of checked out equip or to check list of people requesting unavailable equip

Login

Click on

List of all equipments with status and category

Yes

If status is checked out or unavailable

ADMIN

No

Nothing to be done

Check in equipment by saving and update status

Send mail to employee and cc the manager

Yes

Check out equipment and update status

Click on pending equipment list

Is todays date

>=2 of due date

No

Send mail to employee only

Figure 2 Admin Side Use Case Diagram-PartI

5

Click on lost equipment list

Click on renew equipment

Send mail to employee and manager to inform the amount which will be charged to the department

NO

Are there spare equipments?

Check if anyone on waitlist

NO

Extend Deadline

YES

YES Reject renewal

Extend deadline

Figure 3 Admin Side Use Case Diagram-PartII

The admin logs in using their username and password. The features available for admin are as follows:

2.2.1 Check In

The admin can check-in the equipments that was checked out by any user(employee) back

By scanning the bar code on the equipment

By scanning the Employee ID card using OCR technology to pull out the name and ID of the employee

After scanning both, application should add that equipment to the available list again and also update status of the equipment.

2.2.2 Booked equipments

This list displays the equipments which have been booked before by the employees. The

6 admin can click on each equipment and assign a return date to the equipment when approached by the employee to check out the booked equipment.

2.2.3 Checked Out Equipments

Once the return date has been assigned, the equipments are added to this list. This list will display all the equipments which have been checked out by the admin. On clicking the equipment name, admin can see all details of the checked out equipments like employee

ID, employee name, email, booked date, equipment barcode, equipment name, typem description and return date. There are two buttons on the bottom of page “Email” and

“Lost”

Email button will enable admin to notify users of any information regarding the equipment.

Lost equipment button when clicked will automatically add that equipment to the lost equipments list(listed in 2.2.5) and also at the same time allow the admin to send a mail to the employee and manager to inform the amount which will be charged to the department for the lost equipment.

2.2.4 List of all Equipments

The admin can check all the equipments in the list of all equipments button. When this button is clicked, the list of equipments appears with status and category.

7

The status of the equipment can say either “Available” or “Not available”

The admin can click on the equipments and see the details like barcode, name of equipment, type of equipment, description, quantity, available quantity, wait list of all the equipments.

2.2.5 Pending Equipments list

This feature allows the admin to see a list of all equipments which are pending to be returned to the laboratory. Each equipment will have the name, type, booked by, booked date and return date as to when this equipment was due to be returned.

If the present date is >= 2 days of due date, then a “send mail” button will allow admin to send mail to the employer and cc the manager to remind him/her to return the equipment.

 If present date <=2 days of due date then the “send mail” button can be used to send mail to employee only.

2.2.6 Lost Equipments list

This list allows user to see complete list of lost equipments.

2.2.7 Renew Equipments list

This list when clicked will require admin to enter the user ID of employee and barcode of equipment. This can be done either manually or by scanning. On entering both fields and clicking on “check” will perform two operations:

The application checks if there are spare equipments. If there are spare ones, then deadline is extended for the equipment by changing the return date.

If not, then it checks if anyone is on waitlist for that equipment. If yes then rejects

8 renewal by displaying message “User waiting on equipment” else extends deadline.

2.2.8 Reports

The admin can view comprehensive reports.

 On clicking “detailed report” admin can view one report with all the relevant details of the android application like total equipments, equipment names, types, available, checked out, users, pending, lost, renewed.

There is option of generating reports by selecting equipment type from a dropdown menu.

For example: equipment type – DDR ram card

The report will look as follows:

Table 1 Report Format

Names

Hynix

Kingston

Total no of equipments

1

1

Available

0

1

Checked out

1

0

User

User1

None

These two reports are accessible from android as well as browser. In browser, the admin needs to log in using admin username and password. Then they will be able to view both the reports mentioned above and can also print them if they want to.

Chapter 3

ANDROID DEVELOPMENT BASICS

Android is a Linux-based operating system designed primarily for touch screen mobile

9 devices such as smartphones and tablet computers. To make things easier for developers,

Google had made Android as open source and releases the code under the Apache

License. Android has a large community of developers writing applications ("apps") that extend the functionality of devices, written primarily in a customized version of the Java programming language.

As mentioned above android applications are mostly written in java programming language. The code is compiled using Android SDK tools into an android package, an archive file with an .apk suffix. This .apk file is considered as one application and is used to install the application in all android devices like tablets and phones.

Application components are the essential building blocks of an Android application. Each component is a different point through which the system can enter your application. Not all components are actual entry points for the user and some depend on each other, but each one exists as its own entity and plays a specific role—each one is a unique building block that helps define your application's overall behavior.

There are four different types of application components. Each type serves a distinct purpose and has a distinct lifecycle that defines how the component is created and destroyed.

10

3.1 Four Types of application components

3.1.1 Activities

Activity represents a single screen with a user interface. For example, in this lab inventory application there are many activities such as login activity, user activity, admin activity and so on. One activity in the application is specified as the "main" activity, which is presented to the user when launching the application for the first time. Each activity can then start another activity in order to perform different actions.

Whenever a new activity starts, the previous activity is stopped, but the system preserves the activity in a stack (the "back stack"). When a new activity starts, it is pushed onto the back stack and takes user focus. This back stack follows LIFO(last in first out) stack mechanism, so, when the user is done with the current activity and presses the back button, it is popped from the stack (and destroyed) and the previous activity resumes.

Activity must be declared in the manifest file to be accessible by the system. Declaring is as simple as adding an <activity> element as a child of the <application> element as follows:

<manifest ... >

<application ... >

<activity android:name=".ExampleActivity" />

...

</application ... >

11

...

</manifest >

Intent filters can also be specified in the <activity> element to declare how other application components may activate it.

The activity automatically includes an intent filter that declares the activity responds to the "main" action and should be placed in the "launcher" category. The intent filter looks like this:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

The callback methods for activity are as follows which are shown in the diagram below: onCreate(): This is called when the activity is first created. This is always followed by onStart(). onStart(): This is called just before the activity becomes visible to the user. This is followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.

12

OnResume(): This is called just before the activity starts interacting with the user. This is always followed by onPause(). onPause(): This is called when the system is about to start resuming another activity. And this is followed either by onResume() if the activity returns back to the front, or by onStop() if it becomes invisible to the user. onStop(): This is called when the activity is no longer visible to the user. This is followed either by onRestart() if the activity is coming back to interact with the user, or by onDestroy() if this activity is going away onRestart(): This is called after the activity has been stopped, just prior to it being started again. This is always followed by onStart().

OnDestroy(): This is called before the activity is destroyed. This is followed by nothing.

13

Figure 4 Activity Lifecycle

3.1.2 Services

A service is a component which would be running in background without direct interaction with the user. As the service has no user interface it is not bound to the lifecycle of an activity. Services are used mostly when there is a time consuming and

14 long task, like loading an Image, or a File, or download something for the Internet and asynchronous tasks in general.

Service has two forms:

1.

Started: When an activity starts startService(), then a service is "started". A service can run in the background indefinitely once started, even if the component that started it is destroyed. For example, it might download a image over the network. When the download is completed, the service should stop itself.

2.

Bound: When an application component calls bindService(), a service is "bound".

A bound service provides a client-server interface that allows components to interact with the service, send requests and get results.

The callback methods are: onStartCommand(): This method is called when an activity requests for a service to be started by calling startService(). onBind(): This method is called when an activity wants to bind with the service by calling bindService(). onCreate(): This method is called when the service is first created to perform setup of the service before onStartCommand or onBind is called.

onDestroy(): This method is called when service is no longer required and is to be destroyed.

15

Figure 5 Service Lifecycle

Similar to activity, service must be declared in the application’s manifest file by adding a <service> element as a child of the <application> element.

<manifest ... >

...

16

<application ... >

<service android:name=".ExampleService" />

...

</application>

</manifest>

3.1.3 Content providers

Content providers are used to provide access to other applications to a shared set of application data i.e content providers provide a mechanism through which the data stored by one Android application can be made accessible to other applications. The data is usually stored in file system or SQLite database which the application can access and through content provider, other applications can query or modify the date depending on the settings of the content provider.

A content provider is implemented as a subclass of ContentProvider and an application accesses the data from a content provider with a ContentResolver client object. In order to insert data into provider, ContentResolver.insert() method is used. This method inserts a new row into the provider and returns a content URI for that row. In order to update a row or delete a row ContentResolver.update() and ContentResolver.delete() methods can be used respectively.

17

3.1.4 Broadcast receivers

A broadcast receiver allows registering for system or application events. When any registered event occurs, receivers for an event will be notified by the Android runtime.

System broadcast include screen turning off, the battery is low, or a picture was captured.

Applications broadcast would include letting other applications know that some data has been downloaded to the device and is available for them to use.

The implementing class for a receiver extends the BroadcastReceiver class. If the event for which the broadcast receiver has registered happens the onReceive() method of the receiver is called by the Android system.

3.2 Download and setup ADT bundle

The first step in starting a project would be to download the Android ADT bundle. The bundle provides all features needed to develop the app and also includes a version of the

Eclipse IDE with built in ADT( Android Developer Tools) .

Perform the following steps after downloading:

1.

First need to unpack the ZIP file (named adt-bundle-<os_platform>.zip) and save it to an appropriate location, such as a "Development" directory in our home directory.

2.

Then open the adt-bundle-<os_platform>/eclipse/ directory and launch eclipse .

3.

In Eclipse, click on the SDK manager and download the latest SDK tools and platforms .

3.3 Creating an Android Project that displays ‘Hello World’

The android project consists of all the code required for the android application. The

18

SDK tools which we downloaded provide basic functionality for us to start coding our application.

1.

First need to click ‘New’ in the toolbar.

2.

When the window appear appears, we need to open the Android folder, select Android Application Project, and then click on Next.

Figure 6 Creating new android app in eclipse

In the android application box, we need to fill appropriate values like the application name is the app name that appears to users which is "MyHelloWorld" for this sample project. The project name is the name of our project directory and the name visible in

Eclipse. The Package Name is the package namespace for our app which is

"com.example.myhelloworld” for this sample project. The lowest version that this app supports is the minimum required SDK. If we want to support multiple devices, this

19

20 needs to be set to lowest version available such that the application can perform its basic operations. The target SDK is the highest version of Android for this application. The platform version with which we compile this sample app is specified in the Compile

With. Here while trying out sample project, this is just set to the latest version of android.

The theme specifies the Android UI style to apply for your app.

On clicking next, the following screen appears:

Figure 7 Configure project in eclipse

This screen is to configure the project and is left at default selections

On clicking next, the next screen will create a launcher icon for this app.

21

Figure 8 Configure Attributes in eclipse

On clicking Next, for this sample project we select BlankActivity and click Next. The other details are left at default and click Finish.

22

The app by default stores hello world code and we need to just run it. The code looks as follows: package com.example.myhelloworld; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

}

The Manifest file will provides the characteristics of the app. The code looks like this:

< RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" android:paddingBottom = "@dimen/activity_vertical_margin" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" tools:context = ".MainActivity" >

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

< TextView android:layout_width = "wrap_content"

23 android:layout_height = "wrap_content" android:text = "@string/hello_world" />

</ RelativeLayout >

The src directory contains all source files required for our application.

The res directory contains sub directories like layout, drawable-hdpi, menu, values etc.

The app is run by clicking on the MyHelloWorld package-> RunAs -> Android application. On running this, the main activity class starts and loads a layout file that says

"Hello World”.

3.4 Running the application

The application can be run either on device or on emulator.

3.4.1. On device

There are two ways the application can be run on device: a. The android device needs to be connected to the laptop with USB cable. On connecting the device, option of downloading USB driver would appear in case the driver is not already installed. Then enable USB debugging on the device.

This can be found under Settings->Developer options b. The second way is to run the app from Eclipse:

On Eclipse, click on Run from the toolbar.

In the Run as window that appears, need to select Android Application and click OK .

This will cause eclipse to install the app on the connected device and start it.

3.4.2. On Emulator

When the application needs to be run on Eclipse, then first step is to set the AVD i.e

Android Virtual Device. The AVD is a device configuration for the Android emulator that allows to model different devices.

24

Figure 9 Android Virtual Device Manager

25

In order to create AVD, first need to launch the Android Virtual Device Manager by clicking on the toolbar. The next step is to click on ‘New’ in the Android Virtual Device

Manager panel.

Next step is to fill in the details for the AVD like name, a platform target, an SD card size etc.

Figure 10 Android Virtual Device Edit

Click Okay. The new AVD will appear in the Android Virtual Device Manager screen.

26

Select the new AVD and click Start . Wait for the emulator to boot up and then unlock the emulator screen.

In order to run the app from Eclipse, click Run from the toolbar. And then select Android Application and click OK . Eclipse will install the app on the AVD and starts it.

27

Chapter 4

LABORATORY INVENTORY APP DEVELOPMENT

4.1 OCR Technology

The Application is using OCR technology to scan ID of employees when they return the equipments which were checked out by them.

The OCR engine which is used in this application is Tesseract which is an optical character recognition engine for various operating systems. This has been sponsored by

Google and it is free software. Till date it is considered as the most accurate open source

OCR engine available. When it is combined with the Leptonica Image Processing

Library it can read a wide variety of image formats and convert them to text in over 60 languages. This has been improved extensively by Google. It is released under the Apache License 2.0.

The steps for building the OCR library is as follows:

The first step would be to download the source or clone from this path https://github.com/rmtheis/tess-two. This project contains tools for compiling the

Tesseract, Leptonica, and JPEG libraries for use on Android. This contains an

Eclipse Android library project that provides a Java API for accessing nativelycompiled Tesseract and Leptonica APIs. The eyes-two code is not required for this OCR library.

To build this project using these commands : cd <project-directory>/tess-two

28 ndk-build android update project --path . ant release

Next step would be to import the project as a library in Eclipse. File -> Import ->

Existing Projects into workspace -> tess-two directory.

Then right click the project, Android Tools -> Fix Project Properties.

Then right click -> Properties -> Android -> Check Is Library.

Configure your project to use the tess-two project as a library project: right click the project name -> Properties -> Android -> Library -> Add, and choose tess-two . Once this library is selected, any image can be OCR’ed using this library.

This library is used in our code.

The rotation and image type should be modified like this:

ExifInterface exif = new ExifInterface( _path ); int exifOrientation = exif.getAttributeInt(

ExifInterface.

TAG_ORIENTATION ,

ExifInterface.

ORIENTATION_NORMAL );

Log.

v ( TAG , "Orient: " + exifOrientation); int rotate = 0; switch (exifOrientation) { case ExifInterface.

ORIENTATION_ROTATE_90 : rotate = 90; break ; case ExifInterface.

ORIENTATION_ROTATE_180 : rotate = 180;

29 false ); break case ExifInterface.

ORIENTATION_ROTATE_270 :

}

Log.

if

} v ( rotate = 270; break

TAG ,

// Setting pre rotate

Matrix mtx = new Matrix(); mtx.preRotate(rotate); bitmap

;

;

"Rotation: "

(rotate != 0) {

= Bitmap.

+ rotate);

// Getting width & height of the given image.

int w = bitmap .getWidth(); int h = bitmap .getHeight();

// Rotating Bitmap createBitmap ( bitmap , 0, 0, w, h, mtx,

// Convert to ARGB_8888, required by tess bitmap = bitmap .copy(Bitmap.Config.

ARGB_8888 , true );

Now we have the image in the bitmap, and we can simply use the TessBaseAPI to run the OCR like follows. The DATA_PATH = Path to the storage and lang= for which the language data exists.

TessBaseAPI baseApi = new TessBaseAPI(); baseApi.init(DATA_PATH, lang,TessBaseAPI.OEM_DEFAULT); baseApi.init(DATA_PATH, lang); baseApi.setImage(bitmap);

String recognizedText = baseApi.getUTF8Text();

30 baseApi.end()

4.2 Barcode Scanner

The barcode scanner has been used in this application to scan the barcode of the laboratory equipments.

The steps followed to use the barcode scanner in this app

1.

Download the ZXing Source Code (ZXing-2.2.zip) from the below link. http://code.google.com/p/zxing/downloads/list

2.

Then, extract this and navigate to C:/zxing-2.2/android-integration/src.

3.

Copy the com folder and paste it in the src folder in Eclipse as a package.

The two files contained in this package are a.

IntentIntegrator.java :

This is a utility class which helps ease integration with Barcode Scanner. This is a simple way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the project's source code.

First step is to inititate a barcode scan.

Second is to integrate, create an instance of IntentIntegrator and call initiateScan()} and wait for the result in the application. It does require that the

Barcode Scanner application is installed. The initiateScan() method will prompt the user to download the application, if needed.

This is how it is called in the application in Admin_checkInActivity.java class.

if (v.getId()==R.id.

b_admin_checkin_scanbarcode )

{

//instantiate ZXing integration class

IntentIntegrator scanIntegrator = new IntentIntegrator( this );

//start scanning scanIntegrator.initiateScan();

}

The activity must implement the method onActivityResult(int, int, Intent) and include a line of code like this :

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);

if (scanResult != null) {

// handle scan result

}

// else continue with any other code you need in the method

}

}

This is how it is implemented in the Admin_checkInActivity.java class. protected void onActivityResult( int requestCode, int resultCode, Intent data) {

// if

TODO super

Auto-generated method stub

.onActivityResult(requestCode, resultCode, data);

(requestCode==1)

{

String result=data.getStringExtra( "result" ); et_ID .setText(result);

} if (requestCode==IntentIntegrator.

REQUEST_CODE )

{

//retrieve result of scanning - instantiate ZXing object

IntentResult scanningResult =

IntentIntegrator.

parseActivityResult (requestCode, resultCode, data);

//check we have a valid result if (scanningResult != null ) {

//get content from Intent Result

String scanContent = scanningResult.getContents();

//get format name of data scanned

String scanFormat = scanningResult.getFormatName();

//output to UI

31

32

} else {

}

Toast.

LENGTH_SHORT );

} et_barcode .setText(scanContent);

//invalid scan data or scan canceled toast.show();

Toast toast = Toast.

makeText (getApplicationContext(),

"No scan data received!" , b.

IntentResult.java: This class encapsulates the result of a barcode scan invoked through IntentIntegrator. This is used in the Admin_checkInActivity.java class as follows:

//retrieve result of scanning - instantiate ZXing object

IntentResult scanningResult =

IntentIntegrator.

parseActivityResult (requestCode, resultCode, data);

//check we have a valid result if (scanningResult != null ) {

//get content from Intent Result

String scanContent = scanningResult.getContents();

//get format name of data scanned

String scanFormat = scanningResult.getFormatName();

//output to UI et_barcode .setText(scanContent);

4.3 Json Parser

This application has used JSON which is the best alternative to XML for storing data in files. It is easy to parse and access data stored in JSON format.

In this application a class is created with name JSONParser.java

. The parser class has a method which will make http request to get JSON data and returns a JSONObject. public class JSONParser {

33 static static static

}

InputStream

JSONObject

String

// constructor public json = is = jObj

"" ;

JSONParser() { null

=

; null ;

"utf-8" );

// function get json from url

// by making HTTP POST or GET mehtod public JSONObject makeHttpRequest(String url, String method,

List<NameValuePair> params) {

// Making HTTP request try {

// check for request method if

}

(method == url +=

"POST"

"?"

){

HttpGet httpGet =

// request method is POST

+ paramString; new

// defaultHttpClient

DefaultHttpClient httpClient = new DefaultHttpClient();

HttpPost httpPost = new HttpPost(url); httpPost.setEntity( new UrlEncodedFormEntity(params));

HttpResponse httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent();

} else if (method == "GET" ){

// request method is GET

DefaultHttpClient httpClient = new DefaultHttpClient();

String paramString = URLEncodedUtils.

HttpGet(url); format (params,

HttpResponse httpResponse = httpClient.execute(httpGet);

HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent();

} try {

InputStreamReader(

} catch (UnsupportedEncodingException e) { e.printStackTrace();

} catch (ClientProtocolException e) { e.printStackTrace();

} catch (IOException e) { e.printStackTrace();

}

BufferedReader reader =

String line = is

StringBuilder sb = null

,

; new BufferedReader(

"iso-8859-1" new

), 8);

StringBuilder(); new while

}

((line = reader.readLine()) != sb.append(line + is .close();

"\n" ); null ) { json = sb.toString();

} catch (Exception e) {

Log.

e ( "Buffer Error" , "Error converting result " + e.toString());

}

}

// try parse the string to a JSON object try

}

{ jObj = new JSONObject( json );

} catch (JSONException e) {

Log.

e ( "JSON Parser" , "Error parsing data " + e.toString());

// return JSON String return jObj ;

34

When the parser class is created, then we use it in all our classes for admin and user activities. The way it is used in this application is shown below:

1.

First in the activity class all the declare store all strings in static variables.

35 private private static static

String final url_get

String

= Data.

URL_GET

TAG_SUCCESS =

;

"success" ;

2.

Next step to is to use parser class to get JSONObject and looping through each json item. Create an instance of JSONParser class and use “FOR” loop to loop through each json item and finally storing each json data in variable.

// Creating JSON Parser object

JSONParser jParser = new JSONParser();

// getting JSON string from URL

JSONObject json = jParser .makeHttpRequest( url_get , "GET" , params); try {

// Checking for SUCCESS TAG int success = json.getInt( TAG_SUCCESS ); if (success == 1) {

// Equipment found

// Getting Array of Equipment result = json.getJSONArray( "result" ); c.getString( "e_barcode" )); c.getString( "e_description" )); c.getString( "available" ));

// looping through All Equipment for ( int i = 0; i < result .length(); i++) {

JSONObject c =

// Storing each json item in variable map map map

= new

.put(

.put( result .getJSONObject(i);

HashMap<String, String>();

"e_id" , c.getString(

"e_barcode" ,

"e_id" )); map map map map

.put(

.put(

.put(

.put( myMap

}

"e_name"

"e_description"

"e_type"

.add( map );

, c.getString(

,

, c.getString(

"available" ,

"e_name"

"e_type" ));

));

} else {

}

}

36 catch (JSONException e) { e.printStackTrace();

}

3.

Parsing JSON data and updating into ListView. Listview is implemeted using list data from the parsed JSON. private void populateListView() {

ArrayAdapter<HashMap<String, String>> adapter =

MyListAdapter(); new

}

ListView list = (ListView) findViewById(R.id.

equipment_listView ); list.setAdapter(adapter); list.setTextFilterEnabled( true );

ListView list = (ListView) findViewById(R.id.

equipment_listView ); list.setOnItemClickListener( new AdapterView.OnItemClickListener() {

@Override public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) { boolean isAvailable; if (Integer.

parseInt ( myMap .get(position).get( "available" ))>0) isAvailable= true ; else isAvailable=

Intent i = new false ;

Intent(getApplicationContext(),

User_showEquipmentActivity.

class ); i.putExtra( "equipment" ,(Serializable) myMap .get(position));

} i.putExtra( i.putExtra(

"isAvailalbe"

"waitList" startActivity(i);

,

,isAvailable ); false );

37

4.4 Features of the application

4.4.1 Search Activity

The search activity can be performed by both user and admin. This search can be based on “Search by Name” or “Search by Type”.

This is implemented using Spinners which provide a quick way to select one value from a set. The spinner shows its current value in default state. In order to select a new value, need to touch on the spinner which will in turn display a dropdown menu with all available items.

38

Figure 11 Search activity snapshot

The spinner is added to the layout with the Spinner object. This is performed in the XML layout with a <Spinner> element like below:

39

< Spinner android:id = "@+id/spinner1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentRight = "true" android:layout_below = "@+id/et_user_search" />

An array adapter is used to provide the choices for the spinner. The choices can either come from an SpinnerAdapter such as an ArrayAdapter if the choices are in an array or a

CursorAdapter if the choices are available from a database query. spinner =(Spinner)findViewById(R.id.

spinner1 );

List<String> list = new ArrayList<String>(); list.add( "Search By Name" ); list.add( "Search By Type" );

ArrayAdapter<String> dataAdapter = new

ArrayAdapter<String>( this ,android.R.layout.

simple_spinner_item , list); dataAdapter.setDropDownViewResource(android.R.layout.

simple_spinner_dropdown_it em ); spinner .setAdapter(dataAdapter);

The dataAdapter defines how the selected choice appears in the spinner control. The simple_spinner_item layout is provided by the platform and is the default layout used unless we want to define own separate layout.The setDropDownViewResource(int) is used to specify the layout the adapter should use to display the list of spinner choices

(simple_spinner_dropdown_item is another standard layout defined by the platform).

Next step is to call setAdapter() to apply the adapter to the Spinner.

In order to search by type or name, if the selected position on the spinner is equal to 0

40 then search is perfomed by NAME else by TYPE and the queries which are used are as follows: if (search.equals( "" ))

{ query = "SELECT e.e_id,e.e_barcode,e.e_name,e.e_type,e.e_description,e.`e_quantity` -

COUNT(eb.e_id) AS available FROM equipments e LEFT JOIN equipments_booked eb

ON e.`e_id` = eb.`e_id` GROUP BY e.`e_id`" ;

} else

{ if ( spinner .getSelectedItemPosition()==0) query = "SELECT e.e_id,e.e_barcode,e.e_name,e.e_type,e.e_description,e.`e_quantity` -

COUNT(eb.e_id) AS available FROM equipments e LEFT JOIN equipments_booked eb

ON e.`e_id` = eb.`e_id` WHERE e.e_name='" +search+ "' GROUP BY e.`e_id`" ; else query = "SELECT e.e_id,e.e_barcode,e.e_name,e.e_type,e.e_description,e.`e_quantity` -

COUNT(eb.e_id) AS available FROM equipments e LEFT JOIN equipments_booked eb

ON e.`e_id` = eb.`e_id` WHERE e.e_type='" +search+ "' GROUP BY e.`e_id`" ;

}

4.4.2 Check-In Equipments

To check in equipments, the admin enters the user id and barcode. This can be achieved manually or by scanning barcode and ID card.

When the admin clicks on the scan id, the OCR application starts. Similarly the click on barcode will start the intent for barcode scanning. And the check button will execute the query in background to check the equipment with the scanned barcode and scanned ID card. public void onClick(View v) { if (v.getId()==R.id.

b_admin_checkin_scanid )

{ setRequestedOrientation(getResources().getConfiguration().

orientation );

41

Intent i= new

Intent(getApplicationContext(),CaptureActivity.

class ); startActivityForResult(i, 1);

} if (v.getId()==R.id.

b_admin_checkin_scanbarcode )

{

//instantiate ZXing integration class

IntentIntegrator scanIntegrator = new IntentIntegrator( this );

}

//start scanning scanIntegrator.initiateScan(); if (v.getId()==R.id.

b_admin_checkin_check )

{ query = "SELECT equipments_booked.`e_id`,users.`u_cardid`,users.`u_email`,`equipments`.`e_barcode`,`eq uipments`.`e_description`,`equipments_booked`.`u_id`,`users`.`u_name`,`equipments`.`e

_name`,`equipments`.`e_type`,`booked_date`,`return_date` FROM `equipments_booked`

LEFT JOIN `equipments` ON `equipments`.`e_id`=`equipments_booked`.`e_id` LEFT

JOIN `users` ON `equipments_booked`.`u_id`=users.`u_id` WHERE

`e_barcode`='" + et_barcode .getText()+ "' AND `u_cardid`='" + et_ID .getText()+ "'" ; new CheckIn().execute();

}

}

42

Figure 12 Check-In Activity snapshot

43

4.4.3 Check Out Equipments

The booked equipments which are to be checked out will be assigned a return date by the admin. public static class DatePickerFragment extends DialogFragment implements OnDateSetListener {

@Override public final int

Dialog onCreateDialog(Bundle savedInstanceState) {

// Use the current date as the default date in the picker

Calendar c = Calendar.

year = c.get(Calendar.

getInstance

YEAR );

(); int month = c.get(Calendar.

MONTH ); int day = c.get(Calendar.

DAY_OF_MONTH );

DatePickerDialog dpd= new DatePickerDialog(getActivity(), this , year, month, day); dpd.setTitle( "Enter Return Date" );

// Create a new instance of DatePickerDialog and return it return dpd;

}

Android provides controls for the user to pick a time or pick a date as ready-to-use dialogs.

The DialogFragment manages the dialog lifecycle and allows us to display the pickers in different layout configurations, such as in a basic dialog on handsets or as an embedded part of the layout on large screens.

To display a DatePickerDialog using DialogFragment, need to define a fragment class that extends DialogFragment and return a DatePickerDialog from the fragment's onCreateDialog() method.

44

Figure 13 Check-Out activity snapshot

45

4.4.4 Pending Equipment Activity

The pending equipment activity list will give a list of all the equipments which are pending to be returned to the laboratory.

The query is to find all the equipments for which the present date has exceeded two days from due date.

The query executed in the activity is as follows: query = "SELECT `equipments_booked`.`return_date`, equipments_booked.`e_id`,users.`u_cardid`,users.`u_email`,`equipments`.`e_barcode`,`eq uipments`.`e_description`,`equipments_booked`.`u_id`,`users`.`u_name`,`equipments`.`e

_name`,`equipments`.`e_type`,`equipments_booked`.`booked_date` FROM

`equipments_booked` LEFT JOIN `equipments` ON

`equipments`.`e_id`=`equipments_booked`.`e_id` LEFT JOIN `users` ON

`equipments_booked`.`u_id`=users.`u_id` WHERE `equipments_booked`.`return_date`

IS NOT NULL AND DATE_ADD(`return_date` , INTERVAL 2 DAY) <= '" + Date + "'" ;

46

Figure 14 Pending activity snapshot

The mail option would allow the admin to sent a mail to notify the employee to return the equipment as soon as possible.

public boolean onOptionsItemSelected(MenuItem item) {

// if

{

TODO

(R.id.

Auto-generated method stub b_emailAll ==item.getItemId())

String[] emails = new String[ myMap .size()]; for ( int a=0;a< myMap .size();a++)

{ emails[a]= myMap .get(a).get( "u_email" );

}

Intent email = new Intent(Intent.

ACTION_SEND );

email.putExtra(Intent.

EXTRA_EMAIL ,emails);

email.setType( "message/rfc822" );

startActivity(Intent.

createChooser (email, "Choose an

Email client :" ));

}

} return super .onOptionsItemSelected(item);

47

Mail applications can be launched to send a message with the following Intent: android.content.Intent.ACTION_SEND.

The setType “message/rfc822” would make sure to prompt user email app or all available app with send action will be prompt for selection.

48

Figure 15 Send mail snapshot

4.4.5 Renew Activity

The admin will renew the equipment when there are extra equipments available. If there are no equipments, then error message will appear. Also if other employees are waiting

49 on the equipment, then notification will appear saying that employees are waiting on the equipment. try { params2) success = json.getInt( TAG_SUCCESS ); if ( success ==1)

{ query = "UPDATE `equipments_booked` SET

`return_date`='" + tv_date .getText()+ "' WHERE

`u_id`='" + map .get( "u_id" )+ "' AND `e_id`='" + map .get( "e_id" )+ "'" ;

List<NameValuePair> params2 = new ArrayList<NameValuePair>(); params2.add( new BasicNameValuePair( "query" , query ));

JSONObject json2 = jsonParser .makeHttpRequest( url_post , "POST" , if (json2.getInt( TAG_SUCCESS )==1)

{

}

} else

{

} error = false ; error = true ; else

{ errorMessage = "Not Enough Quantity available" ; query = "SELECT * FROM `wait_list` WHERE

`e_id`='" + map .get( "e_id" )+ "'" ;

List<NameValuePair> params3 = new ArrayList<NameValuePair>(); params3.add( new BasicNameValuePair( "query" , query ));

JSONObject json3 = jsonParser .makeHttpRequest( url_get , "GET" , params3); if (json3.getInt( TAG_SUCCESS )==1)

{ errorMessage error = true ;

= "User are Waiting on this equipment" ;

} else

{

50 query = "UPDATE `equipments_booked` SET

`return_date`='" + tv_date .getText()+ "' WHERE

`u_id`='" + map .get( "u_id" )+ "' AND

`e_id`='" + map .get( "e_id" )+ "'" ;

List<NameValuePair> params4 = new

ArrayList<NameValuePair>(); params4.add( new BasicNameValuePair(

JSONObject json4 =

"query" , query )); jsonParser .makeHttpRequest( url_post , "POST" , params4); if (json4.getInt( TAG_SUCCESS )==1)

{

} else error = false ;

}

}

{

} error = true ;

} catch (JSONException e) { e.printStackTrace();

}

} return null ;

51

Figure 16 Renew activity snapshot

4.4.6 Lost Equipments

The equipments which are lost by the employees are visible in this list.

52

The query that is executed is as follows: query = "SELECT users.`u_cardid`,`users`.`u_name`,users.`u_email`,`equipments`.`e_barcode`,`equipments

`.`e_name` , `equipments`.`e_type`,`equipments`.`e_description` ,

`equipments_lost`.`lost_date` FROM `equipments_lost` LEFT JOIN `equipments` ON

`equipments_lost`.`e_id`=`equipments`.`e_id` LEFT JOIN users ON

`equipments_lost`.`u_id`=users.`u_id`" ;

Figure 17 Lost activity snapshot

53

4.5 Async Task

All the main activities performed in this application use background async task to execute the queries specific for the individual functionalities.

The main purpose of the AsyncTask is to allow background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

When an asynchronous task is executed, the task goes through 4 steps:

1.

The onPreExecute() is invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.

During pre execute step in the application, progress diaolog is shown before starting background thread. protected void onPreExecute() { super .onPreExecute(); pDialog = new

ProgressDialog(User_showEquipmentActivity.

this ); pDialog .setMessage( "Loading...." ); pDialog .setIndeterminate( false ); pDialog .setCancelable( true ); pDialog .show();

}

2.

The doInBackground(Params...) is invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. Here the parameters of the asynchronous

54 task are passed to this step. The results returned by this step will be passed to the last step . protected String doInBackground(String... args) {

// Building Parameters

List<NameValuePair> params = new

ArrayList<NameValuePair>(); params.add( new BasicNameValuePair( "query" , query ));

// getting JSON Object

// Note that create product url accepts POST method

JSONObject json = jsonParser .makeHttpRequest( url_post , "POST" , params);

// check log cat for response

Log.

try d

{

( "Create Response"

// check for success tag success

, json.toString());

= json.getInt( TAG_SUCCESS );

}

} catch (JSONException e) { e.printStackTrace();

} return null;

3.

The onProgressUpdate(Progress...) is invoked on the UI thread after a call to publishProgress(Progress...). This method is used to display any form of progress in the user interface while the background computation is still executing. In this application, this method is not used.

4. The onPostExecute(Result) is invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

55

Once the background task is completed, this step is used to dismiss the progress dialog from step 1. protected void onPostExecute(String file_url) {

// dismiss the dialog once done pDialog

{

.dismiss(); if ( success ==1)

Toast.

makeText (getApplicationContext(), "Done" ,

Toast.

LENGTH_SHORT ).show(); finish();

} if ( success ==0)

{

Toast.

makeText (getApplicationContext(), "Error" ,

Toast.

LENGTH_SHORT ).show();

}

}

4.6 Enhanced OCR functionality

This application uses OCR technology which has been implemented by using Tess library in our application. The steps required to pull out the ID from the Employee ID card are first click the picture(and save it) and next step is to crop the ID and click on Done. This basically requires two separate steps to pull out the ID from the employee id card. But it is also possible to pull the ID in just one step using OCR. And the way this can be done is to create two layers: one layer would be the camera preview and other is the viewfinder to get specific part of the image.

4.6.1 Camera classes

Auto Focus manager class:

56

This class is mainly used to notify on completion of camera auto focus. The devices that do not support auto-focus will receive a "fake" callback to this interface. onAutofocus is called when the camera auto focus completes. If the camera does not support auto-focus and autoFocus is called, onAutoFocus will be called immediately with a fake value of success set to true. This routine does not lock auto-exposure and autowhite balance after it completes. Success returns true if focus was successful, and false otherwise. Camera is the camera service object. public synchronized void onAutoFocus( boolean success, Camera theCamera) { if ( active && !

manual ) { outstandingTask = new TimerTask() {

@Override public void run() {

checkAndStart();

}

}; timer .schedule( outstandingTask , AUTO_FOCUS_INTERVAL_MS );

} manual = false ;

}

PreviewCallbackclass:

This is called when preview frames are displayed. The parameters used are data which is the content of the preview frame in the format defined by ImageFormat, which can be queried with getPreviewFormat(). Here since IfsetPreviewFormat(int) is never called, the default will be the YCbCr_420_SP (NV21) format. public void onPreviewFrame( byte [] data, Camera camera) {

Point cameraResolution = configManager .getCameraResolution();

Handler thePreviewHandler = previewHandler ; if (cameraResolution != null && thePreviewHandler != null ) {

Message message = thePreviewHandler.obtainMessage( previewMessage , cameraResolution.

x ,cameraResolution.

y , data);

message.sendToTarget();

57 previewHandler = null ;

} else {

Log.

d ( TAG , "Got preview callback, but no handler or resolution available" );

}

}

CameraManagerClass:

This class will a camera driver is opened and the hardware parameters are initialized. The holder is the surface object which the camera will draw preview frames into. And finally an IO exception which indicates that the camera driver failed to open. public synchronized void openDriver(SurfaceHolder holder) throws IOException {

Camera theCamera = camera ; if (theCamera == null ) {

theCamera = Camera.

open (); if (theCamera == null ) { throw new IOException();

} camera = theCamera;

} camera .setPreviewDisplay(holder); if (!

initialized ) { initialized = true ; configManager .initFromCameraParameters(theCamera); if ( requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {

adjustFramingRect( requestedFramingRectWidth , requestedFramingRectHeight ); requestedFramingRectWidth = 0; requestedFramingRectHeight = 0;

}

} configManager .setDesiredCameraParameters(theCamera);

SharedPreferences prefs = PreferenceManager.

getDefaultSharedPreferences ( context ); reverseImage = prefs.getBoolean(PreferencesActivity.

KEY_REVERSE_IMAGE , false );

}

The next step would be to ask the camera hardware to begin drawing preview frames to

58 the screen. public synchronized void startPreview() {

Camera theCamera = camera ; if (theCamera != null && !

previewing ) {

theCamera.startPreview(); previewing = true ; autoFocusManager = new AutoFocusManager( context , camera );

}

}

This tells camera to stop drawing the frames. public synchronized void stopPreview() { if ( autoFocusManager != null ) { autoFocusManager .stop(); autoFocusManager = null ;

} if ( camera != null && previewing ) { camera .stopPreview(); previewCallback .setHandler( null , 0); previewing = false ;

}

}

A single preview frame will be returned to the handler supplied. The data will arrive as

as byte[] in the message.obj field, with width and height encoded as message.arg1 and message.arg2, respectively. The handler is the one to send the message to. And the message is the what fiedl of the message to be sent.

public synchronized void requestOcrDecode(Handler handler, int message) {

Camera theCamera = camera ; if (theCamera != null && previewing ) { previewCallback .setHandler(handler, message);

theCamera.setOneShotPreviewCallback( previewCallback );

}

59

}

4.6.2 Capture Activity

View Finder Class:

Plus the second layer is creating a view finder for that camera capture activity. This must be done so that we can select a region from the capture. And save image from bitmap view inside viewfinder.

In order to get a framing rectangle in the captured region, we use Rect. Rect holds four integer coordinates for a rectangle. The rectangle is represented by the coordinates of its

4 edges (left, top, right bottom). These fields can be accessed directly. The width() and height() is used to retrieve the rectangle's width and height.

Rect frame = cameraManager .getFramingRect(); if (frame == null ) { return ;

} int width = canvas.getWidth(); int height = canvas.getHeight();

In order to differentiate the background from the foreground, need to draw the exterior(i.e outside the rect) as darkened. paint .setColor( maskColor );

canvas.drawRect(0, 0, width, frame.

top , paint );

canvas.drawRect(0, frame.

top , frame.

left , frame.

bottom + 1, paint );

canvas.drawRect(frame.

right + 1, frame.

top , width, frame.

bottom + 1, paint );

canvas.drawRect(0, frame.

bottom + 1, width, height, paint );

To display the ID captured from the rect, a flag is used to represent the results from

TessBaseApi. When this flag is true then the word is retreived from the result text. And

Then draw a bounding box around that word.

static final boolean DRAW_WORD_BOXES = true ;

if ( DRAW_WORD_BOXES || DRAW_WORD_TEXT ) { wordBoundingBoxes = resultText .getWordBoundingBoxes();

} if ( DRAW_WORD_BOXES ) { paint .setAlpha(0xFF); paint .setColor(0xFF00CCFF); paint .setStyle(Style.

STROKE ); paint .setStrokeWidth(1); for ( int i = 0; i < wordBoundingBoxes .size(); i++) { rect = wordBoundingBoxes .get(i);

canvas.drawRect(

frame.

left + rect .

left * scaleX,

frame.

top + rect .

top * scaleY,

frame.

left + rect .

right * scaleX,

frame.

top + rect .

bottom * scaleY, paint );

}

} if ( DRAW_WORD_TEXT ) { words = resultText .getText().replace( "\n" , " " ).split( " " ); int [] wordConfidences = resultText .getWordConfidences(); for ( int i = 0; i < wordBoundingBoxes .size(); i++) { boolean isWordBlank = true ; try { if (!

words [i].equals( "" )) {

isWordBlank = false ;

}

} catch (ArrayIndexOutOfBoundsException e) {

e.printStackTrace();

}

CaptureActivityClass:

This class will setup the camera preview surface and initialize the OCR engine. And in case OCR is already initialized, then just start the camera.

60

61 surfaceView = (SurfaceView) findViewById(R.id.

preview_view ); surfaceHolder = surfaceView .getHolder(); if (!

hasSurface ) { surfaceHolder .addCallback( this ); surfaceHolder .(SurfaceHolder);

} boolean doNewInit = ( baseApi == null ) ||

!

sourceLanguageCodeOcr .equals(previousSourceLanguageCodeOcr) || ocrEngineMode != previousOcrEngineMode; if (doNewInit) {

File storageDirectory = getStorageDirectory(); if (storageDirectory != null ) {

initOcrEngine(storageDirectory, sourceLanguageCodeOcr , sourceLanguageReadable );

}

} else {

resumeOCR();

}

Next method is to start or restart the recognition after the OCR engine has been initialized or after the app regains focus. This sets the state related settings and OCR engine parameters and requests camera initialization. void resumeOCR() {

Log.

d ( TAG , "resumeOCR()" );

// This method is called when Tesseract has already been successfully initialized, so set

// isEngineReady = true here.

isEngineReady = true ; isPaused = false ; if ( handler != null ) { handler .resetState();

} if ( baseApi != null ) { baseApi .setPageSegMode( pageSegmentationMode ); baseApi .setVariable(TessBaseAPI.

VAR_CHAR_BLACKLIST , characterBlacklist ); baseApi .setVariable(TessBaseAPI.

VAR_CHAR_WHITELIST , characterWhitelist );

}

62 if ( hasSurface ) {

initCamera( surfaceHolder );

}

}

This method displays information relating to the results of a successful real-time OCR request. ocrResult represents successful OCR results. Next is to send an OcrResultText object to the ViewfinderView for text rendering. Then display the recognized text on the screen. void handleOcrContinuousDecode(OcrResult ocrResult) { lastResult = ocrResult; viewfinderView .addResultText( new OcrResultText(ocrResult.getText(),

ocrResult.getWordConfidences(),

ocrResult.getMeanConfidence(),

ocrResult.getBitmapDimensions(),

ocrResult.getRegionBoundingBoxes(),

ocrResult.getTextlineBoundingBoxes(),

ocrResult.getStripBoundingBoxes(),

ocrResult.getWordBoundingBoxes(),

ocrResult.getCharacterBoundingBoxes()));

Integer meanConfidence = ocrResult.getMeanConfidence(); if ( CONTINUOUS_DISPLAY_RECOGNIZED_TEXT ) { statusViewTop .setText(ocrResult.getText()); int scaledSize = Math.

max (22, 32 - ocrResult.getText().length() / 4); statusViewTop .setTextSize(TypedValue.

COMPLEX_UNIT_SP , scaledSize); statusViewTop .setTextColor(Color.

BLACK ); statusViewTop .setBackgroundResource(R.color.

status_top_text_background ); statusViewTop .getBackground().setAlpha(meanConfidence * (255 / 100));

} if ( CONTINUOUS_DISPLAY_METADATA ) { long recognitionTimeRequired = ocrResult.getRecognitionTimeRequired(); statusViewBottom .setTextSize(14); statusViewBottom .setText( "OCR: " + sourceLanguageReadable + " - Mean confidence: " +

63

meanConfidence.toString() + " - Time required: " + recognitionTimeRequired + " ms" );

}

}

4.7 Future Work

This project used OCR technology to capture the ID from an employee ID card. There are two ways it has been implemented in this project. First implementation required two steps where the admin clicks the picture (save it) and the crop it to capture the ID. But since this was a bit inefficient, the other method was also implemented which is basically getting rid of the two steps mentioned above and achieving the same functionality in one step. In section 4.6 the description of the second method is provided. This is 90% effective and gives correct ID most of the time. But it also depends on the proper focus, lighting and orientation. A good prospect for future enhancement of this project would be to enhance the second method of OCR to make it fully effective (100%) by making use of any new upcoming android capabilities.

64

Chapter 5

CONCLUSION

This application is extremely handy and can be used by most of the companies where manual entry of data in laboratory takes place. It will help employees to save their time and energy in finding equipments which are available and booking them. And since this is a mobile application, employees have the luxury to check for equipments wherever they are and book them. It will help to make the lives of employees and lab administrators simpler.

This application has been developed using java language. There are lots of resources and sites which can help in learning android development. And they can be tested in emulator or on actual devices.

65

References

[1] Android Developer guide http://developer.android.com/

[2] Research on Tesseract, most accurate OCR engine available. https://code.google.com/p/tesseract-ocr/

[3]An overview of the Tesseract OCR engine by Ray Smith http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com

/en/us/pubs/archive/33418.pdf

[4] “Android Cookbook” by Ian F. Darwin (April 2012),

O’Reilly Media, Inc

. http://androidcookbook.com/home.seam

[5] “Learning Android” by Marko Gargenta (March 2011),

O’Reilly Media, Inc

. http://aiti.mit.edu/media/programs/indonesia-summer-2013/materials/gargenta_-_2011_-

_learning_android.pdf

[6] Android Developers Blog http://android-developers.blogspot.com/

[7] Stack Overflow http://stackoverflow.com/

Download