精华内容
下载资源
问答
  • Android扫一扫获取结果

    2018-08-08 11:41:30
    Android扫一扫二维码,获取二维码结果代码,解压可直接使用。
  • android扫一扫依赖包

    2018-12-18 10:24:11
    android扫一扫依赖包 解压里边的arr依赖包。。。。。
  • androidstudio实现数据库查询excel,通过扫一扫功能查询,适合学习扫一扫功能的android开发人员,关于excel查询,我是通过将excel导入到sqlite,然后通过数据库查询,将内容显示出来。内含有完整的androidstudio源码...
  • Android扫一扫 有仿微信版

    千次阅读 2020-07-25 11:26:03
    第三方zxing的GitHub地址 用法: 国际惯例,先上图: Step 1 :添加依赖 ...uses-permission android:name="android.permission.CAMERA"/> Step 3 :activity_main.xml布局 添加 测试用的两个控件 <?

    第三方Zxing的GitHub地址:

    说明:

    这里一共有四种扫描界面,分别为:
    (tip:可根据需要,自行滑到相应的标题学习即可)

    一:基本用法:
    也就是Zxing的基本使用,最简便的扫描界面

    二:自定义扫描界面:带闪光灯
    在基本的界面上,添加了有闪光灯的按钮

    三:自定义扫描界面:带闪光灯 并修改其扫描界面
    这一种,就是对Zxing的扫描界面进行了大更改,可自定义扫描条,边框,等等,只要认真看代码步骤,自己也可以定义

    四:自定义扫描界面:改进版,仿微信扫描条

    这种,是仿照微信的界面的,扫描条是用图片通过动画做的,也可以更换图片,推荐使用这种!!

    相比第三种,性能上也比较好,因为第三种是不断的刷新界面形成扫描条动画,而刷新界面是很浪费性能的,所以,就会造成扫描条运动不流畅的视觉(加快运动更明显)
    而第四种的扫描条是通过图片动画实现的,所以运动是很平滑流畅的,也没有不断刷新界面,不浪费性能,所以,建议使用第四种!!!

    基本用法:

    国际惯例,先上图:
    在这里插入图片描述

    Step 1 :添加依赖

        //第三方zxing
        implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    

    Step 2 :添加权限

      <uses-permission android:name="android.permission.CAMERA"/>
    

    Step 3 :activity_main.xml布局 添加 测试用的两个控件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始"
            android:id="@+id/button"/>
    
        <ImageView
            android:id="@+id/iv_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    Step 4 :MainActivity 代码:

    public class MainActivity extends AppCompatActivity {
    
        private Button button;
        private ImageView ivImage;
    
        //  Step 1 : 初始化 获取控件 设置监听
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //获取测试的控件
            button = findViewById(R.id.button);//点击跳转到扫码活动
            ivImage = findViewById(R.id.iv_image);//输出二维码图片
    
            //控件监听
            listenerView();
        }
    
    
        private void listenerView() {
    
            //  Step 2 :跳转到扫描活动
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    //=======设置扫描活动  可根据需求设置以下内容
                    IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
    
                    //  1.扫描成功后的提示音,默认关闭
                    intentIntegrator.setBeepEnabled(true);
    
                    //  2.启动后置摄像头扫描,若为 1 为前置摄像头,默认后置
                    intentIntegrator.setCameraId(0);
    
                    /*  3.设置扫描的条码的格式:默认为所有类型
                     *   IntentIntegrator.PRODUCT_CODE_TYPES:商品码类型
                     *   IntentIntegrator.ONE_D_CODE_TYPES:一维码类型
                     *   IntentIntegrator.QR_CODE:二维码
                     *   IntentIntegrator.DATA_MATRIX:数据矩阵类型
                     *   IntentIntegrator.ALL_CODE_TYPES:所类有型
                     * */
                    intentIntegrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES);
    
                    /*  4.方向锁:true为锁定,false反之,默认锁定.
                    ps:在AndroidManifest.xml里设置以下属性,则扫码界面完全依赖传感器(tools红色提示,指向它会提示,点击左边蓝色Create...即可)
                    <activity
                        android:name="com.journeyapps.barcodescanner.CaptureActivity"
                        android:screenOrientation="fullSensor"
                        tools:replace="screenOrientation" />
                    * */
                    intentIntegrator.setOrientationLocked(true);
    
                    //  5.设置扫描界面的提示信息:默认为:请将条码置于取景框内扫描。(ps:设置没提示文字:setPrompt(""))
                    intentIntegrator.setPrompt("请选择二维码");
    
                    //  6.设置关闭扫描的时间(单位:毫秒),不设置不关闭
                    intentIntegrator.setTimeout(60000);
    
                    //  7.保存二维码图片:在onActivityResult方法里可获取保存的路径,根据需要来是否需要保存
                    intentIntegrator.setBarcodeImageEnabled(true);
    
                    //启动扫描
                    intentIntegrator.initiateScan();
    
                }
            });
    
        }
    
    
        //  Step 3 :处理扫码后返回的结果
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
    
            if(result!=null){
    
                //==是否扫到内容
                if (result.getContents()!=null){
                    Toast.makeText(this,"扫描结果:"+result.getContents(),Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(this,"取消扫码",Toast.LENGTH_LONG).show();
                }
    
                //==是否有保存照片的路径  在intentIntegrator已设置保存照片
                if(result.getBarcodeImagePath()!=null){
                    
                    FileInputStream file=null;
                    try {
                        file=new FileInputStream(new File(result.getBarcodeImagePath()));
                        ivImage.setImageBitmap(BitmapFactory.decodeStream(file));//显示获取的照片
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }finally {
                        try {
                            file.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
    
                }
                
                /*  获取条码种类:在intentIntegrator.setDesiredBarcodeFormats那设置扫码格式后(点击格式可进入查看该格式有多少个类型)
    
                    例如:PRODUCT_CODE_TYPES:商品码类型,它就有 UPC_A, UPC_E, EAN_8, EAN_13, RSS_14 种类
                    public static final Collection<String> PRODUCT_CODE_TYPES = list(UPC_A, UPC_E, EAN_8, EAN_13, RSS_14);
    
                    根据getFormatName获取到的种类,就知道是哪个扫码格式,进而根据需求进行相关操作
                 */
                if (result.getFormatName()!=null){
                    Toast.makeText(this,"图片格式:"+result.getFormatName(),Toast.LENGTH_LONG).show();
                }
    
    
            }else{
                super.onActivityResult(requestCode, resultCode, data);
            }
    
        }
        
    
    }
    

    自定义扫描界面:带闪光灯**

    国际惯例,先上图:图中白点为闪光灯按钮
    在这里插入图片描述

    Step 1 :引入依赖:

        //第三方zxing
        implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    
    

    Step 2 :申请权限:

        <!--相机-->
        <uses-permission android:name="android.permission.CAMERA"/>
        <!--若需要闪光灯权限 ,请加入此权限(自测不需要)-->
    <!--
        <uses-permission android:name="android.permission.FLASHLIGHT" />
    -->
    

    Step 3 :准备3个布局

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始"
            android:id="@+id/button"/>
    
    </LinearLayout>
    

    content_scan.xml

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!--
        layout_width、layout_height:启动扫描界面的布局参数
    
        zxing_framing_rect_width、zxing_framing_rect_height:
        在扫描界面中,只能扫描二维码的宽高,去掉后会有默认的宽高
        -->
        <com.journeyapps.barcodescanner.BarcodeView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_barcode_surface"
            app:zxing_framing_rect_width="250dp"
            app:zxing_framing_rect_height="250dp"/>
    
        <com.journeyapps.barcodescanner.ViewfinderView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_viewfinder_view"
            app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
            app:zxing_result_view="@color/zxing_custom_result_view"
            app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
            app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
    
    </merge>
    

    activity_scan.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!--装扫描界面的控件
        @layout/content_scan:为嵌入content_scan.xml的布局
        -->
        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/dbv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            app:zxing_scanner_layout="@layout/content_scan">
        </com.journeyapps.barcodescanner.DecoratedBarcodeView>
    
        <!--闪光灯图片 自行找图片样式
            @drawable/ic_flashlight_close 关闭时的图片
        -->
        <ImageButton
            android:id="@+id/ib_flashlight_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="60dp"
            android:background="@drawable/ic_flashlight_close"/>
    </RelativeLayout>
    

    Step 4 :ScanActivity.java

    public class ScanActivity extends AppCompatActivity {
        private CaptureManager capture;
        private ImageButton ibFlashlight;
        private DecoratedBarcodeView barcodeScannerView;
        private boolean bTorch = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            //==设置布局、获取控件
            setContentView(R.layout.activity_scan);
            barcodeScannerView = findViewById(R.id.dbv);
            ibFlashlight= findViewById(R.id.ib_flashlight_close);
    
            //==监听: 根据barcodeScannerView设置闪光灯ibFlashlight状态
            barcodeScannerView.setTorchListener(new DecoratedBarcodeView.TorchListener() {
                @Override
                public void onTorchOn() {//开灯
    
                    //R.drawable.ic_flashlight_open)  开灯显示的图片 自行找图片样式
                    ibFlashlight.setBackground(getResources().getDrawable(R.drawable.ic_flashlight_open));
                    bTorch = true;
                }
    
                @Override
                public void onTorchOff() {//关灯
    
                    //R.drawable.ic_flashlight_close)  关灯显示的图片 自行找图片样式
                    ibFlashlight.setBackground(getResources().getDrawable(R.drawable.ic_flashlight_close));
                    bTorch = false;
                }
            });
    
            //==开或关灯
            ibFlashlight.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(bTorch){
                        barcodeScannerView.setTorchOff();
                    } else {
                        barcodeScannerView.setTorchOn();
                    }
    
                }
            });
    
            //==初始化活动
            capture = new CaptureManager(this, barcodeScannerView);
    
            capture.initializeFromIntent(getIntent(), savedInstanceState);
    
            capture.decode();
        }
    
    
        @Override
        protected void onResume() {
            super.onResume();
            capture.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            capture.onPause();
            barcodeScannerView.setTorchOff();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            capture.onDestroy();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            capture.onSaveInstanceState(outState);
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
            capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
        }
    }
    

    Step 5 :MainActivity 代码:

    public class MainActivity extends AppCompatActivity {
    
        private Button button;
    
        //  Step 1 : 初始化 获取控件 设置监听
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //获取测试的控件
            button = findViewById(R.id.button);//点击跳转到扫码活动
    
            //控件监听
            listenerView();
        }
    
    
        private void listenerView() {
    
            //  Step 2 :跳转到扫描活动
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    //=======设置扫描活动  可根据需求设置以下内容
                    IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
    
                    //启动自定义的扫描活动,不设置则启动默认的活动
                    intentIntegrator.setCaptureActivity(ScanActivity.class);
    
                    //启动扫描
                    intentIntegrator.initiateScan();
    
                }
            });
    
        }
    
    
        //  Step 3 :处理扫码后返回的结果
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
    
            if(result!=null){
    
                //==是否扫到内容
                if (result.getContents()!=null){
                    Toast.makeText(this,"扫描结果:"+result.getContents(),Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(this,"取消扫码",Toast.LENGTH_LONG).show();
                }
    
    
            }else{
                super.onActivityResult(requestCode, resultCode, data);
            }
    
        }
        
    
        
    }
    

    自定义扫描界面:带闪光灯 并修改其扫描界面**

    国际惯例,先上图(ScanWidget代码里有介绍去掉四个角样式)本来是动图的
    本来是动图的

    tip:上面已经有介绍添加依赖和权限了,这里不多说,

    并且,所用到的xml和activity和第一种的相同。

    不同之处:
    1.新建一个自定义的扫描活动:ScanWidget,代码如下

    public class ScanWidget extends ViewfinderView {
    
        /* ******************************************    边角线相关属性    ************************************************/
    
        /**
         * "边角线长度/扫描边框长度"的占比 (比例越大,线越长)
         */
        public float mLineRate = 0.1F;
    
        /**
         * 边角线厚度 (建议使用dp)
         */
        public float mLineDepth =  TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
    
        /**
         * 边角线颜色
         */
        public int mLineColor = Color.WHITE;
    
        /* *******************************************    扫描线相关属性    ************************************************/
    
        /**
         * 扫描线起始位置
         */
        public int mScanLinePosition = 0;
    
        /**
         * 扫描线厚度
         */
        public float mScanLineDepth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
    
        /**
         * 扫描线每次重绘的移动距离
         */
        public float mScanLineDy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());
    
        /**
         * 线性梯度
         */
        public LinearGradient mLinearGradient;
    
        /**
         * 线性梯度位置
         */
        public float[] mPositions = new float[]{0f, 0.5f, 1f};
    
        /**
         * 线性梯度各个位置对应的颜色值
         */
        public int[] mScanLineColor = new int[]{0x00FFFFFF, Color.WHITE, 0x00FFFFFF};
    
    
    
        // This constructor is used when the class is built from an XML resource.
        public ScanWidget(Context context, AttributeSet attrs) {
            super(context, attrs);
    
        }
    
    
        @Override
        public void onDraw(Canvas canvas) {
            refreshSizes();
            if (framingRect == null || previewFramingRect == null) {
                return;
            }
    
            final Rect frame = framingRect;
            final Rect previewFrame = previewFramingRect;
    
            //=====绘制4个角  可以注释此段代码,就像微信那样只要扫描线在动的样式了
            paint.setColor(mLineColor); // 定义四个角画笔的颜色(本身整个扫描界面都为此颜色,通过设置四个角距离而被覆盖,进而形成四个角)
            //左上角
            canvas.drawRect(frame.left, frame.top, frame.left + frame.width() * mLineRate, frame.top + mLineDepth, paint);
            canvas.drawRect(frame.left, frame.top, frame.left + mLineDepth, frame.top + frame.height() * mLineRate, paint);
    
            //右上角
            canvas.drawRect(frame.right - frame.width() * mLineRate, frame.top, frame.right, frame.top + mLineDepth, paint);
            canvas.drawRect(frame.right - mLineDepth, frame.top, frame.right, frame.top + frame.height() * mLineRate, paint);
    
            //左下角
            canvas.drawRect(frame.left, frame.bottom - mLineDepth, frame.left + frame.width() * mLineRate, frame.bottom, paint);
            canvas.drawRect(frame.left, frame.bottom - frame.height() * mLineRate, frame.left + mLineDepth, frame.bottom, paint);
    
            //右下角
            canvas.drawRect(frame.right - frame.width() * mLineRate, frame.bottom - mLineDepth, frame.right, frame.bottom, paint);
            canvas.drawRect(frame.right - mLineDepth, frame.bottom - frame.height() * mLineRate, frame.right, frame.bottom, paint);
    
    
            //=======扫描框为的颜色,灰色遮罩层,删除则无灰色遮罩层
            /*
            int width = canvas.getWidth();
            int height = canvas.getHeight();
            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(CURRENT_POINT_OPACITY);
                canvas.drawBitmap(resultBitmap, null, frame, paint);
            } else {
    
                // ===绘制扫描线
                mScanLinePosition += mScanLineDy;
                if(mScanLinePosition > frame.height()){
                    mScanLinePosition = 0;
                }
                mLinearGradient = new LinearGradient(frame.left, frame.top + mScanLinePosition, frame.right, frame.top + mScanLinePosition, mScanLineColor, mPositions, Shader.TileMode.CLAMP);
                paint.setShader(mLinearGradient);
                canvas.drawRect(frame.left, frame.top + mScanLinePosition, frame.right, frame.top + mScanLinePosition + mScanLineDepth, paint);
                paint.setShader(null);
    
    
    
                final float scaleX = frame.width() / (float) previewFrame.width();
                final float scaleY = frame.height() / (float) previewFrame.height();
    
                final int frameLeft = frame.left;
                final int frameTop = frame.top;
    
                /*去掉扫描区域的闪光点
                if (!lastPossibleResultPoints.isEmpty()) {
                    paint.setAlpha(CURRENT_POINT_OPACITY / 2);
                    paint.setColor(resultPointColor);
                    float radius = POINT_SIZE / 2.0f;
                    for (final ResultPoint point : lastPossibleResultPoints) {
                        canvas.drawCircle(
                                frameLeft + (int) (point.getX() * scaleX),
                                frameTop + (int) (point.getY() * scaleY),
                                radius, paint
                        );
                    }
                    lastPossibleResultPoints.clear();
                }
                */
    
                // draw current possible result points
                if (!possibleResultPoints.isEmpty()) {
                    paint.setAlpha(CURRENT_POINT_OPACITY);
                    paint.setColor(resultPointColor);
                    for (final ResultPoint point : possibleResultPoints) {
                        canvas.drawCircle(
                                frameLeft + (int) (point.getX() * scaleX),
                                frameTop + (int) (point.getY() * scaleY),
                                POINT_SIZE, paint
                        );
                    }
    
                    // swap and clear buffers
                    final List<ResultPoint> temp = possibleResultPoints;
                    possibleResultPoints = lastPossibleResultPoints;
                    lastPossibleResultPoints = temp;
                    possibleResultPoints.clear();
                }
    
                // Request another update at the animation interval, but only repaint the laser line,
                // not the entire viewfinder mask.
                postInvalidateDelayed(ANIMATION_DELAY,
                        frame.left - POINT_SIZE,
                        frame.top - POINT_SIZE,
                        frame.right + POINT_SIZE,
                        frame.bottom + POINT_SIZE);
            }
        }
    
    }
    

    2.content_scan.xml的代码为:

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!--
        layout_width、layout_height:启动扫描界面的布局参数
    
        zxing_framing_rect_width、zxing_framing_rect_height:
        在扫描界面中,只能扫描二维码的宽高,去掉后会有默认的宽高
        -->
        <com.journeyapps.barcodescanner.BarcodeView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_barcode_surface" />
    
        <!--使用的是自定义的扫描活动-->
        <com.gx.test.widget.ScanWidget
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_viewfinder_view" />
    
    </merge>
    

    自定义扫描界面:改进版,仿微信扫描条**

    扫描条是图片,利用动画实现扫描条活动,第二种的扫描条是绘制的线,调快移动距离的话会感觉一卡一卡的,效果不好。
    国际惯例,先上图:因虚拟机录制,看着扫描条一卡一卡的,实际用手机调试,是像微信的扫码条那样流畅的
    在这里插入图片描述

    ps:如果想从上到下扫描后再下往上,下面的Step 4步骤里的设置自己的扫描条的动画解释里有写怎样设置。

    在这里插入图片描述

    Step 1 :引入依赖:

        //第三方zxing
        implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    

    Step 2 :申请权限:

        <!--相机-->
        <uses-permission android:name="android.permission.CAMERA"/>
        <!--若需要闪光灯权限 ,请加入此权限(自测不需要)-->
    <!--
        <uses-permission android:name="android.permission.FLASHLIGHT" />
    -->
    

    Step 3 :自定义 MyApplication

    public class MyApplication extends Application {
        
        private View view;
    
        public View getView() {
            return view;
        }
    
        public void setView(View view) {
            this.view = view;
        }
    }
    

    并在AndroidManifest.xml配置好

        <application
            android:name=".MyApplication"
    

    Step 4 :ScanWidget 自定义扫描活动界面:

    //  Step 1 :继承  ViewfinderView 并 加控制器
    public class ScanWidget extends ViewfinderView {
    
    
        //边角线厚度
        public float mLineDepth =  TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());
    
        //边角线长度/扫描边框长度"的占比 (比例越大,线越长)
        public float mLineRate = 0.1F;
    
    
        public ScanWidget(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        //  Step 2 : 重写此方法:在此方法删除原来的扫描条等等样式,并加入自己的扫描样式
        @Override
        public void onDraw(Canvas canvas) {
    
            refreshSizes();
            if (framingRect == null || previewFramingRect == null) {
                return;
            }
    
            final Rect frame = framingRect;
            final Rect previewFrame = previewFramingRect;
    
            final int width = canvas.getWidth();
            final int height = canvas.getHeight();
    
    
            //====================自己加入的扫描条动画在此处(扫描条其实是View控件放了个背景,view加入动画就实现了扫描条运动)↓
            //ps:若是启用下面代码(带有 PS 的注释那段,请看其作用),请在全局定义boolean b=false,然后例:
            //if(!b){这里写这段自己加入的动画代码; b=true;}  否则出现扫描条不运动,也不会因下面那PS提示的代码让这段代码反复执行。
    
            //=====加入扫描条
            MyApplication myApplication= (MyApplication) this.getContext().getApplicationContext();
    
            //设置扫描条的参数
            View view=myApplication.getView();
            FrameLayout.LayoutParams params= (FrameLayout.LayoutParams) view.getLayoutParams();
            params.width=frame.right-frame.left;//这是计算扫描框的宽度,进而设置扫描条的宽度
            params.setMargins(frame.left,0,0,0);//设置左边距,让扫描条在横方向在扫描框里
            view.setLayoutParams(params);
    
            //=========第一种:设置扫描条的动画 ,仿微信,从同到尾循环扫,并且块到尾时逐渐变完全透明
            AnimationSet set=new AnimationSet(true);
    
            //参数 3:运动开始的地方:frame.top是扫描框离屏幕顶部的距离,减70是因为 这个扫描条 的高是 70 px,
            // 参数3的单位也是px,所以运动开始的地方就是 frame.top-70;参数4作用同3
            Animation trans=new TranslateAnimation(0, 0, frame.top-70, frame.bottom-70);
            trans.setDuration(2000);
            trans.setRepeatMode(Animation.RESTART);
            trans.setRepeatCount(Animation.INFINITE);
            set.addAnimation(trans);
    
            //==这段就是接近尾部后加入的透明,不需要可删除
            Animation alpha=new AlphaAnimation(1,0);
            //注意 1500+500是等于time的 ,因为在移动动画执行3分之2后才执行透明的
            alpha.setStartOffset(1500);
            alpha.setDuration(500);
            alpha.setRepeatMode(Animation.RESTART);
            alpha.setRepeatCount(Animation.INFINITE);
            alpha.setFillAfter(false);
            set.addAnimation(alpha);
    
            //添加动画
            view.startAnimation(set);
    
            //=========第二种:设置扫描条的动画,从上扫到下后又从下往上,如此循环的
    /*        Animation animation = new TranslateAnimation(0, 0, frame.top-70, frame.bottom-70);
            animation.setRepeatMode(Animation.REVERSE);
            animation.setRepeatCount(Animation.INFINITE);
            animation.setDuration(2000);
            view.startAnimation(animation);*/
            
            //清除内存
            myApplication.setView(null);
    
            //=====为矩形扫描区域四个角加上边框  根据情况可以去掉该段代码,像微信扫码了
            paint.setColor(Color.GREEN); // 定义四个角画笔的颜色(本身整个扫描界面都为此颜色,通过设置四个角距离而被覆盖,进而形成四个角)
            //左上角
            canvas.drawRect(frame.left, frame.top, frame.left + frame.width() * mLineRate, frame.top + mLineDepth, paint);
            canvas.drawRect(frame.left, frame.top, frame.left + mLineDepth, frame.top + frame.height() * mLineRate, paint);
    
            //右上角
            canvas.drawRect(frame.right - frame.width() * mLineRate, frame.top, frame.right, frame.top + mLineDepth, paint);
            canvas.drawRect(frame.right - mLineDepth, frame.top, frame.right, frame.top + frame.height() * mLineRate, paint);
    
            //左下角
            canvas.drawRect(frame.left, frame.bottom - mLineDepth, frame.left + frame.width() * mLineRate, frame.bottom, paint);
            canvas.drawRect(frame.left, frame.bottom - frame.height() * mLineRate, frame.left + mLineDepth, frame.bottom, paint);
    
            //右下角
            canvas.drawRect(frame.right - frame.width() * mLineRate, frame.bottom - mLineDepth, frame.right, frame.bottom, paint);
            canvas.drawRect(frame.right - mLineDepth, frame.bottom - frame.height() * mLineRate, frame.right, frame.bottom, paint);
    
            //============================自己加入动画↑=========================
    
    
            // 灰色遮罩层  可以去掉
            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);
    
    /*
    
            //===========PS:以下方法,不断执行onDraw方法绘制扫描线等样式进而产生自带的扫描线和闪光点,
            // 若是扫描到了,就会把结果图绘制在矩形框上,根据情况选择是否注释以下代码或部分动画代码
    
            if (resultBitmap != null) {
                //扫描到后在矩形上绘制不透明的图
                // Draw the opaque result bitmap over the scanning rectangle
                paint.setAlpha(CURRENT_POINT_OPACITY);
                canvas.drawBitmap(resultBitmap, null, frame, paint);
            } else {
    
                //自带的红色扫描线
                // 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;
                final int middle = frame.height() / 2 + frame.top;
                canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
    
                final float scaleX = frame.width() / (float) previewFrame.width();
                final float scaleY = frame.height() / (float) previewFrame.height();
    
                final int frameLeft = frame.left;
                final int frameTop = frame.top;
    
                // draw the last possible result points
                if (!lastPossibleResultPoints.isEmpty()) {
                    paint.setAlpha(CURRENT_POINT_OPACITY / 2);
                    paint.setColor(resultPointColor);
                    float radius = POINT_SIZE / 2.0f;
                    for (final ResultPoint point : lastPossibleResultPoints) {
                        canvas.drawCircle(
                                frameLeft + (int) (point.getX() * scaleX),
                                frameTop + (int) (point.getY() * scaleY),
                                radius, paint
                        );
                    }
                    lastPossibleResultPoints.clear();
                }
    
                // draw current possible result points
                if (!possibleResultPoints.isEmpty()) {
                    paint.setAlpha(CURRENT_POINT_OPACITY);
                    paint.setColor(resultPointColor);
                    for (final ResultPoint point : possibleResultPoints) {
                        canvas.drawCircle(
                                frameLeft + (int) (point.getX() * scaleX),
                                frameTop + (int) (point.getY() * scaleY),
                                POINT_SIZE, paint
                        );
                    }
    
                    // swap and clear buffers
                    final List<ResultPoint> temp = possibleResultPoints;
                    possibleResultPoints = lastPossibleResultPoints;
                    lastPossibleResultPoints = temp;
                    possibleResultPoints.clear();
                }
    
                //不断调用执行绘制该活动界面进出现自动的动画
                // Request another update at the animation interval, but only repaint the laser line,
                // not the entire viewfinder mask.
                postInvalidateDelayed(ANIMATION_DELAY,
                        frame.left - POINT_SIZE,
                        frame.top - POINT_SIZE,
                        frame.right + POINT_SIZE,
                        frame.bottom + POINT_SIZE);
            }
    
    */
    
    
    
        }
    
    
    }
    

    Step 5 :准备3个布局:

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始"
            android:id="@+id/button"/>
    
    </LinearLayout>
    

    content_scan.xml 其实这个布局,BarcodeView和ScanWidget相当于不在布局里,所以该布局像只有View控件,进而达到扫描条运动

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!--
        layout_width、layout_height:启动扫描界面的布局参数
    
        zxing_framing_rect_width、zxing_framing_rect_height:
        在扫描界面中,只能扫描二维码的宽高,去掉后会有默认的宽高
        -->
        <com.journeyapps.barcodescanner.BarcodeView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_barcode_surface" />
    
        <!--注意自定义的扫描活动路径-->
        <com.gx.qr.ScanWidget
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/zxing_viewfinder_view"
            app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
            app:zxing_result_view="@color/zxing_custom_result_view"
            app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
            app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
    
        <!--@drawable/bmt 扫描条图标  请自行找素材-->
        <View
            android:id="@+id/scan_the"
            android:background="@drawable/bmt"
            android:layout_width="wrap_content"
            android:layout_height="70px" />
    
    </merge>
    

    activity_scan.xml 其实这个布局,DecoratedBarcodeView相当于不在布局里,所以该布局像只有ImageButton控件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!--装扫描界面的控件
        @layout/content_scan:为嵌入content_scan.xml的布局
        -->
        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/dbv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            app:zxing_scanner_layout="@layout/content_scan">
        </com.journeyapps.barcodescanner.DecoratedBarcodeView>
    
        <!--闪光灯图片 自行找图片样式
            @drawable/ic_flashlight_close 关闭时的图片
        -->
        <ImageButton
            android:id="@+id/ib_flashlight_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="60dp"
            android:background="@drawable/ic_flashlight_close"/>
    </RelativeLayout>
    

    Step 6 :ScanActivity

    public class ScanActivity extends AppCompatActivity {
        private CaptureManager capture;
        private ImageButton ibFlashlight;
        private DecoratedBarcodeView barcodeScannerView;
        private boolean bTorch = false;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            //==设置布局、获取控件
            setContentView(R.layout.activity_scan);
            barcodeScannerView = findViewById(R.id.dbv);
            ibFlashlight= findViewById(R.id.ib_flashlight_close);
    
            //==保存扫描条到Application里
            View view = findViewById(R.id.scan_the);
            MyApplication myApplication= (MyApplication) getApplication();
            myApplication.setView(view);
    
            //==监听: 根据barcodeScannerView设置闪光灯ibFlashlight状态
            barcodeScannerView.setTorchListener(new DecoratedBarcodeView.TorchListener() {
                @Override
                public void onTorchOn() {//开灯
    
                    //R.drawable.ic_flashlight_open)  开灯显示的图片 自行找图片样式
                    ibFlashlight.setBackground(getResources().getDrawable(R.drawable.ic_flashlight_open));
                    bTorch = true;
                }
    
                @Override
                public void onTorchOff() {//关灯
    
                    //R.drawable.ic_flashlight_close)  关灯显示的图片 自行找图片样式
                    ibFlashlight.setBackground(getResources().getDrawable(R.drawable.ic_flashlight_close));
                    bTorch = false;
                }
            });
    
            //==开或关灯
            ibFlashlight.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(bTorch){
                        barcodeScannerView.setTorchOff();
                    } else {
                        barcodeScannerView.setTorchOn();
                    }
    
                }
            });
    
            //==初始化活动
            capture = new CaptureManager(this, barcodeScannerView);
    
            capture.initializeFromIntent(getIntent(), savedInstanceState);
    
            capture.decode();
        }
    
    
        @Override
        protected void onResume() {
            super.onResume();
            capture.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            capture.onPause();
            barcodeScannerView.setTorchOff();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            capture.onDestroy();
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            capture.onSaveInstanceState(outState);
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
            capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
        }
    }
    

    Step 7 :MainActivity

    public class MainActivity extends AppCompatActivity {
    
        private Button button;
    
        //  Step 1 : 初始化 获取控件 设置监听
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            button = findViewById(R.id.button);//点击跳转到扫码活动
    
            //控件监听
            listenerView();
        }
    
    
        private void listenerView() {
    
            //  Step 2 :跳转到扫描活动
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    //=======设置扫描活动  可根据需求设置以下内容
                    IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
    
                    //启动自定义的扫描活动,不设置则启动默认的活动
                    intentIntegrator.setCaptureActivity(ScanActivity.class);
    
                    //启动扫描
                    intentIntegrator.initiateScan();
    
                }
            });
    
        }
    
    
        //  Step 3 :处理扫码后返回的结果
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
    
            if(result!=null){
    
                //==是否扫到内容
                if (result.getContents()!=null){
                    Toast.makeText(this,"扫描结果:"+result.getContents(),Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(this,"取消扫码",Toast.LENGTH_LONG).show();
                }
    
            }else{
                super.onActivityResult(requestCode, resultCode, data);
            }
    
        }
    
    
    
    }
    

    所用到的图片:

    ic_flashlight_close.png
    在这里插入图片描述

    ic_flashlight_open.png

    在这里插入图片描述

    bmt.png
    在这里插入图片描述

    OK!打完收工

    展开全文
  • https://mp.csdn.net/postedit/78983090 需要看文章的请点击连接。关于二维码的生成及原理,这篇文章都说的很清楚。有什么问题可以进qq群569614530
  • 其次是扫一扫识别,那么很快联想到的就是常见的二维码扫描这类的项目。通过扫一扫实时拿到图像,来做识别。 接下来在Github上找到了QrCodeScanner项目,作者通过一定的优化,使得识别的效率有所提升。那么我们用它...
  • 主要给大家介绍了关于Android实现扫一扫功能之绘制指定区域透明区域的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • android扫一扫(Zbar)

    2019-01-29 12:30:23
    android应用扫一扫支持二维码,条形码,识别速度非常快,亲自测试后在项目中使用
  • Android扫一扫类库

    2016-04-26 11:46:50
    Android扫一扫类库,是在ZXing源码中提出出来的,适用于Android的扫描的编码与解码。
  • 在实现扫一扫的功能的时候,我们需要绘制一个中间为透明的扫码框,其余部分为半透明。通常情况下,例如微信或者支付宝的扫码框都是矩形的,如果中间的扫码框是一个矩形,那么布局是很简单的,可是如果扫码框是一个...

    一、概述
    在实现扫一扫的功能的时候,我们需要绘制一个中间为透明的扫码框,其余部分为半透明。通常情况下,例如微信或者支付宝的扫码框都是矩形的,如果中间的扫码框是一个矩形,那么布局是很简单的,可是如果扫码框是一个圆角矩形,或者圆形等情况怎么办呢?这篇文章主要是记录绘制一个中间透明带圆角的矩形。

    按照惯例,我们先来看看效果图 :

    二、按照流程我们就开始来看看代码啦
    1、CustomDrawable,支持中间出现透明区域的drawable

    package per.juan.scandome;
    
    import android.graphics.Canvas;
    import android.graphics.ColorFilter;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.drawable.Drawable;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    
    /**
     * 支持中间出现透明区域的drawable
     * 通过{@link #setSrcPath(Path)}设定透明区域的形状
     * Created by juan on 2018/07/20.
     */
    public class CustomDrawable extends Drawable {
        private Paint srcPaint;
        private Path srcPath = new Path();
    
        private Drawable innerDrawable;
    
    
        public CustomDrawable(Drawable innerDrawable) {
            this.innerDrawable = innerDrawable;
            srcPath.addRect(100, 100, 200, 200, Path.Direction.CW);
            srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            srcPaint.setColor(0xffffffff);
        }
    
        /**
         * 设置内部透明的部分
         *
         * @param srcPath
         */
        public void setSrcPath(Path srcPath) {
            this.srcPath = srcPath;
        }
    
        @Override
        public void draw(@NonNull Canvas canvas) {
            innerDrawable.setBounds(getBounds());
            if (srcPath == null || srcPath.isEmpty()) {
                innerDrawable.draw(canvas);
            } else {
                //将绘制操作保存到新的图层,因为图像合成是很昂贵的操作,将用到硬件加速,这里将图像合成的处理放到离屏缓存中进行
                int saveCount = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), srcPaint, Canvas.ALL_SAVE_FLAG);
    
                //dst 绘制目标图
                innerDrawable.draw(canvas);
    
                //设置混合模式
                srcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                //src 绘制源图
                canvas.drawPath(srcPath, srcPaint);
                //清除混合模式
                srcPaint.setXfermode(null);
                //还原画布
                canvas.restoreToCount(saveCount);
            }
        }
    
        @Override
        public void setAlpha(int alpha) {
            innerDrawable.setAlpha(alpha);
        }
    
        @Override
        public void setColorFilter(@Nullable ColorFilter colorFilter) {
            innerDrawable.setColorFilter(colorFilter);
        }
    
        @Override
        public int getOpacity() {
            return innerDrawable.getOpacity();
        }
    }

    (1)主要用到的技术是PorterDuffXfermode的PorterDuff.Mode.XOR模式
    (2)核心思想是先正常绘制出整个drawable,然后将指定的区域混合成透明色

    2、CustomLayout

    package per.juan.scandome;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Path;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.FrameLayout;
    
    /**
     * 根据layout中子View的位置,确定局部透明区域
     * Created by juan on 2018/07/20.
     */
    public class CustomLayout extends FrameLayout {
    
        private Context mContext;
        private CustomDrawable background;
    
        public CustomLayout(@NonNull Context context) {
            super(context);
            initView(context, null, 0);
        }
    
        public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.mContext=context;
            initView(context, attrs, 0);
        }
    
        public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(context, attrs, defStyleAttr);
        }
    
        @SuppressLint("NewApi")
        private void initView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            background = new CustomDrawable(getBackground());
            setBackground(background);
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            resetBackgroundHoleArea();
        }
    
        @SuppressLint("NewApi")
        private void resetBackgroundHoleArea() {
            Path path = null;
            // 以子View为范围构造需要透明显示的区域
            View view = findViewById(R.id.iv_scan);
            if (view != null) {
                path = new Path();
                // 矩形透明区域
                path.addRoundRect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), dp2Px(mContext,10), dp2Px(mContext,10),Path.Direction.CW);
            }
            if (path != null) {
                background.setSrcPath(path);
            }
        }
    
        public int dp2Px(Context context, float dp) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dp * scale + 0.5f);
        }
    }
    

    3、然后在XML布局中声明我们的自定义View

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:id="@+id/frame_layout"
        android:layout_height="match_parent">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@mipmap/bg_image" />
    
        <per.juan.scandome.CustomLayout
            android:layout_width="match_parent"
            android:id="@+id/layout"
            android:background="#8c565658"
            android:layout_height="match_parent">
    
            <!-- 根据这个子View所在的位置,计算出透明矩形的位置 -->
            <FrameLayout
                android:id="@+id/iv_scan"
                android:layout_width="200dp"
                android引用块内容center" />
    
        </per.juan.scandome.CustomLayout>
    </FrameLayout>

    好了,本篇文章就这样了,存在不足的地方还望指导,感谢^_^

    附录:
    自定义Drawable之:在Drawable中部指定透明区域

    展开全文
  • 用Zbar库实现的Android扫一扫 集成: 下载打开源码项目,大佬可以先运行看下效果,如果需集成,就使用箭头得扫一扫Module 大佬进入自己的Android studio项目,直接点击File->New->Import Module 选择Demo文件导入即可. ...
  • 主要参考http://blog.csdn.net/yuzhiqiang_1993/article/details/52805057这篇文章,自己实现扫一扫功能过程的一个总结。

    开发安卓app过程中需要集成扫码功能,搜索的时候发现了

    http://blog.csdn.net/yuzhiqiang_1993/article/details/52805057

    这篇博客文章,写的很清楚了,因为我是新手,实现过程中还是出现了一些问题,所以记录下来


    一、资源下载

    直接从上面链接博主的github里面把整个工程下载下来,地址(https://github.com/yuzhiqiang1993/zxing)顺手给个star吧


    主要用到的是上图红框中的zxinglibrary文件夹


    二、资源配置

    因为我使用android studio进行开发的,一下处理是否试用于eclipse我也没试过。

    1.将zxinglibrary文件夹作为module加入你原有的工程中


    2.在弹出界面中选择Import Gradle Project→Next


    3.选择zxinglibrary文件夹的位置,finish。


    4.选择project structure


    5.dependencies中点击加号,选择选择刚刚引入的zxinglibrary


    6.点击OK

    以上,资源配置就完事了。


    三、调用功能实现

    1.相机权限取得

    现在这个时间点开发应该都在6.0以上了,所以相机权限应该是必须的,在你的工程AndroidManifest.xml文件中添加以下代码

    <uses-permission android:name="android.permission.CAMERA"/>
    2.活动定义,依然在你的AndroidManifest.xml文件中添加以下代码
            <!-- 扫一扫实现 -->
            <activity
                android:name="com.yzq.zxinglibrary.android.CaptureActivity"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.NoTitleBar"
                android:windowSoftInputMode="adjustPan|stateHidden">
            </activity>
    3.调用例子如下(我实现的是按钮调用)

            // 扫一扫按钮点击事件
            Button  saoyisao = (Button) findViewById(R.id.saoyisao);
            saoyisao.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 取得相机权限
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        requestPermissions(new String[]{Manifest.permission.CAMERA}, PHOTO_REQUEST_SAOYISAO);
                    }else{
                        // 权限已经取得的情况下调用
                        // 调用扫一扫
                        Intent intent = new Intent(FirstActivity.this,
                                CaptureActivity.class);
                        startActivityForResult(intent, REQUEST_CODE_SCAN);
                    }
                }
            });

        /**
         * 重写申请权限操作返回值的方法
         **/
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            switch (requestCode){
                case PHOTO_REQUEST_SAOYISAO:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                        // 权限申请成功,扫一扫
                        Intent intent = new Intent(FirstActivity.this,
                                CaptureActivity.class);
                        startActivityForResult(intent, REQUEST_CODE_SCAN);
                    }else{
                        Toast.makeText(this, "无相机调用权限,扫一扫功能无法使用,", Toast.LENGTH_SHORT).show();
                    }
            }
        }

        /**
         * 重写取得活动返回值的方法
         **/
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
            switch (requestCode){
                // 扫一扫返回值
                case REQUEST_CODE_SCAN:
                    if(resultCode == RESULT_OK){
                        String content = intent.getStringExtra(Consants.CODED_CONTENT);
                        Log.d(TAG, "扫一扫返回成功!扫码结果为:"+content);
                    }
                    break;
                default:
            }
        }

    以上代码中的
    REQUEST_CODE_SCAN
    PHOTO_REQUEST_SAOYISAO
    
    

    
    

    是我自己设定的int常量


    大概就是这样实现的了,有问题请留言。



    展开全文
  • Android 扫一扫功能实现(Zbar)

    千次阅读 2017-10-19 17:38:40
    1.实现扫一扫功能需要用到解码库,才能识别出二维码信息,  下面提供两个开源库地址:  ZBar:https://github.com/ZBar/ZBar  Zxing:https://github.com/zxing/zxing 2.熟悉Android自定义Camera相关知识 ...

    1.实现扫一扫功能需要用到解码库,才能识别出二维码信息, 
    下面提供两个开源库地址: 
    ZBar:https://github.com/ZBar/ZBar 
    Zxing:https://github.com/zxing/zxing

    2.熟悉Android自定义Camera相关知识


    然而,当我们打开上述的两个库后,可能发现并没什么卵用. 

    因为官方的两个库,里面包含的东西实在太多的,而我们仅仅需要Android中的小部分. 
    怎么办捏,不用担心,上面的链接其实只是我用来装逼的,这样才显得我的逼格高. 
    在我们之前已经有很多人为前辈做过扫一扫功能,所以分享了很多相应的jar包,SO文件,我们只要拿过来用就行了.

    本文用的是Zbar实现扫一扫,因为根据本人对两个库的使用比较,发现Zbar解码比Zxing速度要快,实现方式也简单

    • 集成:

    打开源码项目,找到里面的箭头扫一扫Module

    这里写图片描述

    进入大佬自己的Android studio项目,直接点击File->New->Import Module 选择Demo文件导入即可. 
    记得在App 的gradle添加依赖. compile project(':zbarcode')

    这里写图片描述


    使用代码

    进入扫一扫

    Intent intent1 = new Intent(MainActivity.this, CaptureActivity.class);
            startActivityForResult(intent1, QR_CODE);
     
    • 1
    • 2

    获取返回的结果

    
    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == QR_CODE) {
                Bundle b=data.getExtras();
                String result = b.getString(CaptureActivity.EXTRA_STRING);
                Toast.makeText(this, result + "", Toast.LENGTH_SHORT).show();
            }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注: 请根据大佬自己项目的需求,配置右边SO库架构,对应删掉左边多余的文件夹

    这里写图片描述

    源码分析

    ZbarCode结构

    这里写图片描述

    CaptureActivity:为扫一扫界面的Activity; 
    AutoFocusManager:相机自动聚焦管理类 
    CameraConfigurationManager:相机参数信息的操作类 
    CameraManager:为自定义相机操作的封装,管理相机的打开,取景,参数,回收处理. 
    PreviewCallback:图像数据回调处理; 
    PreviewCallback:主线程Handler; 
    DecodeThread:解码子线程; 
    DecodeHandler:子线程Handler; 
    BeepManager:扫码操作滴的声音处理;

    流程:

    扫一扫大致流程如下序列图:

    CaptureActivityCaptureActivitySurfaceViewSurfaceViewCameraManagerCameraManagerZbar库Zbar库出始化SurfaceView初始化完毕打开摄像头判断是否可以开启相机已开启传递SurfaceHoler开起预览开启预览获取摄像头参数开启自动聚焦Callback回调图像数据开启子线程传递相机参数和相机图像数据在子线程成解码把解码状态还回成功,得到结果失败,重新回调图像数据,进行解码


    展开全文
  • 扫描二维码功能 样式仿照微信扫一扫功能 (可以自定义扫描框大小,以及滚动扫描线的长度以及宽度)
  • cordova android 扫一扫

    2015-09-09 15:39:07
    cordova 配置插件很是麻烦,整了个scan demo ,html 端逻辑在index.js 里面写的 ,android 端逻辑,好懂
  • 该应用是经典的扫一扫源码,下载下载即可集成到项目中使用。
  • Android 扫一扫功能实现 (集成ZXing)

    千次阅读 2017-06-02 13:38:05
    3.跳转扫一扫Activity并添加回调 Intent intent = new Intent(MainActivity. this, CaptureActivity. class ) ; startActivityForResult(intent , REQUEST_CODE_SCAN) ; protected void ...
  • 通过开源框架zxing实现安卓项目中二维码扫描识别及生成二维码图片功能。
  • 目录前言官网的Demo和Sample代码体验1 开发准备1.1 android studio 安装1.2 在项目级gradle里添加华为maven仓1.3 在应用级的build.gradle里面加上SDK依赖1.4 加一下混淆配置1.5 Manifest申请静态权限和码页面声明...
  • zxing 实现二维码扫描 从相册获取二维码识别,部分机型有存储权限需自己做一下处理,闪光灯,以及集成了zxing的库,可自己直接引用生成等操作,
  • Android扫一扫Zxing之基础依赖,Zxing基础依赖。可快速实现,但是是横屏。后期文章会编写自定义Zxing扫一扫
  • Android扫一扫

    2016-07-26 20:21:54
    各种Android扫码问题解决方法
  • Android使用Zxing实现扫一扫功能,开发工具Android studio
  • 公司业务需求,需要做手机号码的识别。所以有了此DEMO,现在就将实现过程分享给大家。
  • 主要介绍了超简单Android集成华为HMS Scankit 扫码SDK实现扫一扫二维码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 好了,实现一个基本的扫一扫就是如此的简单 生成二维码 如果你有生成二维码的需求,可以直接通过**CodeCreator.createQRCode(contentEtString, 400, 400, null);**即可。  try {  /*  * ...
  • 超简单集成Android Zxing实现扫一扫二维码

    万次阅读 多人点赞 2016-10-13 10:54:35
    下面,我们将zxing集成到Android studio来实现扫一扫功能。 首先,zxing的github地址: zxing—github 集成步骤: 1.首先新建工程,将targetSdkVersion改为22或22以下,因为扫描的时候需要调相机,6.0的话涉及...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,074
精华内容 11,629
关键字:

android扫一扫