打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
(7)[转载]delphi for android 条码扫描初步解决方案

现在微信、淘宝在各自的终端平台上都推出了扫一扫的功能,一维码、二维码的图像识别技术技术得到了迅猛的推广,在我们日常生活中,这种技术也早已经渗透到方方面面,google的zxing 就是一个不错的条码图像识别库,delphi xe5推出后,你也想将这项技术应用到实际的工作中吗?希望这篇文章能够帮助到你;

1. 使用delphi 建立FireMonkey Mobile Application 选择空工程,命名为BarCodeScan ,保存后放着;

2. 下载并安装zxing到你的手机上

https://play.google.com/store/apps/details?id=com.google.zxing.client.android

3. 下载dex2jar

https://code.google.com/p/dex2jar/

将dex2jar解压,将delphi firemonkey原始的classes.dex文件拷贝到解压后的目录中(我的原始classes.dex 路径在D:ProgramFilesEmbarcaderoRADStudio12.0libandroiddebugclasses.dex,大家按照自己的路径找找把)

4. 检查下jdk配置,建议使用jdk1.6

5. 使用命令行工具进入dex2jar 解压后的目录,运行以下命令

l 将dex还原成jar包: d2j-dex2jar.bat classes.dex

l 释放到文件目录: jar xf classes-dex2jar.jarcom/embarcadero/firemonkey

l 重新打包: jar cf embarcadero.jar com

现在在当前目录下存在embarcadero.jar 这个jar包了,将此jar包拷贝到 DelphiBarCodeScan工程目录中;

6. 打开eclipse建立android application project项目,引用embarcadero.jar

新建java类NativeActivityExt,继承com.embarcadero.firemonkey.FMXNativeActivity,在这个类中将提供delphi能够使用的jni本地调用。

代码如下:

package com.cikk.barcode;

import android.content.Intent;

import com.embarcadero.firemonkey.FMXNativeActivity;

public class NativeActivityExt extendsFMXNativeActivity {

//供 xe5 for android 获取返回值使用

public native booleanonActivityResultNative(int requestCode, intresultCode, Intent data);

@Override

protected void onActivityResult(intrequestCode, int resultCode, Intent data) {

if (!onActivityResultNative(requestCode, resultCode,data))

super.onActivityResult(requestCode, resultCode,data);

}

}

保存下,将src目录下的所有文件拷贝到Delphi BarCodeScan工程目录中,见步骤5附图;

7. 编写Build.bat 批处理文件,内容如下

@echo off

setlocal

set ANDROID_PLATFORM="%ANDROID%platforms

android-10"

setDX_LIB="%ANDROID%build-tools19.0.0lib"

set PROJ_DIR="?%"

set EMBO_DEX="D:ProgramFilesEmbarcaderoRAD

Studio12.0libandroiddebugclasses.dex"

set VERBOSE=0

mkdir outputclasses 2> nul

mkdir outputjar 2> nul

mkdir outputdex 2> nul

echo.

echo 编译 NativeActivityExt.java 源文件

echo.

SET VERBOSE_FLAG=-verbose

javac %VERBOSE_FLAG% -Xlint:deprecation -cp

%ANDROID_PLATFORM%android.jar;embarcadero.jar -d

outputclasses srccomcikkbarcode

NativeActivityExt.java

echo.

echo 创建jar包

echo.

SET VERBOSE_FLAG=v

jar c%VERBOSE_FLAG%f outputjarnew_classes.jar

-C outputclasses com

echo.

echo 转换为dex格式

echo.

SET VERBOSE_FLAG=--verbose

call dx --dex %VERBOSE_FLAG% --output=%PROJ_DIR%

outputdexnew_classes.dex --positions=lines

%PROJ_DIR%outputjarnew_classes.jar

echo.

echo 合并dex 文件

echo.

java -cp %DX_LIB%dx.jar

com.android.dx.merge.DexMerger %PROJ_DIR%output

dexclasses.dex %PROJ_DIR%outputdex

new_classes.dex %EMBO_DEX%

echo 删除临时文件

echo.

del outputdexnew_classes.dex

del outputjarnew_classes.jar

rmdir outputjar

:Exit

Endlocal

确保build.bat 中各变量设置是否正确,如何设置可以参考我的另一篇文章《Delphi XE5 for Android启动无黑屏等待总结》

8. 运行Build.bat,成功后在outputdex 中可以获得我们需要的classes.dex文件(我尝试使用eclipse直接编译来获取classes.dex文件,但delphi调用失败)

9. 回到Delphi XE5,我们将SplashScreen 工程Build一次,然后点击Project->Deployment 进入发布管理模块

确保缺省的classes.dex未被选中,点击Add Files选择通过build生成的classes.dex,添加成功后选中新增项,点击Change RemotePath,更改发布后的路径

保存;

打开AndroidManifest.template.xml,做相应修改

调整activity配置

<activityandroid:name="com.embarcadero.firemonkey.FMXNativeActivity"

android:label="?tivityLabel%"

android:configChanges="orientation|keyboardHidden">

<meta-dataandroid:name="android.app.lib_name"

android:value="%libNameValue%"/>

<intent-filter>

<actionandroid:name="android.intent.action.MAIN"/>

<categoryandroid:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

<activityandroid:name="com.cikk.barcode.NativeActivityExt"

android:label="?tivityLabel%"

android:configChanges="orientation|keyboardHidden"

android:screenOrientation="portrait">

<!-- Tell NativeActivity the name of our .so-->

<meta-dataandroid:name="android.app.lib_name"

android:value="%libNameValue%"/>

<intent-filter>

<actionandroid:name="android.intent.action.MAIN"/>

<categoryandroid:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

保存;

新建FireMonkey mobile form ,设置下界面

F12编写调用zxing的代码

unit frmMain;

interface

uses

System.SysUtils,

System.Types,

System.UITypes,

System.Classes,

System.Variants,

FMX.Types,

FMX.Controls,

FMX.Forms,

FMX.Graphics,

FMX.Dialogs,

FMX.Edit,

FMX.StdCtrls,

Androidapi.JNI.GraphicsContentViewText;

type

TMainForm = class(TForm)

Label1: TLabel;

Button1: TButton;

edtScanFormat: TEdit;

edtScanCode: TEdit;

procedure Button1Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

private

const ScanRequestCode = 0;

procedure RegisterDelphiNativeMethods;

function OnActivityResult(RequestCode, ResultCode: Integer;Data: JIntent): Boolean;

{ Private declarations }

public

{ Public declarations }

end;

var

MainForm: TMainForm;

implementation

uses Posix.pthread,

Androidapi.JNI.JavaTypes,FMX.Helpers.Android,

Androidapi.JNI,

Androidapi.JNI.App,

Androidapi.JNIBridge,

Androidapi.NativeActivity;

var

ARNRequestCode, ARNResultCode: Integer;

ARNData: JIntent;

ARNResult: Boolean;

{$R *.fmx}

procedure OnActivityResultThreadSwitcher;

begin

ARNResult := MainForm.OnActivityResult(ARNRequestCode,ARNResultCode, ARNData);

end;

function OnActivityResultNative(PEnv: PJNIEnv; This:JNIObject;

RequestCode, ResultCode: Integer; dataIntent: JNIObject):Boolean; cdecl;

begin

ARNRequestCode := requestCode;

ARNResultCode := resultCode;

ARNData := nil;

if Assigned(DataIntent) then

ARNData := TJIntent.Wrap(DataIntent);

TThread.Synchronize(nil, OnActivityResultThreadSwitcher);

Result := ARNResult;

end;

procedure TMainForm.Button1Click(Sender: TObject);

var

Intent: JIntent;

ResolveInfo: JResolveInfo;

begin

Intent :=TJIntent.JavaClass.init(StringToJString('com.google.zxing.client.android.SCAN'));

Intent.setPackage(StringToJString('com.google.zxing.client.android'));

ResolveInfo :=SharedActivity.getPackageManager.resolveActivity(Intent, 0);

SharedActivity.startActivityForResult(Intent, 0);

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

RegisterDelphiNativeMethods;

end;

function TMainForm.OnActivityResult(RequestCode, ResultCode:Integer;

Data: JIntent): Boolean;

var

ScanContent,

ScanFormat: string;

begin

Result := False;

if RequestCode = ScanRequestCode then

begin

if ResultCode = TJActivity.JavaClass.RESULT_OK then

begin

if Assigned(Data) then

begin

ScanContent :=JStringToString(Data.getStringExtra(StringToJString('SCAN_RESULT')));

ScanFormat :=JStringToString(Data.getStringExtra(StringToJString('SCAN_RESULT_FORMAT')));

Self.edtScanFormat.Text := ScanFormat;

Self.edtScanCode.Text := ScanContent;

Result := True;

end;

end;

end;

end;

procedure TMainForm.RegisterDelphiNativeMethods;

var

PEnv: PJNIEnv;

ActivityClass: JNIClass;

NativeMethods: array[0..1] of JNINativeMethod;

begin

PEnv := TJNIResolver.GetJNIEnv;

NativeMethods[0].Name := 'onActivityResultNative';

NativeMethods[0].Signature :='(IILandroid/content/Intent;)Z';

NativeMethods[0].FnPtr := @OnActivityResultNative;

ActivityClass := PEnv^.GetObjectClass(

PEnv, PANativeActivity(System.DelphiActivity).clazz);

PEnv^.RegisterNatives(PEnv, ActivityClass, @NativeMethods[0],1);

PEnv^.DeleteLocalRef(PEnv, ActivityClass);

end;

end.

保存,调试运行把,是不是可以正常扫描及成功返回结果值了;

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Delphi 10.1.2解决Android平台下TEdit光标移动错误的问题
Android - 反编译android apk文件
艰辛的Delphi 11.1 Android项目升级之路(成功升级的注意事项)
Delphi Android 将Google ZXing 整合(调用Jar文件)
Android 篡改apk文件的可行性分析
android混淆(Obfuscate)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服