Android項目實戰(二十八):使用Zxing實現二維碼及最佳化執行個體_Android

來源:互聯網
上載者:User

前言:

多年之前接觸過zxing實現二維碼,沒想到今日項目中再此使用竟然使用的還是zxing,百度之,竟是如此牛的玩意。

當然,項目中我們也許只會用到二維碼的掃描和產生兩個功能,所以不必下載完整的jar包,使用簡化版的即可,下文可見。

這篇文章講述:

1、如果快速在項目中整合zxing,實現掃描和產生二維碼功能                 

2、根據項目需求去修改源碼實現我們的要求並進行最佳化

一、快速整合zxing二維碼

1、下載庫檔案 :http://xiazai.jb51.net/201611/yuanma/ZXingBarCode_jb51.zip ,

下載完成後可以看到:

我們從這些檔案中拷貝需要的到自己的項目中,下面開始:

  ①、res 目錄下 : raw檔案夾 整個複製到個人項目相對位置

  ②、res --> values目錄下:ids.xml檔案中的內容全部複製到個人項目相對位置,個人項目沒有則直接複製檔案到相對位置

  ③、res --> values目錄下:colors.xml檔案中的內容全部複製到個人項目的相對位置

  ④、res --> layout目錄下:camera.xml 布局檔案複製到個人項目相對位置

  ⑤、res --> drawable_mdpi 目錄下:navbar.9.png圖片複製到個人項目相對位置,這張圖片是標題列背景圖片,這裡建議先改成navbar.png 不要使用.9圖片

  ⑥、libs目錄下:zxing.jar檔案複製到個人項目相對位置,並且右鍵點擊as library

  ⑦、src --> com目錄下:zxing 檔案夾複製到個人項目相對位置 ,會報錯,修改R的目錄結構即可

  ⑧、AndroidManifest.xml檔案中 添加 (二維碼掃描activity,這個需要後面自己去修改,用於實現自己的要求)

 <activity android:name="com.zxing.activity.CaptureActivity"/>

⑨、AndroidManifest.xml檔案中 添加許可權  

<uses-permission android:name="android.permission.CAMERA" />  <uses-permission android:name="android.permission.VIBRATE" />  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2、準備工作完成了,下面開始寫demo

現在需求是一個主介面MainActivity.java 裡面有兩個按鈕,分別跳轉 產生二維碼介面和 掃描二維碼介面
然後分別開始寫兩個activity功能的實現:

①、 產生二維碼

先寫布局檔案  ,一個圖片 , 一個開始產生按鈕 , 一個輸入框(二維碼需要根據文本資訊產生,沒有文本資訊無法產生)
activity_create.xml

<?xml version="1.0" encoding="utf-8"?><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="com.maiji.zxingdemo.CreateActivity">  <ImageView    android:id="@+id/create_img"    android:layout_width="300dp"    android:layout_height="300dp"    android:scaleType="fitXY"    android:layout_gravity="center_horizontal"    />  <Button    android:id="@+id/create_btn"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center_horizontal"    android:text="開始產生二維碼"    />  <EditText    android:id="@+id/create_edit"    android:layout_width="match_parent"    android:layout_height="wrap_content" /></LinearLayout>

activity代碼: 代碼比較簡單 ,不在此解釋了

private ImageView create_img;  private Button create_btn;  private EditText create_edit;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_create);    initView();    initEvent();  }  private void initEvent() {    create_btn.setOnClickListener(this);  }  private void initView() {    create_img = (ImageView) findViewById(R.id.create_img);    create_btn = (Button) findViewById(R.id.create_btn);    create_edit = (EditText) findViewById(R.id.create_edit);  }  @Override  public void onClick(View v) {    switch (v.getId()){      case R.id.create_btn:        String content = "" ;        if (create_edit.getText().toString().equals("")){          Toast.makeText(this,"請輸入二維碼資訊",Toast.LENGTH_SHORT).show();          return;        }        content = create_edit.getText().toString();        try {          //產生二維碼圖片,第一個參數是二維碼的內容,第二個參數是正方形圖片的邊長,單位是像素          Bitmap qrcodeBitmap = EncodingHandler.createQRCode(content, 800);          if (qrcodeBitmap!=null) {            create_img.setImageBitmap(qrcodeBitmap);          }else{            Toast.makeText(this,"產生二維碼失敗",Toast.LENGTH_SHORT).show();          }        } catch (Exception e) {          // TODO Auto-generated catch block          e.printStackTrace();        }        break;    }  }  public byte[] Bitmap2Bytes(Bitmap bm) {    ByteArrayOutputStream baos = new ByteArrayOutputStream();    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);    return baos.toByteArray();  }

效果圖:

②、掃描二維碼

這個就更簡單了,只需要開啟一個zxing提供的activity 然後擷取到掃描得到的字串即可

看ScanActivity(掃描Activity)的關鍵代碼

private TextView zxing_content;@Overrideprotected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_scan);  zxing_content = (TextView) findViewById(R.id.zxing_content);  Intent startScan = new Intent(this,CaptureActivity.class);  startActivityForResult(startScan, 0); //實際開啟了一個zxing提供給我們的掃描activity,當然我們後面會對這個activity進行一些最佳化修改}/** * 掃一掃,成功後傳回值進行判斷 */@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {  super.onActivityResult(requestCode, resultCode, data);  if (resultCode == -1) {    String result = data.getExtras().getString("result");    zxing_content.setText(result); //顯示掃描二維碼得到的資料  }}

布局檔案:

<?xml version="1.0" encoding="utf-8"?><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.maiji.zxingdemo.ScanActivity">  <TextView    android:id="@+id/zxing_content"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_centerInParent="true"    android:textSize="30sp"    /></RelativeLayout>

效果圖:

二、修改源碼,實現項目的需求

1、修改掃描二維碼的介面

對應的是 zxing-->activity-->CaptureActivity.java   ,布局檔案為 camera.xml

所以修改介面只需要在 camera.xml檔案中修改即可。

無非就是把原來的“CANCEL”取消按鈕去掉,把頂部的標題列換一下。

布局裡面有一個 <SurfaceView>控制項 用於顯示相機拍出的畫面預覽,這裡可以根據需求改是全介面顯示還是顯示局部

<com.zxing.view.ViewfinderView>控制項,即掃描框,預設的是寬高比1:1.5,實際需要修改寬高,在下面介紹

2、修改掃描框的寬高

第1步操作做完之後會發現,我們沒法修改掃描框的寬高。

修改掃描框寬高很簡單,找到 zxing-->camera-->CameraManager.java 檔案

這裡較為頂部的代碼中看到:

 private static final int MIN_FRAME_WIDTH = 240; private static final int MIN_FRAME_HEIGHT = 240; private static final int MAX_FRAME_WIDTH = 480; private static final int MAX_FRAME_HEIGHT = 480;

這四個屬性的值即掃描框的寬高,然後可以根據需求直接修改,當然這個值在不同解析度的裝置上寬高不一致 , 有需要的話可以進行一下單位轉換

 public static int Dp2Px( Context context,float dp) {  final float scale = context.getResources().getDisplayMetrics().density;  return (int) (dp * scale + 0.5f); }

 效果圖: 我修改了掃描框的最小最大寬高分別一致,並且載camera.xml布局中刪去了“CANCEL”取消按鈕

 3、給掃描框添加文字提示

看一下微信的掃描介面,會發現掃描框下面有一段文字提示。 那麼我們這裡沒有,需要添加

找到zxing-->view-->Viewfinderview.java

這裡是自訂掃描框的類

找到代碼:

 canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);   Collection<ResultPoint> currentPossible = possibleResultPoints;

在這兩行代碼之間我們畫上文字提示

canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);    TextPaint textPaint = new TextPaint();   textPaint.setARGB(0xFF, 0xFF, 0xFF,0xFF);  //字型顏色   textPaint.setTextSize(32);  //字型大小   textPaint.setAntiAlias(true); //設定消除鋸齒,否則字跡會很模糊   StaticLayout layout = new StaticLayout("將二維碼放入框內,即可自動掃描",textPaint,       frame.right-frame.left, Layout.Alignment.ALIGN_NORMAL,1.0F,0.0F,true);   canvas.translate(frame.left+5, (float) (frame.bottom + (float)30)); //繪製起始位置   layout.draw(canvas);   Collection<ResultPoint> currentPossible = possibleResultPoints;

然後在看下掃描介面效果圖:

4、解決掃描介面相機預覽展開變形問題

實現了上面幾步的最佳化,仔細的同學可能會發現,如果我們給SurfaceView設定全螢幕顯示(可以看到的相機畫面很多),會發現相機拍攝出來的預覽圖有些展開變形

原因:zxing橫屏變豎屏之後,Camera的代碼還是採用的橫屏代碼設定的參數

最佳化方法:找到 zxing-->camera--> CameraConfigurationManager.java

initFromCameraParameters方法中,在 Log.d(TAG, "Screen resolution: " + screenResolution);這句之後增加Point screenResolutionForCamera = new Point();screenResolutionForCamera.x = screenResolution.x;screenResolutionForCamera.y = screenResolution.y;    if (screenResolution.x < screenResolution.y) {screenResolutionForCamera.x = screenResolution.y;screenResolutionForCamera.y = screenResolution.x; }

再將cameraResolution = getCameraResolution(parameters, screenResolution);更改為

cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);

完成之後,在進行掃描操作,這時候相機拍出來的預覽介面就正常顯示,不再有展開變形問題。

至此便給項目引入了一個可以使用的二維碼模組功能了。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.