ZxingDemo

ZxingDemo

更新日志

  • compile 1.0 2019/04/12 首次构建

使用说明

  • 可打开默认二维码扫描页面

  • 支持对图片Bitmap的扫描功能

  • 支持对UI的定制化操作

  • 支持对条形码的扫描功能

  • 支持生成二维码操作

  • 支持控制闪光灯开关

使用方式:

  • 集成默认的二维码扫描页面

在具体介绍该扫描库之前我们先看一下其具体的使用方式,看看是不是几行代码就可以集成二维码扫描的功能。

  • 在module的build.gradle中执行compile操作
 implementation 'com.zxn.zxing:CustomUIZxing:1.0.3'
  • 在demo Application中执行初始化操作
@Override
public void onCreate() {
    super.onCreate();
    ZXingLibrary.initDisplayOpinion(this);
}
  • 在代码中执行打开扫描二维码界面操作
/**
 * 打开默认二维码扫描界面
 */
button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
        startActivityForResult(intent, REQUEST_CODE);
    }
});

这里的REQUEST_CODE是我们定义的int型常量。

  • 在Activity的onActivityResult方法中接收扫描结果
/**
 * 处理二维码扫描结果
 */
if (requestCode == REQUEST_CODE) {
    //处理扫描结果(在界面上显示)
    if (null != data) {
        Bundle bundle = data.getExtras();
        if (bundle == null) {
            return;
        }
        if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
            String result = bundle.getString(CodeUtils.RESULT_STRING);
            Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
        } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
            Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
        }
    }
}

怎么样是不是很简单?下面我们可以来看一下具体的执行效果:

执行效果:

[图片上传失败...(image-482055-1560843225234)]%2015.33.08.gif)

但是这样的话是不是太简单了,如果我想选择图片解析呢?别急,对二维码图片的解析也是支持的

  • 集成对二维码图片的解析功能

  • 调用系统API打开图库

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
  • 在Activity的onActivityResult方法中获取用户选中的图片并调用二维码图片解析API
if (requestCode == REQUEST_IMAGE) {
    if (data != null) {
        Uri uri = data.getData();
        ContentResolver cr = getContentResolver();
        try {
            Bitmap mBitmap = MediaStore.Images.Media.getBitmap(cr, uri);//显得到bitmap图片

            CodeUtils.analyzeBitmap(mBitmap, new CodeUtils.AnalyzeCallback() {
                @Override
                public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
                    Toast.makeText(MainActivity.this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                }

                @Override
                public void onAnalyzeFailed() {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            });

            if (mBitmap != null) {
                mBitmap.recycle();
            }
        } catch (Exception e) {
            e.printStackTrace();
    }
}

执行效果

[图片上传失败...(image-e015df-1560843225234)]

有了默认的二维码扫描界面,也有了对二维码图片的解析,可能有的同学会说如果我想定制化显示UI怎么办呢?没关系也支持滴。

  • 定制化显示扫描UI

由于我们的扫描组件是通过Fragment实现的,所以能够很轻松的实现扫描UI的定制化。

  • 在新的Activity中定义Layout布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_second"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/second_button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:layout_gravity="bottom|center_horizontal"
        />

    <FrameLayout
        android:id="@+id/fl_my_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></FrameLayout>

</FrameLayout>

启动id为fl_my_container的FrameLayout就是我们需要替换的扫描组件,也就是说我们会将我们定义的扫描Fragment替换到id为fl_my_container的FrameLayout的位置。而上面的button是我们添加的一个额外的控件,在这里你可以添加任意的控件,各种UI效果等。具体可以看下面在Activity的初始化过程。

  • 在Activity中执行Fragment的初始化操作
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    CodeUtils.addCaptureFragment(getSupportFragmentManager(), R.id.fl_my_container, R.layout.my_custom_camera, analyzeCallback);
}

其中analyzeCallback是我们定义的扫描回调函数,其具体的定义:

/**
     * 二维码解析回调函数
     */
    CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
        @Override
        public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
            bundle.putString(CodeUtils.RESULT_STRING, result);
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }

        @Override
        public void onAnalyzeFailed() {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
            bundle.putString(CodeUtils.RESULT_STRING, "");
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }
    };

仔细看的话,你会发现我们调用了CondeUtils.setFragmentArgs方法,该方法主要用于修改扫描界面扫描框与透明框相对位置的,与若不调用的话,其会显示默认的组件效果,而如果调用该方法的话,可以修改扫描框与透明框的相对位置等UI效果,我们可以看一下my_camera布局文件的实现。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <com.uuzuche.lib_zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:inner_width="200dp"
        app:inner_height="200dp"
        app:inner_margintop="150dp"
        app:inner_corner_color="@color/scan_corner_color"
        app:inner_corner_length="30dp"
        app:inner_corner_width="5dp"
        app:inner_scan_bitmap="@drawable/scan_image"
        app:inner_scan_speed="10"
        app:inner_scan_iscircle="false"
        />

</FrameLayout>

上面我们自定义的扫描控件的布局文件,下面我们看一下默认的扫描控件的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/result_view" />


    <com.zxn.zxing.view.ScanViewfinder
        android:id="@+id/sv_viewfinder"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="150dp"
        android:background="@drawable/capture"
        android:contentDescription="@string/app_name"
        app:scanBitmap="@drawable/scan_line"
        app:scanSpeed="12" />

    <TextView
        android:id="@+id/tv_sacn_notice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/sv_viewfinder"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="593066063"
        android:textColor="#ffffff"
        android:visibility="visible" />


</RelativeLayout>

可以发现其主要的区别就是在自定义的扫描控件中多了几个自定义的扫描框属性:

<declare-styleable name="ScanViewfinder">
    <attr name="scanBackground" format="reference" />
    <attr name="scanBitmap" format="reference" />
    <attr name="scanSpeed" format="integer" />
</declare-styleable>

代码中动态修改显示我们的扫描UI:

    FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks = new FragmentManager.FragmentLifecycleCallbacks() {

        @Override
        public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable Bundle savedInstanceState) {
            super.onFragmentViewCreated(fm, f, v, savedInstanceState);
            TextView textView = v.findViewById(R.id.tv_sacn_notice);
            textView.setText("593066063---------");
        }

    };

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    getSupportFragmentManager().registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks,true);
}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
    }


通过以上几个属性我们就可以定制化的显示我们的扫描UI了,比如定制化微信扫描UI:

执行效果

[图片上传失败...(image-6fee1f-1560843225234)]%2015.33.08.gif)

当然了如果以上的以上,你还是对定制化UI方面不太满意,可以直接下载我的项目,然后引入lib-zxing module作为你的module,直接修改其代码。

  • 生成二维码图片

  • 生成带Logo的二维码图片:

/**
 * 生成二维码图片
 */
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String textContent = editText.getText().toString();
        if (TextUtils.isEmpty(textContent)) {
            Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        editText.setText("");
        mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        imageView.setImageBitmap(mBitmap);
    }
});
  • 生成不带logo的二维码图片
/**
 * 生成不带logo的二维码图片
 */
button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        String textContent = editText.getText().toString();
        if (TextUtils.isEmpty(textContent)) {
            Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        editText.setText("");
        mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
        imageView.setImageBitmap(mBitmap);
    }
});
  • 生成一维码效果:
/**
 * 绘制条形码
 *
 * @param content       要生成条形码包含的内容
 * @param widthPix      条形码的宽度
 * @param heightPix     条形码的高度
 * @param isShowContent 否则显示条形码包含的内容
 * @return 返回生成条形的位图
 */
public static Bitmap createBarcode(String content, int widthPix, int heightPix, boolean isShowContent){}
  • 执行效果

[图片上传失败...(image-9a9d6e-1560843225234)].gif)

  • 支持控制闪光灯
/**
 * 打开闪光灯
 */
CodeUtils.isLightEnable(true);

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