2017-09-13 10:20:36 ni357103403 阅读数 1320
  • Android 高级专题

    本课程包含23章,共计95个小节课程,内容包括:Android多线程、网络编程、数据解析、数据存储、多媒体、Android 图形图像、Android 动画、GPS 定位、 Android 传感器编程、蓝牙、NDK、消息推送、二维码生成与扫描、分享和第三方登录、Bmob云服务、Afinal框架、 XUtils框架、版本控制、性能测试(听云)、App发布上线、Vitamio 跨平台播放器、EventBus、Android MVP 架构等。

    10597 人正在学习 去看看 郭宏志

本文章转自http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428

Zxing使用

从底部gitHub项目下载地址下载项目完后,可以看到整体代码结构如下:

这里写图片描述

这里写图片描述

我们只需将zxing包下的所有代码copy一份到我们的项目中去,除了这写代码以外,还需要zxing的jar包,也从项目中直接copy一份

全部copy完之后,还需要相应的资源文件

1、values文件下的ids文件
2、raw文件中的资源文件(可以替换)
3、layout文件下的activity_capture.xml(可以进行相应的订制)
4、图片资源

生成二维码

等上面工作全部准备完毕后,就可以创建我们的二维码了,如何生成二维码?这时需要EncodingUtils这个二维码生成工具类。通过调用工具类中的createQRCode方法来生成二维码。

/**
 * 创建二维码
 *
 * @param content   content
 * @param widthPix  widthPix
 * @param heightPix heightPix
 * @param logoBm    logoBm
 * @return 二维码
 */
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;
}

    /**
     * 创建二维码并将图片保存在本地
     */
    private void create() {
        int width = DensityUtil.dip2px(this, 200);
        Bitmap bitmap = EncodingUtils.createQRCode("http://www.baidu.com",
                width, width, BitmapFactory.decodeResource(getResources(),
                        R.drawable.ic_launcher));
        iv_zxing.setImageBitmap(bitmap);
        saveBitmap(bitmap);
    }

    /**
     * 将Bitmap保存在本地
     * 
     * @param 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(CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(this.getContentResolver(),
                    file.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // 通知图库更新
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.parse("file://" + "/sdcard/namecard/")));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

这里生成的二维码内容是一个百度的地址,中间LOGO是默认的安卓小机器人。

运行程序可以看到如下效果:

这里写图片描述

二维码扫描

二维码扫描需要借助于我们的CaptureActivity这个类,打开CaptureActivity界面并进行扫描,扫描完毕后回调onActivityResult方法,也就是我们可以通过onActivityResult得到扫描后的结果。详细代码如下:

    /**
     * 打开二维码扫描
     */
    private void open() {
        config();
        startActivityForResult(new Intent(MainActivity.this,
                CaptureActivity.class), 0);
    }
    /**
     * 提高屏幕亮度
     */
    private void config() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = 1.0f;
        getWindow().setAttributes(lp);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();
            String result = bundle.getString("result");
            tv_result.setText(result);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

效果就不演示的,因为使用的是模拟器。

扫描本地图片

扫描本地图片需要我们在CaptureActivity中进行相应的修改,为此我在扫描界面底部增加了一个按钮,用来选择本地图片。layout代码这里就不展示,我们直接看点击后的事件处理。

    /**
     * 打开本地图片
     */
    private void openLocalImage() {
        // 打开手机中的相册
        Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); 
        innerIntent.setType("image/*");
        Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");
        this.startActivityForResult(wrapperIntent, 0x01);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

打开系统图片库后选择图片,这时需要重写onActivityResult方法用于返回图片信息。

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            case 0x01:
                // 获取选中图片的路径
                Cursor cursor = getContentResolver().query(data.getData(),
                        null, null, null, null);
                if (cursor.moveToFirst()) {
                    photo_path = cursor.getString(cursor
                            .getColumnIndex(MediaStore.Images.Media.DATA));
                }
                cursor.close();

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Result result = scanningImage(photo_path);
                        if (result != null) {
                            handleDecode(result, new Bundle());
                        }
                    }
                }).start();

                break;

            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

获取图片路径photo_path后,调用scanningImage方法进行扫描,zxing源码中,扫描到的结果都是存放在Result这个结果集中。获取到Result后,就进行结果的回传,阅读CaptureActivity源码,可以得知最后Result结果集会传递给handleDecode方法。

    /**
     * A valid barcode has been found, so give an indication of success and show
     * the results.
     * 
     * @param rawResult
     *            The contents of the barcode.
     * @param bundle
     *            The extras
     */
    public void handleDecode(Result rawResult, Bundle bundle) {
        inactivityTimer.onActivity();
        beepManager.playBeepSoundAndVibrate();

        Intent resultIntent = new Intent();
        bundle.putInt("width", mCropRect.width());
        bundle.putInt("height", mCropRect.height());
        bundle.putString("result", rawResult.getText());
        resultIntent.putExtras(bundle);
        this.setResult(RESULT_OK, resultIntent);
        CaptureActivity.this.finish();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

获取到图片路径后需要将其二维码信息包装成Result对象,因此需要解析图片:

    /**
     * 扫描二维码图片的方法
     * 
     * @param path
     * @return
     */
    public Result scanningImage(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; // 先获取原大小
        scanBitmap = BitmapFactory.decodeFile(path, options);
        options.inJustDecodeBounds = false; // 获取新的大小
        int sampleSize = (int) (options.outHeight / (float) 200);
        if (sampleSize <= 0)
            sampleSize = 1;
        options.inSampleSize = sampleSize;
        scanBitmap = BitmapFactory.decodeFile(path, options);
        int width = scanBitmap.getWidth();
        int height = scanBitmap.getHeight();
        int[] pixels = new int[width * height];
        scanBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        /**
         * 第三个参数是图片的像素
         */
        RGBLuminanceSource source = new RGBLuminanceSource(width, height,
                pixels);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        try {
            return reader.decode(bitmap1, hints);

        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        }
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

根据路径获取Bitmap,最后通过QRCodeReader 中的decode方法解析成Result对象并返回,最终传递给handleDecode方法。

运行程序效果如下:

这里写图片描述

最后扫描出来的是之前定义的百度地址。

权限与Activity

当二维码的生成与扫描完成后,别忘了权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.zxingtest"
    android:versionCode="1"
    android:versionName="1.0" >

    <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"/>

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.example.zxingtest.zxing.activity.CaptureActivity"></activity>
    </application>

</manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

以下是完整的github项目地址
github项目源码地址:点击【项目源码】

2017-03-18 17:23:09 Android_Cll 阅读数 13461
  • Android 高级专题

    本课程包含23章,共计95个小节课程,内容包括:Android多线程、网络编程、数据解析、数据存储、多媒体、Android 图形图像、Android 动画、GPS 定位、 Android 传感器编程、蓝牙、NDK、消息推送、二维码生成与扫描、分享和第三方登录、Bmob云服务、Afinal框架、 XUtils框架、版本控制、性能测试(听云)、App发布上线、Vitamio 跨平台播放器、EventBus、Android MVP 架构等。

    10597 人正在学习 去看看 郭宏志

-----------------转载请注明出处:http://blog.csdn.net/android_cll

-----------------都有注释我就不用说得太清楚,我就贴一下实现步骤和源码,不懂得可以下载源码自己看、

一:效果图:



二:实现步骤:

1.导入第三方架包,下载地址:

http://download.csdn.net/detail/android_cll/9784977

2.在项目build.gradle文件下加入相应的包、

compile 'cn.yipianfengye.android:zxing-library:2.1'

3.一个图片的Util工具类、

package com.uuch.android_zxinglibrary;

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

/**
 * 文 件 名: ImageUtil
 * 创 建 人: 曹刘浪
 * 创建日期: 2017-3-18 12:12
 */

public class ImageUtil {
    /**
     * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换
     *
     * @param context
     * @param imageUri
     */
    @TargetApi(19)
    public static String getImageAbsolutePath(Context context, Uri imageUri) {
        if (context == null || imageUri == null)
            return null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
            if (isExternalStorageDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri)) {
                String id = DocumentsContract.getDocumentId(imageUri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } // MediaStore (and general)
        else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
            // Return the remote address
            if (isGooglePhotosUri(imageUri))
                return imageUri.getLastPathSegment();
            return getDataColumn(context, imageUri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
            return imageUri.getPath();
        }
        return null;
    }

    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }
}

4.第一个界面的xml、

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:background="#ff0000"
        android:text="二维码扫描"
        android:textColor="#fff" />


    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:background="#ff0000"
        android:text="二维码生成"
        android:textColor="#fff" />

</RelativeLayout>

5.MainActivity、

package com.uuch.android_zxinglibrary;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.uuzuche.lib_zxing.activity.CaptureActivity;
import com.uuzuche.lib_zxing.activity.CodeUtils;

import java.util.List;

import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

public class MainActivity extends Activity implements EasyPermissions.PermissionCallbacks{

    /**
     * 扫描跳转Activity RequestCode
     */
    public static final int REQUEST_CODE = 111;
    /**
     * 选择系统图片Request Code
     */
    public static final int REQUEST_IMAGE = 112;

    public Button button1 = null;
    public Button button4 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * 初始化组件
         */
        initView();
    }


    /**
     * 初始化组件
     */
    private void initView() {
        button1 = (Button) findViewById(R.id.button1);
        button4 = (Button) findViewById(R.id.button4);
        /**
         * 二维码扫描界面
         *
         *
         * 生成二维码图片
         */
        button1.setOnClickListener(new ButtonOnClickListener(button1.getId()));
        button4.setOnClickListener(new ButtonOnClickListener(button4.getId()));
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        /**
         * 处理二维码扫描结果
         */
        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();
                }
            }
        }

        /**
         * 选择系统图片并解析
         */
        else if (requestCode == REQUEST_IMAGE) {
            if (data != null) {
                Uri uri = data.getData();
                try {
                    CodeUtils.analyzeBitmap(ImageUtil.getImageAbsolutePath(this, uri), 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();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        else if (requestCode == REQUEST_CAMERA_PERM) {
            Toast.makeText(this, "从设置页面返回...", Toast.LENGTH_SHORT)
                    .show();
        }
    }


    /**
     * 请求CAMERA权限码
     */
    public static final int REQUEST_CAMERA_PERM = 101;


    /**
     * EsayPermissions接管权限处理逻辑
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }


    @AfterPermissionGranted(REQUEST_CAMERA_PERM)
    public void cameraTask(int viewId) {
        if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA)) {
            // Have permission, do the thing!
            onClick(viewId);
        } else {
            // Ask for one permission
            EasyPermissions.requestPermissions(this, "需要请求camera权限",
                    REQUEST_CAMERA_PERM, Manifest.permission.CAMERA);
        }
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        Toast.makeText(this, "执行onPermissionsGranted()...", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        Toast.makeText(this, "执行onPermissionsDenied()...", Toast.LENGTH_SHORT).show();
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this, "当前App需要申请camera权限,需要打开设置页面么?")
                    .setTitle("权限申请")
                    .setPositiveButton("确认")
                    .setNegativeButton("取消", null /* click listener */)
                    .setRequestCode(REQUEST_CAMERA_PERM)
                    .build()
                    .show();
        }
    }


    /**
     * 按钮点击监听
     */
    class ButtonOnClickListener implements View.OnClickListener{

        private int buttonId;

        public ButtonOnClickListener(int buttonId) {
            this.buttonId = buttonId;
        }

        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.button4) {
                Intent intent = new Intent(MainActivity.this, ThreeActivity.class);
                startActivity(intent);
            } else {
                cameraTask(buttonId);
            }
        }
    }


    /**
     * 按钮点击事件处理逻辑
     * @param buttonId
     */
    private void onClick(int buttonId) {
        switch (buttonId) {
            case R.id.button1:
                Intent intent = new Intent(getApplication(), CaptureActivity.class);
                startActivityForResult(intent, REQUEST_CODE);
                break;
            default:
                break;
        }
    }
}

6.二维码生成界面的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"
    android:fitsSystemWindows="true">

    <EditText
        android:id="@+id/edit_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:minLines="3" />

    <Button
        android:id="@+id/button_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/edit_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:text="生成logo二维码图片"
        android:visibility="gone" />

    <Button
        android:id="@+id/button1_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:text="生成普通二维码图片" />

    <ImageView
        android:id="@+id/image_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />

</RelativeLayout>

7.二维码生成ThreeActivity、

package com.uuch.android_zxinglibrary;

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.uuzuche.lib_zxing.activity.CodeUtils;

public class ThreeActivity extends Activity {

    public EditText editText = null;
    public Button button1 = null;
    public ImageView imageView = null;

    public Bitmap mBitmap = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);


        initView();
    }

    /**
     * 初始化组件
     */
    private void initView() {

        editText = (EditText) findViewById(R.id.edit_content);
        button1 = (Button) findViewById(R.id.button1_content);
        imageView = (ImageView) findViewById(R.id.image_content);


        /**
         * 生成不带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);
            }
        });
    }

}

8.去AppLication初始化、

package com.uuch.android_zxinglibrary;

import android.app.Application;

import com.uuzuche.lib_zxing.activity.ZXingLibrary;

public class MApplication extends Application{

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

        ZXingLibrary.initDisplayOpinion(this);
    }
}

9.在AndroidManifest.xml文件中加上权限、

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

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

------------------------到这应该都已经写完了这个功能,大神勿喷,不会的或者想节约时间的可以下载源码、

源码地址:http://download.csdn.net/detail/android_cll/9785625


2016-09-15 23:09:10 a_zhon 阅读数 3955
  • Android 高级专题

    本课程包含23章,共计95个小节课程,内容包括:Android多线程、网络编程、数据解析、数据存储、多媒体、Android 图形图像、Android 动画、GPS 定位、 Android 传感器编程、蓝牙、NDK、消息推送、二维码生成与扫描、分享和第三方登录、Bmob云服务、Afinal框架、 XUtils框架、版本控制、性能测试(听云)、App发布上线、Vitamio 跨平台播放器、EventBus、Android MVP 架构等。

    10597 人正在学习 去看看 郭宏志

现在越来越多的app都具有扫码功能了,扫码支付,扫码登录等等。。。如果要进入网页只需打开相机对准二维码一扫就可完成了,省去了输入网址的繁琐的步骤大大的提高了效率,下面就让我们自己的app也实现这个功能。

zxing源代码github地址这里面具有各个平台的源代码。

这里使用的zxing库下载

1.实现二维码扫描

//需要以带返回结果的方式启动扫描界面
  Intent intent = new Intent(oneActivity.this, CaptureActivity.class);
  startActivityForResult(intent, 0);

2.重写onActivityResult获取扫描到的结果

 if (resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();
	        //获取扫描结果
            String result = bundle.getString("result");
            Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        }

3.生成二维码,这里可以选择生成带Logo和不带Logo的二维码样式。

Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.azhong);
/**
* 第一个参数:需要转换成二维码的内容
* 第二个参数:二维码的宽度
* 第三个参数:二维码的高度
* 第四个参数:Logo图片
*/
Bitmap bitmap = EncodingUtils.createQRCode("http://blog.csdn.net/a_zhon/", 500, 500, logo);

只需这几步便可轻松集成二维码至app,还是非常友好的。

效果图,因为这里模拟器没有摄像头所以就无法演示了,同时还需要进设置–>应用–>授予app摄像头权限

这里写图片描述

2016-06-28 11:27:07 zhupengqq 阅读数 713
  • Android 高级专题

    本课程包含23章,共计95个小节课程,内容包括:Android多线程、网络编程、数据解析、数据存储、多媒体、Android 图形图像、Android 动画、GPS 定位、 Android 传感器编程、蓝牙、NDK、消息推送、二维码生成与扫描、分享和第三方登录、Bmob云服务、Afinal框架、 XUtils框架、版本控制、性能测试(听云)、App发布上线、Vitamio 跨平台播放器、EventBus、Android MVP 架构等。

    10597 人正在学习 去看看 郭宏志

Android二维码扫描开发和二维码的生成


下面看完成过程:
1.先导入外界的类库 BarCodeTest

2新建一个项目:
在布局中定义
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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:id="@+id/btnscon"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="开始扫描" />

    <TextView
        android:id="@+id/tv1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="show" />
</LinearLayout>
在MainActivity.java中
package com.example.testqrcode;

import java.security.spec.EncodedKeySpec;

import com.google.zxing.WriterException;
import com.zxing.activity.CaptureActivity;
import com.zxing.encoding.EncodingHandler;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;

public class MainActivity extends Activity {
	private Button  scanButton,btngen;
	private TextView   tvshow;
	private EditText    edt1;
	private ImageView  iv1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		scanButton=(Button) findViewById(R.id.btnscon);
		tvshow=(TextView) findViewById(R.id.tv1);
		scanButton.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Log.d("MainActivity", "可以扫描二维码了");
				Intent  startSan=new Intent(MainActivity.this,CaptureActivity.class);
				//startActivity(startSan);
				startActivityForResult(startSan, 0);
			}
		});
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if(resultCode==RESULT_OK){
			String result=data.getExtras().getString("result");
			tvshow.setText(result);
		}
	}
}
另外这个CaptureActivity.class是外部的类,所以要在 AndroidManifest.xml中定义
找到BarCodeTest的AndroidManifest.xml,会发现有这样一段话
 <activity
            android:configChanges="orientation|keyboardHidden"
            android:name="com.zxing.activity.CaptureActivity"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >
        </activity>
把这个类的声明复制到你的项目中去

运行之后,会出现这样,反馈的信息


那么怎么根据输入的值生成一个二维码呢?
在布局中定义:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/edt1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="请输入要编码的内容" >
    </EditText>

    <Button
        android:id="@+id/btngen"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="生成二维码" />

    <ImageView
        android:id="@+id/iv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:layout_gravity="center_horizontal"
        />

</LinearLayout>
在MainActivity.java中

package com.example.testqrcode;

import java.security.spec.EncodedKeySpec;

import com.google.zxing.WriterException;
import com.zxing.activity.CaptureActivity;
import com.zxing.encoding.EncodingHandler;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;

public class MainActivity extends Activity {
	private Button  scanButton,btngen;
	private TextView   tvshow;
	private EditText    edt1;
	private ImageView  iv1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tvshow=(TextView) findViewById(R.id.tv1);
		btngen=(Button) findViewById(R.id.btngen);
		edt1=(EditText) findViewById(R.id.edt1);
		iv1=(ImageView) findViewById(R.id.iv1);
		btngen.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String in=edt1.getText().toString();
				if(in.equals("")){
					Log.d("MainActivity", "请输入文本");
				}
				try {					
					Bitmap  qrcode=EncodingHandler.createQRCode(in, 400);
					iv1.setImageBitmap(qrcode);
				} catch (WriterException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
}
生成的二维码会放在定义的ImgeView里(这里是放在ImgeView,当然你可以根据你项目的需求,放在自己 想放的地方,方便我们灵活运用


2017-06-01 18:41:46 qq_35619188 阅读数 308
  • Android 高级专题

    本课程包含23章,共计95个小节课程,内容包括:Android多线程、网络编程、数据解析、数据存储、多媒体、Android 图形图像、Android 动画、GPS 定位、 Android 传感器编程、蓝牙、NDK、消息推送、二维码生成与扫描、分享和第三方登录、Bmob云服务、Afinal框架、 XUtils框架、版本控制、性能测试(听云)、App发布上线、Vitamio 跨平台播放器、EventBus、Android MVP 架构等。

    10597 人正在学习 去看看 郭宏志

看几篇文章:
Android如何为按键添加声音 (扫描完成后可添加声音。)
Android 长按识别图中二维码 zxing
android端快速生成二维码和进行二维码扫描(按照这个方法导入项目很容易实现)
Android端最新二维码生成与创建库
当然还有其他更好的方法。 android二维码、条形码分分钟秒杀
实现过程:
在生成二维码点击事件中调用:

startActivityForResult(new
Intent(MainActivity.this,CaptureActivity.class),RESULT_CANCELED);

通过onActivityResult的到扫描结果:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode== Activity.RESULT_OK){
        //在这里添加声音。
            //sp.play(music, 1, 1, 0, 0, 1);
             bundle = data.getExtras(); //可以是URL String 标点符号等。
            Toast.makeText(this,bundle.getString("result"),Toast.LENGTH_LONG).show();
            //在textview中显示内容
            result.setText(bundle.getString("result"));
    //如果是网页通过Intent跳转。
//  Intent intent = new Intent();
//  intent.setAction("android.intent.action.VIEW");
//  Uri content_url = Uri.parse(bundle.getString("result"));
//  intent.setData(content_url);
//  startActivity(intent);
        }
    }

添加声音:

sp= new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
//将声音存在raw文件夹中
music =sp.load(this,R.raw.s,1);

生成二维码:
在EncodingUtils文件中提供了下面这个静态方法用于客户端快速创建二维码:

public static Bitmap createQRCode(String content, int widthPix, int heightPix, Bitmap logoBm)

第一个参数是生成二维码的内容(可以是任意字符串,超链接等等),第二三个参数表示生成二维码的宽度和高度(单位px),最后一个参数为图像,可以自定义。

        //s 为输入内容
      s= editText.getText().toString();
      Bitmap logoBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
      //调用EncodingUtils.createQRCode
      bitmap= EncodingUtils.createQRCode(s, 800,800, logoBitmap);//logoBitmap =null 没有图标
      //用ImageView 将二维码显示出来。
      img.setImageBitmap(bitmap);

长按二维码识别内容或者将二维码保存到本地:

img.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Bitmap obmp = ((BitmapDrawable) (img).getDrawable()).getBitmap();
                int width = obmp.getWidth();
                int height = obmp.getHeight();
                int[] data = new int[width * height];
                obmp.getPixels(data, 0, width, 0, 0, width, height);
                RGBLuminanceSource source = new RGBLuminanceSource(width, height, data);
                BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
                QRCodeReader reader = new QRCodeReader();
                Result re = null;
                try {
                    re = reader.decode(bitmap1);
                } catch (NotFoundException e) {
                    e.printStackTrace();
                } catch (ChecksumException e) {
                    e.printStackTrace();
                } catch (FormatException e) {
                    e.printStackTrace();
                }
                    showSelectAlert(obmp, re.getText());
                return false;
            }
        });

长按弹出对话框的方法:

private void showSelectAlert(final Bitmap bitmap, final String url) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("请选择");
        String str[] = {"保存图片", "扫二维码"};
        builder.setItems(str, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterfacem, int i) {
                switch (i) {
                    case 0: {
                    //保存图片
                        saveBitmap();
       Toast.makeText(MainActivity.this,"保存成功",Toast.LENGTH_LONG).show();

                    }
                    break;
                    case 1: {
                    //显示内容
                        Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
                    }
                    break;
                }
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterfacem, int i) {

            }
        });
        builder.show();}

保存图片的方法:

    /** 保存方法 */
    public void saveBitmap() {
    //创建或判断文件是否存在 localTempImgDir 文件夹名称
        File f = new File(Environment.getExternalStorageDirectory()+"/"+localTempImgDir);
        if (!f.exists())
            f.mkdirs();
       File cameraFile =new File(f,"二维码"+(new SimpleDateFormat("yyyy_MM_dd_HHmmss").format(new Date()))+".jpg");
        try {
        //压缩文件
            FileOutputStream out = new FileOutputStream(cameraFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //更新图库
        MediaScannerConnection.scanFile(MainActivity.this, new String[]{cameraFile.getAbsolutePath()}, null, null);

    }

因为要访问相机 ,所以要添加权限:

    private  PermissionListener mListener;

    private void takePhotoForCamera() {
        String[] permissions={Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
        requestRuntimePermission(permissions, new PermissionListener() {
            @Override
            public void onGranted() {

            }

            @Override
            public void onDenied(List<String> deniedPermission) {

            }
        });
    }
  //andrpoid 6.0 需要写运行时权限
    public void requestRuntimePermission(String[] permissions, MainActivity.PermissionListener listener) {

        mListener = listener;
        List<String> permissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {
                permissionList.add(permission);
            }
        }
        if (!permissionList.isEmpty()) {
            ActivityCompat.requestPermissions(MainActivity.this, permissionList.toArray(new String[permissionList.size()]), 1);
        } else {
            mListener.onGranted();
        }
    }


    @TargetApi(23)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    List<String> deniedPermissions = new ArrayList<>();
                    for (int i = 0; i < grantResults.length; i++) {
                        int grantResult = grantResults[i];
                        String permission = permissions[i];
                        if (grantResult != PackageManager.PERMISSION_GRANTED) {
                            deniedPermissions.add(permission);
                        }
                    }
                    if (deniedPermissions.isEmpty()) {
                        mListener.onGranted();
                    } else {
                        mListener.onDenied(deniedPermissions);
                    }
                }
                break;
            default:
                break;
        }
    }
    public interface PermissionListener {
        /**
         * 成功获取权限
         */
        void onGranted();

        /**
         * 为获取权限
         * @param deniedPermission
         */
        void onDenied(List<String> deniedPermission);

    }
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.CAMERA" />  
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

自定义边框:使用zxing生成二维码,边框自定义宽度
EncodingUtils类中:

//二维码边框宽度,这里文档说设置0-4
hints.put(EncodeHintType.MARGIN,1);

也可以

        bitMatrix= updateBit(bitMatrix,2); //2 为边框宽度

     //该方法生成自定义白边框后的bitMatrix;  也可以、通过 hints.put(EncodeHintType.MARGIN,1)设置
    private static  BitMatrix updateBit(BitMatrix matrix, int margin){

        int tempM = margin*2;

        int[] rec = matrix.getEnclosingRectangle();   //获取二维码图案的属性

        int resWidth = rec[2] + tempM;

        int resHeight = rec[3] + tempM;

        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix

        resMatrix.clear();

        for(int i= margin; i < resWidth- margin; i++){   //循环,将二维码图案绘制到新的bitMatrix中

            for(int j=margin; j < resHeight-margin; j++){

                if(matrix.get(i-margin + rec[0], j-margin + rec[1])){

                    resMatrix.set(i,j);

                }

            }

        }

        return resMatrix;

    }
没有更多推荐了,返回首页