您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx-lua在android上实现生成及扫描二维码

2017-03-02 16:22 489 查看
首先说明下,生成二维码是用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.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删除。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息