1. 程式人生 > >cocos2dx-lua在android上實現生成及掃描二維碼

cocos2dx-lua在android上實現生成及掃描二維碼

首先說明下,生成二維碼是用android原生的BitMatrix和Bitmap類來生成的,而掃描二維碼用到了google官方的zxing包(core.jar)。

這裡我把所有生成二維碼的程式碼和lua呼叫的掃描二維碼方法都放在了專案->frameworks->runtime-src->proj.android->src->org->cocos2dx->lua->AppActivity.java中。

而core_3.2.0.jar放在了proj.android->libs下,掃描二維碼相關類放到了專案->frameworks->runtime-src->proj.android

->src->zxing下。

-----1.下載zxing包core_3.2.0.jar

------------1.1下載地址

------------1.2下載後放在libs中

proj.android->libs->core_3.2.0.jar

-----2.下載掃描二維碼相關類及程式碼

------------2.1下載地址

------------2.2將相關類引入工程

將Android Zxing Demo->BarCodeTest->src->com->zxing複製貼上到專案->frameworks->runtime-src->

proj.android->src下。

------------2.3其中zxing包含的目錄結構為

zxing

->activity    ->CaptureActivity.java

->camera   ->AutoFocusCallback.java

                  ->CameraConfigurationManager.java

                  ->CameraManager.java

                  ->FlashLightManager.java

                  ->PlanarYUVLuminanceSource.java

                  ->PreviewCallback.java

->decoding->CaptureActivityHandler.java

                  ->DecodeFormatManager.java

                  ->DecodeHandler.java

                  ->DecodeThread.java

                  ->FinishListener.java

                  ->InactivityTimer.java

                  ->Intents.java

->enCoding->EncodingHandler.java

->view        ->ViewfinderResultPointCallback.java

                  ->ViewfinderView.java

-----3.匯入資源

------------3.1 values

將Android Zxing Demo->BarCodeTest->res->values中的ids.xml和colors.xml複製貼上到專案->frameworks->runtime-src->proj.android->res->values下,若已有這兩個檔案,合併下里面的程式碼。

------------3.2 raw

將Android Zxing Demo->BarCodeTest->res->raw中的beep.ogg和relm_properties複製貼上到專案->frameworks->runtime-src->proj.android->res->raw下,若已有這兩個檔案,重新命名。

------------3.3 layout

將Android Zxing Demo->BarCodeTest->res->layout中的camera.xml複製貼上到專案->frameworks->runtime-src->proj.android->res->layout下,若已有該檔案,重新命名。

------------3.4 圖片

這裡只有一個drawable-mdpi下的navbar.9.png需要匯入,由於我後來更改了camera.xml檔案,所以我就匯入了我們的掃描介面資源,沒匯入Android Zxing Demo中的圖片資源。後面我會把我改的camera.xml檔案程式碼貼出來,其中有3張圖片,資源我就不放出來了,沒有的去網上隨便找個,名字一致就行。當然也放在drawable-mdpi下。

-----4.AndroidManifest.xml修改

------------4.1 增加許可權

 	<!-- 二維碼 -->
 	<uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
------------4.2 增加掃描介面Activity

<Application />下新增Activity元素

        <activity
            android:name="zxing.activity.CaptureActivity"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:hardwareAccelerated="true" >
        </activity>
其中有句android:hardwareAccelerated="true",因為掃描介面是有個不斷掃動的條的,這裡我是用android的平移動畫來實現的,實現後出現了圖片閃爍顯示不全的問題,於是在該<activity />頁簽下加上了這句,意思是在該activity上開啟硬體加速

-----5.生成二維碼

------------5.1專案->frameworks->runtime-src->proj.android->src->org->cocos2dx->lua->AppActivity.java新增程式碼

其中報紅叉的類自己引入一下。

	private static final int BLACK = 0xff000000;
	private static final int WHITE = 0xffffffff;

	//生成二維碼
	public static boolean createQRCode(String str, int widthAndHeight, String filePath) throws WriterException {//Bitmap String str,int widthAndHeight
		Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
		BitMatrix matrix = new MultiFormatWriter().encode(str,
				BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		int[] pixels = new int[width * height];
		
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (matrix.get(x, y)) {
					pixels[y * width + x] = BLACK;
				}else{
					pixels[y * width + x] = WHITE;
				}
			}
		}
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_8888);
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		saveBitmap(bitmap, filePath);
		return true;
	}

	//儲存圖片
	public static void saveBitmap(Bitmap bitmap, String filePath){
		File file = new File(filePath, "qrCode.png");
		if (file.exists()) {
			file.delete();
		}
		try {
			FileOutputStream out = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, 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();
		}
	}
其中createQRcode方法為最終lua掉用oc的方法,將生成的圖片存到cocos2dx的writablePath下,並儲存為"qrCode.png"。最後在lua端取出用sprite顯示
------------5.2lua呼叫createQRcode方法,並顯示
    local luaj = require "src.cocos.cocos2d.luaj"
    local className = "org/cocos2dx/lua/AppActivity"
    local methodName = "createQRCode"
    local filePath = cc.FileUtils:getInstance():getWritablePath()
    local args = 
    {
        "https://www.baidu.com/",
        180,
        filePath
    }
    local sig = "(Ljava/lang/String;ILjava/lang/String;)Z"

    local ok, ret = luaj.callStaticMethod(className, methodName, args, sig)
    if ok and ret then
        print("ok and ret")
        filePath = filePath.."qrCode.png"
        local rect = cc.rect(0, 0, 180, 180)
        local sprite = cc.Sprite:create() 
        sprite:initWithFile(filePath, rect)
        sprite:setPosition(300, 300)
        self:addChild(sprite)
    end
luaj.callStaticMethod為lua呼叫java程式碼的方法。args為將要呼叫java方法的引數,sig為將要呼叫的java方法的引數型別和返回型別,括號裡為引數型別,括號外為返回型別。

-----6.掃描二維碼

------------6.1專案->frameworks->runtime-src->proj.android->src->org->cocos2dx->lua->AppActivity.java新增程式碼

其中報紅叉的類自己引入一下。

	public static AppActivity activity;
	private static int luaFuncId;
	private final static int SCANNIN_GREQUEST_CODE = 1;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		activity = this;
	}

	//掃描二維碼
	public static void scanQRCode(final int luaFunctionId){
		luaFuncId = luaFunctionId;
		Intent intent = new Intent();
		intent.setClass(activity, CaptureActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		activity.startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
	}

	//二維碼掃描成功返回時處理
	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
		case SCANNIN_GREQUEST_CODE:
			if(resultCode == RESULT_OK){
				Bundle bundle = data.getExtras();
				String result = bundle.getString("result");
				Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFuncId, result);
				Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFuncId);
			}
			break;
		}
    }
其中publicstatic AppActivityactivity;其中為呼叫掃描介面時需要的引數,其值在onCreate中賦值。

其中privatestaticintluaFuncId;為掃描成功後,java呼叫lua方法。這裡在lua呼叫java的scanQRCode方法時作為引數傳進來,並賦值。

------------6.2lua掉用java掃描二維碼程式碼:

    local luaj = require "src.cocos.cocos2d.luaj"
    local callBack = function (result)
        print("cocos result : ", result)
    end

    local className = "org/cocos2dx/lua/AppActivity"
    local methodName = "scanQRCode"
    local args = 
    {
        callBack
    }
    local sig = "(I)V"
    luaj.callStaticMethod(className, methodName, args, sig)
-----7.掃描二維碼程式碼修改

說明:由於我們的掃描介面是橫屏的,並且修改了掃描時的介面,同時加上掃描時的動畫,所以在demo的程式碼上做了些小改動。
------------7.1 橫屏掃描:

src->zing->camera->CameraConfigurationManager.java類的void setDesiredCameraParameters(Camera camera)方法中,

camera.setDisplayOrientation(90);註釋掉。

------------7.2 自己的掃描介面:

---------------------7.2.1ViewFinderView.java修改:
src->zing->view->ViewFinderView.java類的publicvoid onDraw(Canvas canvas)方法的裡面全部註釋,不用demo中的介面。

---------------------7.2.2camera.xml修改:
全部程式碼為:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
        android:layout_gravity="center" />

	<zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
        
	<ImageView
		android:id="@+id/scan_bg"
	    android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
		android:src="@drawable/bg_saoyisao" />
        
	<ImageView
		android:id="@+id/scan_line"
		android:layout_width="280dp"
		android:layout_height="2dp"
		android:layout_alignParentTop="true"
		android:layout_gravity="center_horizontal"
		android:layout_marginTop="70dp"
		android:src="@drawable/bg_saoyisao_tiao" />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:orientation="vertical" >

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:paddingBottom="10dp"
            android:paddingTop="10dp"
            android:text="@string/saoyisao"
            android:textColor="@android:color/white"
            android:textSize="25sp"	/>

        <Button
            android:id="@+id/btn_cancel_scan"
            android:layout_width="19dp"
            android:layout_height="33dp"
            android:gravity="top|left"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:background="@drawable/btn_fanhui1" />
        
    </RelativeLayout>

</FrameLayout>
其中scan_bg為掃描框及其餘部分半透的一個大背景,scan_line為不斷掃描的條,btn_cancel_scan為返回按鈕。沒有圖片資源的可以在網上隨便找個,然後把名字改為上面對應的名字,放在res->drawable-mdpi下。
------------7.3 掃描線動畫:
src->zxing->activity->CaptureActivity.java類中publicvoid onCreate(Bundle savedInstanceState)方法最後新增程式碼:
		TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 650); 
		animation.setDuration(2000);//設定動畫持續時間 
		animation.setRepeatCount(-1);//設定重複次數 Animation.INFINITE
//		animation.setRepeatMode(Animation.REVERSE);//設定反方向執行 
		scanLine.startAnimation(animation);
由於播放掃描條的動畫時,掃描條閃爍顯示不全,所以在AndroidManifest.xml中添加了開啟硬體加速的程式碼,參考4.2 。 -----8.備註: ------------8.1 完整AppAcitivity.java程式碼:
/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2016 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
 
http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.lua;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;

import zxing.activity.CaptureActivity;

/**
 * 以下均為掃描二維碼倒入的類 
 */
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Hashtable;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;

public class AppActivity extends Cocos2dxActivity{  
	public static AppActivity activity;
	private static int luaFuncId;
	private final static int SCANNIN_GREQUEST_CODE = 1;
	private static final int BLACK = 0xff000000;
	private static final int WHITE = 0xffffffff;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		activity = this;
	}
	
	//生成二維碼
	public static boolean createQRCode(String str, int widthAndHeight, String filePath) throws WriterException {//Bitmap String str,int widthAndHeight
		Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); 
		BitMatrix matrix = new MultiFormatWriter().encode(str,
				BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		int[] pixels = new int[width * height];
		
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (matrix.get(x, y)) {
					pixels[y * width + x] = BLACK;
				}else{
					pixels[y * width + x] = WHITE;
				}
			}
		}
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_8888);
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		saveBitmap(bitmap, filePath);
		return true;
	}
	
	//掃描二維碼
	public static void scanQRCode(final int luaFunctionId){
		luaFuncId = luaFunctionId;
		Intent intent = new Intent();
		intent.setClass(activity, CaptureActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		activity.startActivityForResult(intent, SCANNIN_GREQUEST_CODE);
	}
	
	//儲存圖片
	public static void saveBitmap(Bitmap bitmap, String filePath){
		File file = new File(filePath, "qrCode.png");
		if (file.exists()) {
			file.delete();
		}
		try {
			FileOutputStream out = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, 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();
		}
	}
	
	//二維碼掃描成功返回時處理
	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
		case SCANNIN_GREQUEST_CODE:
			if(resultCode == RESULT_OK){
				Bundle bundle = data.getExtras();
				String result = bundle.getString("result");
				Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFuncId, result);
				Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFuncId);
			}
			break;
		}
    }
}
------------8.2 若遇到R.xx.xx找不到或者報紅時,可能是layout中的佈局檔案xxx.xml有問題或者values中的xxx.xml有問題,請仔細檢查並更改。
------------8.3 enCoding->EncodingHandler.java這個類是生成二維碼的程式碼,我這裡將生成的程式碼放在了AppActivity.java中,所以就沒用到這個類。不需要的也可以將EncodingHandler.java刪除。

相關推薦

cocos2dx-lua在android實現生成掃描

首先說明下,生成二維碼是用android原生的BitMatrix和Bitmap類來生成的,而掃描二維碼用到了google官方的zxing包(core.jar)。 這裡我把所有生成二維碼的程式碼和lua呼叫的掃描二維碼方法都放在了專案->frameworks->

Ionic3 生成專案掃描

建立專案 ionic start devdacticQRCodes blank cd devdacticQRCodes // 安裝外掛 npm install ngx-qrcode2 --save

1分鐘快速實現高效的掃描,急速識別手機相簿

最近由於專案需求,需要在二維碼掃描時新增識別相簿內二維碼的功能,於是,遇到了許多問題在這裡總結,好為以後不在採坑。 1、二維碼識別速度慢,效率低 2、手機相簿內的二維碼識別速度慢,識別不出來 好了,主要問題就是這些。 下面直接上程式碼, 使用常規方法在掃描手機相簿二

Android生成掃描

現在高階大氣上檔次的Android程式都會有二維碼生成和掃描的功能, 因為我最近在做一個專案,需要使用到二維碼的生成和掃描,經過查詢資料,使用的是通過zxing來生成和掃描二維碼 簡化好的二維碼核心庫:https://download.csdn.net/download/qq_31844

JS 生成列印

1. 字串生成二維碼 HTML程式碼 <div class="qrcBody" id="qrcBody"> </div> js程式碼 jQuery('#qrcBody').qrcode({ width: 250,

使用Jquery.qrcode.jsLodop控制元件生成列印

<html> <head> <meta charset="utf-8"> <title>二維碼列印</title> <meta http-equiv="X-UA-Compatible" content="I

Android Zxing實現掃描條形碼功能仿微信整合閃光燈生成

最近在做android專案需要用到二維碼條形碼掃描功能,我用的是Eclipse網上原始碼大多是GitHup上的Android studio版本的所以我改了一版整合到專案中去。 效果圖: 左邊版本的掃碼框是自定義的。右邊版本的掃碼框和掃描線是圖片因為太醜所以最終換成左邊

實現手機掃描頁面登入,類似web微信-第二篇,關於的自動生成

接上一章,我們已經基本把業務邏輯分析清楚了 下面我們第一步,實現二維碼的web動態生成。 頁面的二維碼包含的資訊我在上一篇已經解釋過,是一個頁面的sessionID,這個sessionID主要是標示出哪個頁面是哪個頁面,例如你開啟N個頁面,必然每個頁面的標示會不一樣,只有你

方案優化:網站實現掃描關註微信公眾號,自動登陸網站並獲取其信息

用戶 class his onerror 就會 openid display 要點 rac 上一篇 《網站實現掃描二維碼關註微信公眾號,自動登陸網站並獲取其信息》 中已經實現用戶掃碼登陸網站並獲取其信息 但是上一篇方案中存在一個問題,也就是文章末尾指出的可以優化的地方(可

簡單的掃描吐司+生成

1.匯入依賴(build.gradle) implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.3.4' 2.MainActivity頁面 public class MainActivity extends AppCompat

生成掃描

導依賴 implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.3.4' 許可權 <uses-permission android:name="android.permission.CAMERA" /> <uses-pe

java 介面實現壓縮後的生成多張

pom的jar包: <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version&

掃描 生成

mainactivity.xml佈局 <?xml version="1.0" encoding="utf-8"?> <Button android:id="@+id/btnSan" android:layout_width="

掃描 生成

mainactivity.xml佈局 <?xml version="1.0" encoding="utf-8"?> <Button android:id="@+id/btnSan" android:layout_width="match_paren

在微信中,實現微信點擊鏈接或者掃描在瀏覽器中打開指定的鏈接

eba oid 體驗 直接 p s 營銷 商城 鏈接 app 這個問題我查看了許多資料,最後總結一下: 我首先看了IOS端微信關於下載app的整個邏輯: 關於公眾號裏面關於微官網裏面的app下載,如果你將你的應用中在微信開發平臺認證過來,這個是要掏錢的;你點微官網app的下

實現手機掃描進行登入

專案結構: 實現流程: pc端: 1:開啟二維碼登入網頁index.html 2:index.html呼叫GetQrCodeServlet 3:GetQrCodeServlet幹2件事   a:生成隨機的uuid,是一個唯一標識,該標識貫穿整個流

掃描研究總結(高仿微信掃一掃,輕鬆實現定製掃描介面)

在正文之前說點題外話,加上這篇我已經寫了3篇部落格了,其實我寫部落格的初衷不是想證明自己有多牛,並且我也只是從事安卓開發只有半年時間的小渣,但是不想成為大牛的渣不是好渣,所以我想通過部落格把工作學習中遇到的問題進行研究總結,從而提高自己,與此同時如果能給廣大從事

掃描登入實現原理分析

記得比較早使用手機掃碼登入是網頁版微信,這種免去輸入繁瑣的賬號密碼,拿起手機掃一掃就可以登入的方式一開始還是比較驚豔的。 那它是如何實現的呢?我們來簡單研究下。(以淘寶網二維碼登入為例) 首先,任何一個二維碼錶示的都是一串字串。 通過草料二維碼解析出這

微信點選連結或者掃描通過預設瀏覽器開啟指定連結是如何實現

微信上進行的網頁宣傳、遊戲傳播、APP下載各類活動很多,但是各位朋友肯定經常會遇到一些特殊需求,網頁需要在手機預設瀏覽器開啟而不是微信內建瀏覽器。這個問題怎麼解決呢?   解決方案:微信中開啟連結,自動開啟外部瀏覽器開啟頁面 微信中點選或開啟連結,自動開啟外部瀏覽器開啟指定頁面。全程完全自動化

Jquery掃描的簡單實現

二維碼:利用圖形模擬二進位制0、1的概念,達到儲存少量資料的功能,一般移動端瀏覽器解析出二維碼裡面隱藏的url資料會自動進行跳轉,常見的支付寶、微信掃描登陸就是利用該原理 Jquery二維碼