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下载地址

http://download.csdn.net/download/aa1000777/8996127

------------1.2下载后放在libs中

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

-----2.下载扫描二维码相关类及代码

------------2.1下载地址

http://download.csdn.net/detail/bear_huangzhen/8747969

------------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.2 lua调用 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;
		}
    }
其中 public static AppActivity activity ;其中为调用扫描界面时需要的参数,其值在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类的 public void 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类中 public void 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删除。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值