目前二维码(条形码)的使用非常广泛,所以啊,就想去实现以下嘛,最简单的方法就是选择开源库了。
在网上一查开源库还是很多的,介绍使用最多的就是zxing,所以这里也就是用zxing了。但是由于zxing开源库太大了,有很多不是Android要用的,所以网上很多都是介绍将zxing库中Android用到内容重新封装使用。
但是对于新手来说还是不太好操作的,我看了下,大部分都是拷贝原工程的一部分代码,然后再进行一系列的修改,最终成功使用。
我这里介绍的是直接使用zxing-android-embedded开源库(其实差不多,但是方便,简单),对于需要快速实现该功能的项目来说还是很好的。
首先添加依赖(3.5.0版本,最新的可以取官网查询)
compile 'com.journeyapps:zxing-android-embedded:3.5.0'
添加权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
有些小伙伴就发现了CAMERA是危险权限,Android6.0以上需要申请运行时权限
但是该库已经封装好了,所以只需要这里添加就行,还是很方便的,为那些会忘记的同学降低出错率
FLASHLIGHT权限是为了扫描时开启闪光灯,如不需要就删除
/**
* 传入一个字符串,生成一个二维码
* @param str
* @return
*/
private Bitmap encodeAsBitmap(String str){
Bitmap bitmap = null;
BitMatrix result;
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try {
//可以指定生成二维码Bitmap的大小
result = multiFormatWriter.encode(str, BarcodeFormat.QR_CODE, 400, 400);
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
bitmap = barcodeEncoder.createBitmap(result);
} catch (WriterException e){
e.printStackTrace();
} catch (IllegalArgumentException iae){
return null;
}
return bitmap;
}
先自定义一个扫描Activity(Fragment)
public class ScanActivity extends AppCompatActivity implements DecoratedBarcodeView.TorchListener {
private CaptureManager captureManager;
private boolean isLightOn = false;
private DecoratedBarcodeView mDBV;
private Button swichLight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//隐藏状态栏,因为该activity使用无actionbar主题,所以就是全屏了
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_scan);
swichLight = findViewById(R.id.btn_switch);
mDBV = findViewById(R.id.dbv_custom);
mDBV.setTorchListener(this);
// 如果没有闪光灯功能,就去掉相关按钮
if(!hasFlash()) {
swichLight.setVisibility(View.GONE);
}
swichLight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isLightOn){
mDBV.setTorchOff();
}else{
mDBV.setTorchOn();
}
}
});
//重要代码,初始化捕获
captureManager = new CaptureManager(this,mDBV);
captureManager.initializeFromIntent(getIntent(),savedInstanceState);
captureManager.decode();
}
// 判断是否有闪光灯功能
private boolean hasFlash() {
return getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
@Override
public void onTorchOn() {
Toast.makeText(this,"torch on", Toast.LENGTH_LONG).show();
isLightOn = true;
}
@Override
public void onTorchOff() {
Toast.makeText(this,"torch off",Toast.LENGTH_LONG).show();
isLightOn = false;
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
captureManager.onSaveInstanceState(outState);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return mDBV.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
@Override
protected void onPause() {
super.onPause();
captureManager.onPause();
}
@Override
protected void onResume() {
super.onResume();
captureManager.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
captureManager.onDestroy();
}
}
一些跟生命周期有关,记得重写,最核心的就是captureManager。
界面xml部分
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SwitchLight"
android:id="@+id/btn_switch"
android:layout_marginBottom="20dp"
android:background="#7f383838"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" />
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/dbv_custom"
app:zxing_framing_rect_width="250dp"
app:zxing_framing_rect_height="250dp"
app:zxing_preview_scaling_strategy="fitXY"
app:zxing_use_texture_view="true">
com.journeyapps.barcodescanner.DecoratedBarcodeView>
Android清单文件中scanActivity的配置
<activity
android:name=".ScanActivity"
android:screenOrientation="fullSensor"
android:stateNotNeeded="true"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:windowSoftInputMode="stateAlwaysHidden">
activity>
首先初始化,设置一些配置参数
private void initScan() {
integrator = new IntentIntegrator(this);
integrator.setPrompt("请扫描"); //底部的提示文字,设为""可以置空
integrator.setCameraId(0); //前置或者后置摄像头
integrator.setBeepEnabled(false); //扫描成功的「哔哔」声,默认开启
integrator.setCaptureActivity(ScanActivity.class); //设置扫描activity,也就是上面写的Activity
}
设置完就可以在启动了,一句代码就行
integrator.initiateScan();