<1>使用zxing二维码实现扫一扫功能,需要添加zxing.jar包到libs以及将下面的相关的文件导入到项目中
<2>在清单文件中添加所要用到的权限,并注册activity
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.hardware.camera" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<activity android:name=".activity.CaptureActivity" />
<3>核心代码:
//跳转到扫描界面,并返回值到所在的activity
Intent intent = new Intent(getActivity(), CaptureActivity.class);
startActivityForResult(intent, 100);
在当前的fragment中重写onActivityResult()方法
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
//如果bundle不为空
if (bundle != null) {
//获取扫描到的值
String result = bundle.getString("result");
//判断是否是网页地址,并且判断是否是与微信有关的网址
if (Patterns.WEB_URL.matcher(result).matches() && !result.startsWith("http://weixin.qq.com/")) {
//通过默认的浏览器打开网页
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.parse(result);
intent.setData(uri);
startActivity(intent);
} else if (result.startsWith("http://weixin.qq.com/")) {
//如果是与微信有关的网址,则跳转到ScanResultActivity
Intent intent = new Intent(getActivity(), ScanResultActivity.class);
intent.putExtra("result", "以下内容非本应用提供,请谨慎使用,与微信有关");
startActivity(intent);
} else {
//否则跳转到ScanResultActivity中
Intent intent = new Intent(getActivity(), ScanResultActivity.class);
intent.putExtra("result", "无法展示");
startActivity(intent);
}
} else {
//bundle为空时,表示无法识别,依然跳转到ScanResultActivity中
Intent intent = new Intent(getActivity(), ScanResultActivity.class);
intent.putExtra("result", "无法识别");
startActivity(intent);
}
}
}
<4>在ScanResultActivity中,将传过来的值展示出来
public class ScanResultActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_result);
tv = ((TextView) findViewById(R.id.scan_tv));
Intent intent=getIntent();
String result=intent.getStringExtra("result");
tv.setText(result);
}
}
至此二维码扫描的功能就完成了,但是如果想要修改扫描框则去修改ViewfinderView,想要修改扫描框的大小,去camera包下的CameraManager修改
public final class ViewfinderView extends View {
//刷新界面的时间
private static final long ANIMATION_DELAY = 20L;
private static final int OPAQUE = 0xFF;
//四个绿色边角对应的长度
private int ScreenRate;
//四个绿色边角对应的宽度
private final int CORNER_WIDTH = 10;
//扫描框中间的线的宽度
private static final int MIDDLE_LINE_WIDTH = 6;
//扫描中的中间线与扫描框左右的间隙
private static final int MIDDLE_LINE_PADDING = 5;
//中间那条线每次刷新移动的距离
private static final int SPEEN_DISTANCE = 5;
//手机的屏幕宽度
private static float density;
//字体大小
private static final int TEXT_SIZE = 16;
//字体距离扫描框下面的距离
private static final int TEXT_PADING_TOP = 30;
//画笔
private final Paint paint;
//中间滑动线的最顶端的位置
private int slideTop;
//中间滑动线的最低端的位置
private int slideBottom;
private Bitmap resultBitmap;
private final int maskColor;
private final int resultColor;
// private final int frameColor;
// private final int laserColor;
private final int resultPointColor;
// private int scannerAlpha;
private Collection possibleResultPoints;
private Collection lastPossibleResultPoints;
private boolean isFirst;
// This constructor is used when the class is built from an XML resource.
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取屏幕的宽度
density = context.getResources().getDisplayMetrics().density;
//将像素转化为dp
ScreenRate = (int) (20 * density);
// Initialize these once for performance rather than calling them every time in onDraw().
paint = new Paint();
Resources resources = getResources();
maskColor = resources.getColor(R.color.viewfinder_mask);
resultColor = resources.getColor(R.color.result_view);
// frameColor = resources.getColor(R.color.viewfinder_frame);
// laserColor = resources.getColor(R.color.viewfinder_laser);
resultPointColor = resources.getColor(R.color.possible_result_points);
// scannerAlpha = 0;
possibleResultPoints = new HashSet(5);
}
@Override
public void onDraw(Canvas canvas) {
//中间的扫描线,你要修改扫描框的大小,去cameraManager里面去修改
Rect frame = CameraManager.get().getFramingRect();
if (frame == null) {
return;
}
//初始化中间线滑动的最上边和最下边
if (!isFirst) {
isFirst = true;
slideTop = frame.top;
slideBottom = frame.bottom;
}
//获取屏幕宽高
int width = canvas.getWidth();
int height = canvas.getHeight();
// Draw the exterior (i.e. outside the framing rect) darkened
//画出扫描框外面的阴影部分,共四个部分,扫描框的上面到屏幕上面,扫描框的下面
//到屏幕的下面,扫描框的左边到屏幕的左边,扫描框的右边到屏幕的右边
paint.setColor(resultBitmap != null ? resultColor : maskColor);
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (resultBitmap != null) {
// Draw the opaque result bitmap over the scanning rectangle
paint.setAlpha(OPAQUE);
canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
} else {
// Draw a two pixel solid black border inside the framing rect
//画边框线上的角,总共8个部分
paint.setColor(Color.GREEN);
canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate, frame.top + CORNER_WIDTH, paint);
canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top + ScreenRate, paint);
canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right, frame.top + CORNER_WIDTH, paint);
canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top + ScreenRate, paint);
canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left + ScreenRate, frame.bottom, paint);
canvas.drawRect(frame.left, frame.bottom - ScreenRate, frame.left + CORNER_WIDTH, frame.bottom, paint);
canvas.drawRect(frame.right - ScreenRate, frame.bottom - CORNER_WIDTH, frame.right, frame.bottom, paint);
canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom - ScreenRate, frame.right, frame.bottom, paint);
// Draw a red "laser scanner" line through the middle to show decoding is active
// paint.setColor(laserColor);
// paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
// scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
// int middle = frame.height() / 2 + frame.top;
// canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
//绘画中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTENCE
slideTop += SPEEN_DISTANCE;
if (slideTop >= frame.bottom) {
slideTop = frame.top;
}
canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop - MIDDLE_LINE_WIDTH / 2, frame.
right - MIDDLE_LINE_PADDING, slideTop + MIDDLE_LINE_WIDTH / 2, paint);
//画边框下面的字
paint.setColor(Color.WHITE);
paint.setTextSize(TEXT_SIZE * density);
paint.setAlpha(0x50);
paint.setTypeface(Typeface.create("System", Typeface.BOLD));
canvas.drawText(getResources().getString(R.string.scan_text), frame.left - 42, (float) (frame.bottom + (float) TEXT_PADING_TOP * density), paint);
Collection currentPossible = possibleResultPoints;
Collection currentLast = lastPossibleResultPoints;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new HashSet(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(OPAQUE);
paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
}
}
if (currentLast != null) {
paint.setAlpha(OPAQUE / 2);
paint.setColor(resultPointColor);
for (ResultPoint point : currentLast) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
}
}
//只刷新扫描框的内容,其他地方不刷新
// Request another update at the animation interval, but only repaint the laser line,
// not the entire viewfinder mask.
postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
}
}
public void drawViewfinder() {
resultBitmap = null;
invalidate();
}
/**
* Draw a bitmap with the result points highlighted instead of the live scanning display.
*
* @param barcode An image of the decoded barcode.
*/
public void drawResultBitmap(Bitmap barcode) {
resultBitmap = barcode;
invalidate();
}
public void addPossibleResultPoint(ResultPoint point) {
possibleResultPoints.add(point);
}
}
CaptureActivity的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<com.sq.dissertation.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentTop="true"
android:background="@color/menuLine">
<ImageView
android:id="@+id/btn_cancel_scan"
android:layout_width="75dp"
android:layout_height="match_parent"
android:src="@mipmap/menu_back"
android:layout_marginLeft="2dp"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/btn_cancel_scan"
android:layout_alignBaseline="@+id/btn_cancel_scan"
android:layout_centerHorizontal="true"
android:gravity="center_vertical"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="二维码扫描"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold" />
RelativeLayout>
RelativeLayout>