Android使用ZBar掃描二維碼/條形碼(例項)+常見問題彙總
寫在前面:因專案需求,需要實現二維碼掃碼功能,筆者測試過多種開源掃碼工具,但因不跨平臺、掃描速度慢等問題逐個放棄,最後選用ZBar實現功能,筆者發現ZBar掃碼在跨主流手機平臺、掃碼速度等方面有較明顯的優勢,現將核心功能整理成示例程式碼,便於日後複用和有需要的讀者參考。
========================2017.06.19 重要更新==========================
有讀者反饋程式碼在Android 6.0和7.0上執行會閃退,經查,是許可權問題,Android6.0+具有更高要求的許可權限制,對敏感性操作(如呼叫攝像頭、訪問通訊錄等)需要額外申請執行時許可權(當然AndroidManifest.xml也要註冊)。詳細資料可以參考
示例原始碼:(推薦下載,完美相容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