android使用zxing二维码扫一扫功能

来源:互联网 发布:优化再造办税服务 编辑:程序博客网 时间:2024/05/23 21:11

<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<ResultPoint> possibleResultPoints;    private Collection<ResultPoint> 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<ResultPoint>(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<ResultPoint> currentPossible = possibleResultPoints;            Collection<ResultPoint> currentLast = lastPossibleResultPoints;            if (currentPossible.isEmpty()) {                lastPossibleResultPoints = null;            } else {                possibleResultPoints = new HashSet<ResultPoint>(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的布局

<?xml version="1.0" encoding="utf-8"?><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>

这里写图片描述

0 0