二维码的扫描与生成

二维码呀,现在的项目基本都有的东西,早就有人写出来了,我也是在用别人的基础上写写心得啊什么的,自己封装一个还没那时间和技术去搞,所以这篇文章讲的就是怎么用。


二维码

呃,图有点大,好像还暴露了些许信息,算了不管了,就这样吧。

效果大概就是这样的。

接下来讲讲怎么实现的:

首先是下包,用的是ZXing
http://download.csdn.net/download/wiseant/9136099
原谅我忘了之前自己用的是哪个,然后简书又不能上传,好了我百度了个版本一样的发过来,我是用这个版本的,要是不行你们百度下这个版本吧,正常应该是OK的。

然后是布局文件,这个很简单

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_scan"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#1c1c1c"
    android:orientation="vertical">

    <include layout="@layout/head"
        android:id="@+id/head"/>


    <SurfaceView                                                 //这个就是主要的啦
        android:id="@+id/surfaceview"
        android:background="@drawable/saomiao"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/head"/>



    <RelativeLayout                                                //这个本来不必要的,为了那天线没办法
        android:id="@+id/layout_contain"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:layout_marginTop="170dp"
        android:layout_marginRight="70dp"
        android:layout_marginLeft="70dp">

        <com.***.**.view.*****//这个就是那条线
            android:id="@+id/scanline"
            android:layout_width="match_parent"
            android:layout_height="2dp"
            android:layout_marginTop="33dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"/>

    </RelativeLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:textColor="@color/white"
        android:layout_gravity="bottom"
        android:gravity="center|top"
        android:padding="20dp"
        android:text="将医生二维码放入框内,即可自动扫描"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

</RelativeLayout>

这里很多坑,SurfaceView 要是再嵌套一层layout的话,里面的画面会变形,还有不能全屏(具体什么原因,暂时没空去找,大神可以指点一下)。至于那个背景框,叫UI截个图妥妥的不用自己话后面的线。
还有那个ScanLineView 是别人给我的,它的动画长度略坑,所以勉强调成这样刚好。
其实最好的方法就是改里面的代码,但是时间不够还是算了,将就着用吧。

接下来是activity的代码了,没有全部贴,二维码那块都在这里了,其实很少东西的

   @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

//        setContentView(R.layout.activity_scan);
        title.setText("扫描医生二维码");

        qrScanManager = new QRScanManager(this);           //主要是这玩意而已
        layout_contain = (RelativeLayout) findViewById(R.id.layout_contain);
        qrScanManager.initWithSurfaceView(this, R.id.surfaceview);
        qrScanManager.setBeepResource(R.raw.beep);
        Rect rect = initCrop();
        qrScanManager.setCropRect(rect);

        ScanLineView scanline = (ScanLineView) findViewById(R.id.scanline);

        // 动画效果
        TranslateAnimation animation = new TranslateAnimation(
                Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, 1.0f);
        animation.setDuration(4500);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        scanline.startAnimation(animation);
    }

    private Rect initCrop() {

        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();

        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) layout_contain.getLayoutParams();
        int x = params.leftMargin;
        int y = params.topMargin;
        int width = screenWidth - 2 * x;
        int height = width;

        params.height = height;

        layout_contain.setLayoutParams(params);

        return new Rect(x, y, width + x, height + y);
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        qrScanManager.onResume();

    }

    @Override
    protected void onPause() {
        qrScanManager.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        qrScanManager.onDestroy();
        super.onDestroy();
    }

    @Override
    public void onScanResult(String content) {
      Toast.makeText(this, "结果:" + code[1], Toast.LENGTH_SHORT).show();
    }

至于那个ScanLineView 其实要是不要求的话去掉它,代码就简单多了,要的人我放上代码吧


public class ScanLineView extends View {
    Paint paint = new Paint();

    private float density;// 屏幕密度
    private float width, height;// 控件的宽度高度

    public ScanLineView(Context context) {
        super(context);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ScanLineView(Context context, AttributeSet attrs, int defStyleAttr,
                        int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public ScanLineView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public ScanLineView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        density = getResources().getDisplayMetrics().density;
        // 去锯齿
        paint.setAntiAlias(true);
        paint.setColor(Color.parseColor("#53d555"));

        
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;

        } else {
            width = (int) (250 * density);
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;

        } else {
            height = (int) (250 * density);
        }

        // Log.e("tag", " ------ width:"+width +"   height:"+height);
        setMeasuredDimension((int) this.width, (int) this.height);
        
        Shader mShader = new LinearGradient( width/2.0f,height,width/2.0f, 0, new int[] {
                Color.BLUE, Color.TRANSPARENT}, null,
                Shader.TileMode.CLAMP);
        paint.setShader(mShader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 为Paint设置渐变器

        // 绘制矩形
        canvas.drawRect(0, 0, width, height, paint);
    }
}

嗯,就是这个自定义View了,其实代码很少,东西也不多

扫描的就是这么简单就搞定了···

然后是生成二维码,这个更简单,一个工具类搞定

    /**
     * 生成一个二维码图像
     *
     * @param url
     *          传入的字符串,通常是一个URL
     * @param QR_WIDTH
     *          宽度(像素值px)
     * @param QR_HEIGHT
     *          高度(像素值px)
     * @return
     */
    public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH, int QR_HEIGHT) {
        try {
            // 判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return null;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
            int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
            // 下面这里按照二维码的算法,逐个生成二维码的图片,
            // 两个for循环是图片横列扫描的结果
            for (int y = 0; y < QR_HEIGHT; y++) {
                for (int x = 0; x < QR_WIDTH; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * QR_WIDTH + x] = 0xff000000;
                    } else {
                        pixels[y * QR_WIDTH + x] = 0xffffffff;
                    }
                }
            }
            // 生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
            // 显示到一个ImageView上面
            // sweepIV.setImageBitmap(bitmap);
            return bitmap;
        } catch (WriterException e) {
            Log.i("log", "生成二维码错误" + e.getMessage());
            return null;
        }
    }

生成二维码,一个bitmap搞定
Bitmap bitmap = QRCodeUtil.create2DCoderBitmap(qrCodeBean.getQRCodeUrl(), 250, 250);

有了bitmap,然后爱放哪放哪,妥妥的就这么简单搞定了。

说说题外话:
最近少写了好多篇文章了,说是项目多了,忙不过来,其实还有原因就是自己懒,天气冷了,人也越变越懒了,本来这篇文章早几天就想写的了,拖啊拖啊的就到了今天。

话说,最近逛着逛着简书,发现喜欢上了看 堂主姓蔡 这个人写的故事,大多是鬼故事,都还不错的样子。

再有,今晚准备剁手

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容