欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android如何实现URL转换成二维码

程序员文章站 2022-08-02 14:58:40
二维码已经成为我们日常生活中的一个不可获取的产物,火车票上,景区门票,超市付款等等都会有二维码的身影。 本文将实现由url转换成二维码的过程。 先看一下示例图 从...

二维码已经成为我们日常生活中的一个不可获取的产物,火车票上,景区门票,超市付款等等都会有二维码的身影。

本文将实现由url转换成二维码的过程。

先看一下示例图

Android如何实现URL转换成二维码

从示例图中我们可以清晰地看到,url被转换成了二维码。

下面跟随我来一起实现这个功能。

导入google提供的开源库

compile 'com.google.zxing:core:3.3.0'

来讲解一下核心的部分:二维码转换

①生成二维码bitmap

public static boolean createqrimage(string content, int widthpix, int heightpix, bitmap logobm, string filepath) {
    try {
      if (content == null || "".equals(content)) {
        return false;
      }

      //配置参数
      map<encodehinttype, object> hints = new hashmap<>();
      hints.put(encodehinttype.character_set, "utf-8");
      //容错级别
      hints.put(encodehinttype.error_correction, errorcorrectionlevel.h);
      //设置空白边距的宽度
      hints.put(encodehinttype.margin, 2); //default is 4

      // 图像数据转换,使用了矩阵转换
      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 != null && bitmap.compress(bitmap.compressformat.jpeg, 100, new fileoutputstream(filepath));
    } catch (writerexception | ioexception e) {
      e.printstacktrace();
    }

    return false;
  }

②在二维码中间添加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;
  }

③创建二维码文件存储目录

private static string getfileroot(context context) {
    if (environment.getexternalstoragestate().equals(environment.media_mounted)) {
      file external = context.getexternalfilesdir(null);
      if (external != null) {
        return external.getabsolutepath();
      }
    }

    return context.getfilesdir().getabsolutepath();
  }

④创建数据库工具类来存储临时数据

public class sputil {

  private static final string config = "config";

  /**
   * 获取sharedpreferences实例对象
   *
   * @param filename
   */
  private static sharedpreferences getsharedpreference(string filename) {
    return qrcodeapplication.getinstance().getsharedpreferences(filename, context.mode_private);
  }

  /**
   * 保存一个string类型的值!
   */
  public static void putstring(string key, string value) {
    sharedpreferences.editor editor = getsharedpreference(config).edit();
    editor.putstring(key, value).apply();
  }

  /**
   * 获取string的value
   */
  public static string getstring(string key, string defvalue) {
    sharedpreferences sharedpreference = getsharedpreference(config);
    return sharedpreference.getstring(key, defvalue);
  }

}

⑤展示二维码

public static void showthreadimage(final activity mcontext, final string text, final imageview imageview, final int centerphoto) {
    string precontent = sputil.getstring("share_code_content", "");
    if (text.equals(precontent)) {
      string prefilepath = sputil.getstring("share_code_filepath", "");
      imageview.setimagebitmap(bitmapfactory.decodefile(prefilepath));

    } else {
      sputil.putstring("share_code_content", text);
      final string filepath = getfileroot(mcontext) + file.separator + "qr_" + system.currenttimemillis() + ".jpg";
      sputil.putstring("share_code_filepath", filepath);

      //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中
      new thread(new runnable() {
        @override
        public void run() {
          boolean success = qrcodeutil.createqrimage(text, 800, 800, bitmapfactory.decoderesource(mcontext.getresources(), centerphoto),
              filepath);

          if (success) {
            mcontext.runonuithread(new runnable() {
              @override
              public void run() {
                imageview.setimagebitmap(bitmapfactory.decodefile(filepath));
              }
            });
          }
        }
      }).start();
    }
  }

构造一个输入页面的类,使用bundle通过<key,value>传值(后期会改为mvvm-databinding形式)

public class contentactivity extends appcompatactivity implements view.onclicklistener {

  private edittext eturl;

  private button btnconvert;

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_content);

    initview();
  }

  private void initview() {
    eturl = (edittext) findviewbyid(r.id.et_url);
    btnconvert = (button) findviewbyid(r.id.btn_convert);

    btnconvert.setonclicklistener(this);

  }

  @override
  public void onclick(view v) {
    switch (v.getid()) {
      case r.id.btn_convert:
        string str_url = "https://" + eturl.gettext().tostring();
        bundle bundle = new bundle();
        bundle.putstring("url", str_url);
        // 当输入框为空时,提示用户
        if (str_url.equals("https://")) {
          toast.maketext(getapplicationcontext(), "输入框不能为空", toast.length_short).show();
        } else {
          intent intent = new intent(contentactivity.this, mainactivity.class);
          intent.putextras(bundle);
          startactivity(intent);
        }
        break;
      default:
        break;
    }
  }
}

将二维码图片展示在页面上(后期会改为mvvm-databinding形式)

public class mainactivity extends appcompatactivity {

  private imageview iv;

//  private string url = "http://weibo.com/cnwutianhao";

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);

    string str_url = getintent().getextras().getstring("url");

    iv = (imageview) findviewbyid(r.id.iv_qrcode);

    qrcodeutil.showthreadimage(this, str_url, iv, r.mipmap.ic_launcher);
  }
}

布局文件

①输入页面(后期会改为databinding形式)

<?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:orientation="vertical"
  android:padding="10dp">

  <edittext
    android:id="@+id/et_url"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_margintop="100dp"
    android:hint="请输入网址"
    android:inputtype="texturi" />

  <button
    android:id="@+id/btn_convert"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignparentbottom="true"
    android:layout_centerhorizontal="true"
    android:layout_marginbottom="20dp"
    android:text="转换成二维码" />

</relativelayout>

②二维码展示页面

<relativelayout 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"
  tools:context="com.tnnowu.android.qrcode.mainactivity">

  <imageview
    android:id="@+id/iv_qrcode"
    android:layout_width="220dp"
    android:layout_height="220dp"
    android:layout_centerinparent="true"
    android:layout_margintop="40dp"
    android:background="#ffffff" />

</relativelayout>

源代码已上传至github,https://github.com/cnwutianhao/qrcode

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。