Android : ประยุกต์ใช้ Zbar example บนแอพพลิเคชั่นของเรา
|หลังจากบทความก่อนได้อธิบาย example code ของ Zbar ไปแล้วนะครับครั้งนี้จะนำตัวอย่างนั้นกลับมาประยุกต์ใช้ในโปรเจ็คของเราใครยังไม่เคยอ่านบทความก่อนนะครับ ตามไปอ่านได้ที่ Android อ่าน QR code จากกล้องด้วย Zbar (อธิบาย Example Code) อีกทั้งในการนำตัวอย่างจาก Zbar มาประยุกต์ใช้ร่วมกับโปรเจ็คของเราทำให้ไม่ต้องติดตั้งแอพพลิเคชั่นสแกน QR-code อื่นๆก่อนเพื่อให้โปรเจ็คของเราไปเรียกใช้งาน (เสมือนเรานำตัวอย่างของ Zbar มาอยู่ในแอพพลิเคชั่นของเรา)
ภาพรวมแอพพลิเคชั่น
ประกอบด้วย 2 Activity คือ MainActivity และ CameraTestActivity (ซึ้งเราได้กล่าวถึงในบทความที่ผ่านมาแล้ว) โดย MainActivity จะทำการเรียก Camera TestActivity ให้ทำงานเพื่อขอผลลัพธ์โดยฟังก์ชั่น startAcitivtyForResult() หลังจากนั้นเมื่อ CameraTestActivity ได้ผลลัพธ์ก็จะส่งผลลัพธ์กลับโดยฟังก์ชั่น setResult() และ MainActivtiy จะรับผลลัพธ์โดยฟังก์ชั่น onActivityResult()
สาธิตตัวอย่าง
Step 1. import library
ทำการนำเข้า library มายังโปรเจ็คของเรานะครับ โดยการ คัทลอกไฟล์และโฟลเดอร์ทั้งหมดในโฟลเดอร์ libs ของตัวอย่าง (โปรเจ็ค CameraTestActivity) เป็นอันจบขั้นตอนการนำเข้าไลบรารี่
Step 2. copy ตัวอย่างจาก CameraTestActivity
คัทลอกทั้งในโฟลเดอร์ src และ res/layout ดั้งนี้ไฟล์ CameraTestActivity.java, CameraPreview.java และ main.xml
Step 3. ออกแบบ activity_main.xml
โดยในแอพพลิเคชั่นตัวอย่างนี้ เราต้องการ 1 Button และ 1 Edittext (เพื่อไปยังหน้าสแกน QR-code และ แสดงผลลัพธ์จากการสแกน)
activity_main.xml
<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="com.example.testzbar.MainActivity" >
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="85dp"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/editText1"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="To ... Zbar" />
</RelativeLayout>
Step 4. เปิดกล้องสแกน QR-Code
ในขั้นตอนนี้ แค่กำหนดให้เมื่อกดปุ่ม R.id.button1 แอพพลิเคชั่นจะไปเริ่ม CameraTestActivity
Q – startActivityForResult แตกต่างจาก startActivity อย่างไรหล่ะ
A – startActivity ใช้เพื่อเริ่ม Activity ใหม่
– startActivityForResult ใช้เพื่อเริ่ม Activity ใหม่และต้องการผลลัพธ์เมื่อจบ Activity นั้นๆ
MainActivity.xml
public class MainActivity extends Activity implements OnClickListener{
private Button buttonToCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonToCamera = (Button)findViewById(R.id.button1);
buttonToCamera.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button1: // เมื่อกดปุ่ม button1
Intent intent = new Intent(this, CameraTestActivity.class);
startActivityForResult(intent, 1); // เริ่ม CameraTestActivity
break;
default:
break;
}
}
}
Step 5. ปรับแต่งให้ CameraTestActivity ส่งค่าที่สแกนได้กลับ
ขั่นตอนนี้จะเพิ่มการคืนค่าผลลัพธ์จาก CameraTestActivity โดยคืนค่าผลลัพธ์เมื่อพบ QR-code โดยเรียกใช้ฟังก์ชั่น setResult ทำการคือค่าผลลัพธ์กลับไปให้ Activity ที่เรียกใช้ครับ
*ผมย่อ code ไว้นะครับส่วนที่เปลี่ยนแปลงคือสีเขียวครับ
* อย่าคัดลอกทั้งหมดให้คัทลอกแค่ส่วน source code สีเขียวไปปรับใน CameraTestActivity.java เดิมนะครับ
CameraTestActivity.java
public class CameraTestActivity extends Activity
{
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
TextView scanText;
Button scanButton;
ImageScanner scanner;
private boolean barcodeScanned = false;
private boolean previewing = true;
private String resultText = "";
static {
System.loadLibrary("iconv");
}
public void onCreate(Bundle savedInstanceState) {
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
}
public void onPause() {
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
}
private void releaseCamera() {
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
}
private Runnable doAutoFocus = new Runnable() {
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
};
PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
scanText.setText("barcode result " + sym.getData());
resultText = sym.getData();
barcodeScanned = true;
}
Intent returnIntent = new Intent();
returnIntent.putExtra("result",resultText);
setResult(RESULT_OK,returnIntent);
finish();
}
}
};
// Mimic continuous auto-focusing
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
}
Step 6. MainActivity รับผลลัพธ์จาก CameraTestActivity
ส่วนนี้ทำการรับผลลัพธ์จาก CameraTestActivity โดยฟังก์ชั่น onActivityResult จะได้ผลลัพธ์จากพารามิเตอร์ data และเพิ่มลง EditText
* อย่าคัดลอกทั้งหมดให้คัทลอกแค่ส่วน source code สีเขียวไปปรับใน MainActivity.java เดิมนะครับ
MainActivity.java
public class MainActivity extends Activity implements OnClickListener{
private Button buttonToCamera;
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonToCamera = (Button)findViewById(R.id.button1);
buttonToCamera.setOnClickListener(this);
editText = (EditText)findViewById(R.id.editText1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
String contents = data.getStringExtra("result");
editText.setText(contents);
}
if(resultCode == RESULT_CANCELED){
//handle cancel
}
}
}
@Override
public void onClick(View v) {
// ส่วนนี้ไม่เปลี่ยนแปลง เลยย่อไว้ครับ
}
}
เมื่อจบทุกขั้นตอนข้างบนแล้วทดลองรันแอพพลิเคชั่นดูครับ และขอสรุปสั้นๆก่อนจะจบบทความ ตัวอย่างนี้เป็นตัวอย่างง่ายๆที่นำ example code ของ Zbar มาประยุกต์ใช้กับโปรเจ็คโดยการเรียกใช้ CamaraTestActivity ให้ทำงานและดึงผลลัพธ์กลับมาแสดงผลบน MainActivity ครับ หวังว่าจะมีประโยชน์แก่คนที่พบเห็นนะครับ @Octoboy