Android zxing Barcode scanner integration
Applications where we need a barcode scanner integrated in our app, the best and first scanner library hits you is zxing. So lets get started how to build and integrate the library to our Project.
Final results:
Step 1: Download the Zxing sources from Git: https://github.com/zxing/zxing
Step 2: For building the Zxing library project you need a library called core.jar
You can directly download the latest releases of jar from maven repository using either one of the below links:
http://repo1.maven.org/maven2/com/google/zxing/core/
https://oss.sonatype.org/content/repositories/snapshots/com/google/zxing/core/
OR You can always generate the core.jar from the sources downloaded.
Here are the steps to generate the build on a Mac:
1: Navigate to the ‘core’ folder in the zxing-master library from your terminal
2: Run: [mvn -DskipTests -Dgpg.skip=true install]
If Maven not installed you cant run the above command.
Install Maven:
a: I would recommend to install ‘brew’: an installer for third pary packages. (Go to http://brew.sh/ for instructions on brew installation)
b: From the terminal just run:
ruby -e “$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)”
c: Now that you are done with ‘brew’ installation. Just tell brew to install maven by running:
brew install maven
Step 3: After successful build a target folder will be created, just pick the core-x.y.z.jar file from the folder.
Now we got our heart of the application : core-x.y.z.jar Proceed to Building the zxing library.
Before integrating scanner to our app we need to first build the zxing Android library.
Note: for this tutorial i used zxing library version 4.5.1, As 4.5.2 uses java 1.7 compiler which has issues with eclipse but the same works well with Android studio/.
Step 4: From eclipse just import ‘android’ folder from zxing-master to projects.
Step 5: Now create a libs directory under the root then copy the core-x.y.z.jar.
Also add the core-x.y.z.jar to build path.
(Project Properties > Java Build Path > Libraries > Add JARs… > Select the library project then core.jar from libs > Click ‘Ok’)
All your error are gone and the project is ready for build just run and check the App on a device.
Step 6: Now that our Example scanner App is running fine, we need to integrate this to our project.
Step 7: First mark the android zxing project built from the last step as library from properties and checking the ‘is library’ option.
Step 8: Okay now from our project (Already existing one or i created a new project for the sake of this tutorial) just go to properties > under references add the scanner project.
Step 9: First of all add this permission to your manifest:
<uses–permission android:name=”android.permission.CAMERA” />
then add this activity declaration to your Manifest File:
1
2
3
4
5
6
7
|
<activity
android:name=“com.google.zxing.client.android.CaptureActivity”
android:configChanges=“orientation|keyboardHidden”
android:screenOrientation=“portrait”
android:theme=“@android:style/Theme.NoTitleBar.Fullscreen”
android:windowSoftInputMode=“stateAlwaysHidden” >
</activity>
|
Step 10: Intent to call scanner:
1
2
3
|
Intent intent = new Intent(“com.google.zxing.client.android.SCAN”);
intent.putExtra(“SCAN_MODE”, “QR_CODE_MODE”);
startActivityForResult(intent, 0);
|
Available Scan Modes:
SCAN_MODE : Decodes all barcodes that are understood by zxing.
PRODUCT_MODE : Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get prices, reviews, etc. for products.
ONE_D_MODE : Decode only 1D barcodes.
QR_CODE_MODE : Decode only QR codes.
DATA_MATRIX_MODE : Decode only Data Matrix codes.
AZTEC_MODE : Decode only Aztec.
PDF417_MODE : Decode only PDF417.
Use can also set multiple formats using: “SCAN_FORMATS”, “Comma separated scan modes”
Ex: intent.putExtra(“SCAN_FORMATS”, “PRODUCT_MODE,ONE_D_MODE,DATA_MATRIX_MODE”);
Note: It is recommended to explicitly set the formats which are only required for the scan.
Optionally zxing also provides to set the scanning rectangle height and width in pixels.
The app will try to honor these, but will clamp them to the size of the preview frame.
You should specify both or neither, and pass the size as an int. [SCAN_WIDTH, SCAN_HEIGHT]
Also you can set the Prompt message to show on-screen when scanning by intent, using [PROMPT_MESSAGE]
Content has been abstracted from intent.java from the zxing library. Please refer the below link for more information on Intent options:
https://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/Intents.java
Step 11: In on Activity results get the scanned results:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == SCANNER_REQUEST_CODE) {
// Handle scan intent
if (resultCode == Activity.RESULT_OK) {
// Handle successful scan
String contents = intent.getStringExtra(“SCAN_RESULT”);
String formatName = intent.getStringExtra(“SCAN_RESULT_FORMAT”);
byte[] rawBytes = intent.getByteArrayExtra(“SCAN_RESULT_BYTES”);
int intentOrientation = intent.getIntExtra(“SCAN_RESULT_ORIENTATION”, Integer.MIN_VALUE);
Integer orientation = (intentOrientation == Integer.MIN_VALUE) ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra(“SCAN_RESULT_ERROR_CORRECTION_LEVEL”);
} else if (resultCode == Activity.RESULT_CANCELED) {
// Handle cancel
}
} else {
// Handle other intents
}
}
|
Complete code of MainActivity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
public class MainActivity extends Activity implements OnClickListener {
public int SCANNER_REQUEST_CODE = 123;
TextView tvScanResults;
Button btnScan;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
tvScanResults = (TextView) findViewById(R.id.tvResults);
btnScan = (Button) findViewById(R.id.btnScan);
btnScan.setOnClickListener(this);
}
@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;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == SCANNER_REQUEST_CODE) {
// Handle scan intent
if (resultCode == Activity.RESULT_OK) {
// Handle successful scan
String contents = intent.getStringExtra(“SCAN_RESULT”);
String formatName = intent.getStringExtra(“SCAN_RESULT_FORMAT”);
byte[] rawBytes = intent.getByteArrayExtra(“SCAN_RESULT_BYTES”);
int intentOrientation = intent.getIntExtra(“SCAN_RESULT_ORIENTATION”, Integer.MIN_VALUE);
Integer orientation = (intentOrientation == Integer.MIN_VALUE) ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra(“SCAN_RESULT_ERROR_CORRECTION_LEVEL”);
tvScanResults.setText(contents + “\n\n” + formatName);
} else if (resultCode == Activity.RESULT_CANCELED) {
// Handle cancel
}
} else {
// Handle other intents
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btnScan) {
// go to fullscreen scan
Intent intent = new Intent(“com.google.zxing.client.android.SCAN”);
intent.putExtra(“SCAN_MODE”, “SCAN_MODE”);
startActivityForResult(intent, SCANNER_REQUEST_CODE);
}
}
}
|
Final Manifest file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<?xml version=“1.0” encoding=“utf-8”?>
<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“com.td.barcodeqrscanner”
android:versionCode=“1”
android:versionName=“1.0” >
<uses-sdk
android:minSdkVersion=“8”
android:targetSdkVersion=“18” />
<uses-permission android:name=“android.permission.CAMERA” />
<application
android:allowBackup=“true”
android:icon=“@drawable/ic_launcher”
android:label=“@string/app_name”
android:theme=“@style/AppTheme” >
<activity
android:name=“com.td.barcodeqrscanner.MainActivity”
android:configChanges=“orientation|navigation”
android:label=“@string/app_name”
android:screenOrientation=“portrait” >
<intent-filter>
<action android:name=“android.intent.action.MAIN” />
<category android:name=“android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<!– ZXing scanner –>
<activity
android:name=“com.google.zxing.client.android.CaptureActivity”
android:configChanges=“orientation|keyboardHidden”
android:screenOrientation=“portrait”
android:theme=“@android:style/Theme.NoTitleBar.Fullscreen”
android:windowSoftInputMode=“stateAlwaysHidden” >
</activity>
</application>
</manifest>
|