精华内容
下载资源
问答
  • Android扫一扫

    2016-07-26 20:21:54
    各种Android扫码问题解决方法
    展开全文
  • Android扫一扫获取结果

    2018-08-08 11:41:30
    Android扫一扫二维码,获取二维码结果代码,解压可直接使用。
  • androidstudio实现数据库查询excel,通过扫一扫功能查询,适合学习扫一扫功能的android开发人员,关于excel查询,我是通过将excel导入到sqlite,然后通过数据库查询,将内容显示出来。内含有完整的androidstudio源码...
  • Android扫一扫Zxing之基础依赖,Zxing基础依赖。可快速实现,但是是横屏。后期文章会编写自定义Zxing扫一扫

    Android扫一扫Zxing

    这个是最基础的Zxing的依赖扫一扫,Zxing设置的扫描是横屏,之后的文章会写篇自定义的Zxing扫一扫

    一、在根目录的build.gradle中添加依赖

    allprojects {
        repositories {
            jcenter()
            maven{ url "http://dl.bintray.com/journeyapps/maven" }
        }
    }

    二、在主项目的build.gradle中添加依赖,并同步gradle

    compile 'com.google.zxing:core:3.0.1'
    compile 'com.journeyapps:zxing-android-embedded:2.0.1@aar'
    compile 'com.journeyapps:zxing-android-legacy:2.0.1@aar'
    compile 'com.journeyapps:zxing-android-integration:2.0.1@aar'

    三、在清单文件中添加权限

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

    注:"android.permission.CAMERA"Android6.0以上系统中要手动获取参考:Android6.0以上系统获取权限

    四、跳转到扫描界面

    //跳转到扫描界面
    IntentIntegrator intentIntegrator = new IntentIntegrator(MainActivity.this);
    intentIntegrator.initiateScan();

    五、重写回调,解码扫描结果

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if (scanResult != null) {
            String result = scanResult.getContents();
            Log.e("LKing","扫描结果:"+result);
        }
    }

     

    展开全文
  • 在实现扫一扫的功能的时候,我们需要绘制一个中间为透明的扫码框,其余部分为半透明。通常情况下,例如微信或者支付宝的扫码框都是矩形的,如果中间的扫码框是一个矩形,那么布局是很简单的,可是如果扫码框是一个...

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

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

    二、按照流程我们就开始来看看代码啦
    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中部指定透明区域

    展开全文
  • 第三方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!打完收工

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

    万次阅读 热门讨论 2016-11-27 01:26:37
    1.一本正经的简介:如果你觉得快乐,你就扫一扫. 如果你觉得快乐,你就扫一扫. 如果你觉得快乐,你就扫一扫. 早上买豆浆油条可以扫一扫,中午吃湘菜可以扫一扫,街边卖水果的大妈支持扫一扫. 如果你现在还不知道什么是...
  • Android扫一扫(Zxing),闪光灯,生成二维码图片,解析二维码(条码)等 原创 2017年10月20日 09:42:01 标签:

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,904
精华内容 761
关键字:

android扫一扫