菜鸟的自己今天又回顾了一下二维码的实现

这是老大给我的第二个任务,让我研究一下二维码的功能,菜鸟的自己半天实现了扫描和生成二维码的功能,记下来吧。

 首先还是在gitHub小伙伴的帮助下完成的,非常感谢,希望gitHub多出点这样的精华

  1.去gitHub上下载库,链接(https://github.com/XuDaojie/QRCode-Android)

  2.将该demo中的qrcodelib作为module导入到你的项目,修改你的build.gradle配置,分别添加如下代码:

compile 'com.github.XuDaojie:QRCode-Android:v0.4.2'

和marven;

repositories {
    maven { url "http://repo1.maven.org/maven2" }
    maven { url 'https://jitpack.io' }
}
有了这些你的准备工作就完事了,让你的工程依赖你所导入的jar包
接下来开始准备代码部分:
   
<LinearLayout    
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="10dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="2dp"
android:gravity="center"
android:orientation="vertical"
tools:context="com.dmdfchina.view.ZxingActivity">
 
 
<Button
        android:id="@+id/btn_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:text="扫描" />
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textColor="@android:color/holo_blue_bright"
        android:text="ss"
        android:textSize="18sp" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="请输入你想输入的内容"
        android:id="@+id/btn_hint1"
        android:layout_alignTop="@+id/btn_switch"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="生成二维码"
        android:id="@+id/btn_hint2"
        android:layout_alignTop="@+id/btn_hint1"
        android:layout_alignParentEnd="true" />

    <ImageView
        android:id="@+id/img_shouw"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:background="@mipmap/ic_launcher"
        android:layout_height="wrap_content"/>


</LinearLayout>


核心代码部分:
	
public class ZxingActivity extends AppCompatActivity implements View.OnClickListener {
    private static final int REQUEST_OK=1001;
    private Button scan, generate;
    private EditText content;
    private ImageView mShowImg;
    private TextView mQRCodeResult;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_zxing);
        initViewById();
    }

    private void initViewById() {
        scan = (Button) findViewById(R.id.btn_switch);
        content = (EditText) findViewById(R.id.btn_hint1);
        generate = (Button) findViewById(R.id.btn_hint2);
        mShowImg= (ImageView) findViewById(R.id.img_shouw);
        mQRCodeResult= (TextView) findViewById(R.id.tv_result);

        scan.setOnClickListener(this);
        generate.setOnClickListener(this);
    }

    //扫描成功后震动
    private void vibrate() {
        Vibrator mVibrator= (Vibrator) getSystemService(VIBRATOR_SERVICE);
        mVibrator.vibrate(200);

    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //打开框扫描
            case R.id.btn_switch:
                changeLight();
                startActivityForResult(new Intent(ZxingActivity.this,
                        SimpleCaptureActivity.class), 0);
                break;
            //生成二维码
            case R.id.btn_hint2:
                Handler mHandler=new Handler();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        create();
                    }
                });

                break;
            default:
                break;
        }
    }
//打开扫描框需要回掉的方法
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==REQUEST_OK){
            Bundle bundle=data.getExtras();
            if (bundle!=null){
                String result=bundle.getString("result");
                mQRCodeResult.setText(result);
            }
        }
    }
    //扫描时提高屏幕的亮度
    public void changeLight(){
        WindowManager.LayoutParams lp=getWindow().getAttributes();
        lp.screenBrightness=1.0f;
        getWindow().setAttributes(lp);
    }


    private void create() {
        int width = DensityUtils.dip2px(this, 200);
        String writeContent=content.getText().toString();
        if (writeContent!=null) {
            Bitmap bitmap = EncodingUtils.createQRCode(writeContent,
                    width, width, BitmapFactory.decodeResource(getResources(),
                            R.mipmap.ic_launcher));
            mShowImg.setImageBitmap(bitmap);
            saveBitmap(bitmap);
        }else{
            Toast.makeText(ZxingActivity.this,"请输入你要生成二维码的文本",Toast.LENGTH_LONG).show();
        }
    }

    /**
     * Bitmap保存在本地
     */
    public void saveBitmap(Bitmap bitmap) {
        // 首先保存图片
        File appDir = new File(Environment.getExternalStorageDirectory(),
                "zxing_image");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = "zxing_image" + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(this.getContentResolver(),
                    file.getAbsolutePath(), fileName, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 通知图库更新
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.parse("file://" + "/sdcard/namecard/")));
    }
}
  比较重要的写了点注释,帮助理解吧
   EncodingUtils.java这个工具是从一个地方down过来的,很不错,分享给大家吧
 
 
	
/**
 * 二维码生成工具类
 */
public class EncodingUtils {
    public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm) {
        try {
            if (content == null || "".equals(content)) {
                return null;
            }
            // 配置参数
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 容错级别
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
                    heightPix, hints);
            int[] pixels = new int[widthPix * heightPix];
            // 下面这里按照二维码的算法,逐个生成二维码的图片,
            // 两个for循环是图片横列扫描的结果
            for (int y = 0; y < heightPix; y++) {
                for (int x = 0; x < widthPix; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * widthPix + x] = 0xff000000;
                    } else {
                        pixels[y * widthPix + x] = 0xffffffff;
                    }
                }
            }
            // 生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
            if (logoBm != null) {
                bitmap = addLogo(bitmap, logoBm);
            }
            //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
            return bitmap;
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 在二维码中间添加Logo图案
     */
    private static Bitmap addLogo(Bitmap src, Bitmap logo) {
        if (src == null) {
            return null;
        }
        if (logo == null) {
            return src;
        }
        //获取图片的宽高
        int srcWidth = src.getWidth();
        int srcHeight = src.getHeight();
        int logoWidth = logo.getWidth();
        int logoHeight = logo.getHeight();
        if (srcWidth == 0 || srcHeight == 0) {
            return null;
        }
        if (logoWidth == 0 || logoHeight == 0) {
            return src;
        }
        //logo大小为二维码整体大小的1/5
        float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
        Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
        try {
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(src, 0, 0, null);
            canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
            canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
            canvas.save(Canvas.ALL_SAVE_FLAG);
            canvas.restore();
        } catch (Exception e) {
            bitmap = null;
            e.getStackTrace();
        }
        return bitmap;
    }
}
 
 
到这里核心的代码就没了,但是这时候大家会发现没有SimpleCaptureActivity.java这个类,本来我们打开扫描框本来可是使用startActivityForResult(new Intent(ZxingActivity.this,CaptureActivity.class),0)来实现,但是你会发现这个扫描框的样式很吓人,因此我们通常就需要定义SimpleCaptureActivity.java继承CaptureActivity来实现比较好看的样式,注意在导入包时候一定要导入
import io.github.xudaojie.qrcodelib.CaptureActivity中的,负责样式会很吓人的。好接下来咱看一下Sim。的的代码吧!
ublic class SimpleCaptureActivity extends CaptureActivity {
    protected Activity mActivity = this;

    private AlertDialog mDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        mActivity = this;
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void handleResult(String resultString) {
        if (TextUtils.isEmpty(resultString)) {
            Toast.makeText(mActivity, io.github.xudaojie.qrcodelib.R.string.scan_failed, Toast.LENGTH_SHORT).show();
            restartPreview();
        } else {
            if (mDialog == null) {
                mDialog = new AlertDialog.Builder(mActivity)
                        .setMessage(resultString)
                        .setPositiveButton("确定", null)
                        .create();
                mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        restartPreview();
                    }
                });
            }
            if (!mDialog.isShowing()) {
                mDialog.setMessage(resultString);
                mDialog.show();
            }
        }
    }
}
 
 
Okay,这样简单的二维码的扫描和生成几乎已经搞定了,但是不要着急,你还需要在你的配置文件中添加适当的权限。
 
 
<!-- 二维码的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
这样就大致搞定了一个简单的二维码的效果。仅供参考哈。

发布了8 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/honey_angle_first/article/details/72963703
今日推荐