1. 程式人生 > >Android使用ZBar掃描二維碼/條形碼(例項)+常見問題彙總

Android使用ZBar掃描二維碼/條形碼(例項)+常見問題彙總

寫在前面:因專案需求,需要實現二維碼掃碼功能,筆者測試過多種開源掃碼工具,但因不跨平臺、掃描速度慢等問題逐個放棄,最後選用ZBar實現功能,筆者發現ZBar掃碼在跨主流手機平臺、掃碼速度等方面有較明顯的優勢,現將核心功能整理成示例程式碼,便於日後複用和有需要的讀者參考。

========================2017.06.19 重要更新==========================

有讀者反饋程式碼在Android 6.0和7.0上執行會閃退,經查,是許可權問題,Android6.0+具有更高要求的許可權限制,對敏感性操作(如呼叫攝像頭、訪問通訊錄等)需要額外申請執行時許可權(當然AndroidManifest.xml也要註冊)。詳細資料可以參考

這裡。問題現已解決,原始碼如下,親測,相容Android 5.0/6.0/7.0。

示例原始碼:(推薦下載,完美相容Android 5.0/6.0/7.0,程式碼簡單易移植,0積分共享)

主要新增的程式碼段:

1、新增許可權判斷

// 判斷是否有相機許可權(主要用於相容Android 6.0+)
		if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 
				== PackageManager.PERMISSION_GRANTED) {// 有相機許可權
			initViews();
		} else {
			ActivityCompat.requestPermissions(this,
					new String[] { Manifest.permission.CAMERA },
					CAMERA_REQUEST_CODE);// 無許可權,申請相機許可權,然後利用回撥函式判斷是否申請成功
		}

2、利用申請許可權的回撥結果進一步操作

@Override
public void onRequestPermissionsResult(int requestCode,
		@NonNull String[] permissions, @NonNull int[] grantResults) {// 申請許可權後的回撥操作
		// 判斷請求碼
		if (requestCode == CAMERA_REQUEST_CODE) {
			// grantResults授權結果
			if (grantResults.length > 0
					&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
				initViews();
			} else {
				// 授權失敗
				showTip();
			}
		}
	}

**注意**

第一,以上程式碼段需實現OnRequestPermissionsResultCallback介面,該介面只存在於較新版本的android-support-v4.jar中,如果讀者的android-support-v4.jar中不包含該介面,可以替換以下供下載的原始碼中的jar包。

第二,以上程式碼段需在具有可傳送請求的元件中編碼(比如Activity、Fragment等上下文環境中),否則onRequestPermissionsResult無法正常回調,即便在其它元件(如Adapter)中傳入Activity等的引用例項,也同樣如此。這點很重要!

有疑問歡迎留言!

========================2016.08.31更新==========================

原文的示例適用於Android 4.X系統,但在Android 5.0上不相容,出現“開啟攝像頭後立即自動關閉”的問題,報錯:

AndroidRuntime(2797): java.lang.UnsatisfiedLinkError: dlopen failed: "/data/appxxx.xxx.xxxx-1/lib/arm64/libiconv.so" is 32-bit instead of 64-bit

原因是,Android 5.0+(包括6.0)預設開啟ART模式並支援64位,如果libs下帶“64”的資料夾(5.0以上系統會自動在此資料夾下載入.so檔案)裡的是32位而不是64位的.so檔案,就會報上述錯誤。

筆者在網上找到跨平臺的ZBar Demo,現將資源共享,本文原始資源(以下“資源下載”中提供的)不再建議使用

Android使用ZBar掃描二維碼/條形碼(例項)【相容Android5.0平臺】

資源下載(已不建議使用,因為不相容Android 5.0+系統)

使用方式

1.複製com.zbar.lib及其下共4個包檔案到專案中。

2.在lib下新增armeabi中的libiconv.so和libzbar.so庫檔案。

3.新增res下的資原始檔,包括drawable、layout、raw、values(包含ids.xml)等。

4.在AndroidManifest.xml清單中新增許可權和Activity宣告。

5.呼叫掃碼功能,在呼叫處通過以下程式碼使用掃碼功能:

Intent intent = new Intent();
intent.setClass(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, SCANNIN_GREQUEST_CODE);

6.獲得掃碼結果,在步驟5中程式碼塊所在的Activity中通過以下程式碼獲取掃碼結果:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	switch (requestCode) {
	case SCANNIN_GREQUEST_CODE:
		if (resultCode == RESULT_OK) {
			String result = data.getStringExtra("QR_CODE");
			// TODO 獲取結果,做邏輯操作
			tvResult.setText(result);
		} else {
			Toast.makeText(this, "無法獲取掃碼結果", 2000).show();
		}
		break;
	}
}

測試效果:

1.二維碼(一串字元:1234567890)

2.掃碼前(點選“掃碼”開始掃碼)

3.掃碼時(對準二維碼)

4.掃碼後(呈現出掃碼結果)

常見問題彙總

移植後,若專案本身沒報錯,但不能掃碼,可能存在以下問題:

1.未移植armeabi資料夾下的libiconv.so和libzbar.so庫檔案。(缺少時一般在執行時報錯)

2.未在AndroidManifest.xml清單中配置所需許可權。(可以執行,但掃碼時黑屏,無法開啟攝像頭)

  <!-- 二維碼掃碼 -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

3.未在AndroidManifest.xml清單檔案中配置Activity:CaptureActivity。(缺少時一般在執行時報錯)

<activity
android:name="com.zbar.lib.CaptureActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:windowSoftInputMode="stateAlwaysHidden" >

4.報錯:

AndroidRuntime(2797): java.lang.UnsatisfiedLinkError: dlopen failed: "/data/appxxx.xxx.xxxx-1/lib/arm64/libiconv.so" is 32-bit instead of 64-bit

解決方案見上述2016.08.31更新說明。

5.報錯閃退:

java.lang.RuntimeException:getParameters failed (empty parameters)

解決方案見上述2017.06.19更新內容。

轉載請註明出處:

http://blog.csdn.net/daijin888888/article/details/51374263