我最近得到了Android条形码扫描仪设备。我想在Delphi 10 Seattle中编写一个小型库存多设备应用程序。扫描仪有两种模式设置可以返回扫描条形码,第一种模式只是将条形码传递给聚焦编辑控制,第二种模式是广播模式。因为Delphi仍然有一些编辑控件的怪癖,这些控件在Android环境中与虚拟键盘串联不能正常工作,我必须使用广播模式。在网络上,我发现手册中几乎没有任何有用的信息,控制设备的API和用eclipse编写的android演示应用程序 我能够获得Delphi的API包装器并成功控制设备,更改参数,打开扫描仪等。 然而,如果不能理解android意图和广播的工作原理,我无法成功实现它。 我确实为Delphi http://docwiki.embarcadero.com/CodeExamples/Seattle/en/FMX.Android_Intents_Sample研究了意图样本 .Did运行Android意图示例应用程序,它确实工作。 Eclipse android演示项目工作正常,编译并运行它没有问题。困境现在是如何在Delphi中接收广播意图。我在这里工作eclipse演示有manifest.xml和mainactivity代码......
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testscan"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.testscan.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Mainactivity:
package com.example.testscan;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.device.ScanDevice;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
public class MainActivity extends Activity {
ScanDevice sm;
private final static String SCAN_ACTION = "scan.rcv.message";
private String barcodeStr;
private EditText showScanResult;
private BroadcastReceiver mScanReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
byte[] barocode = intent.getByteArrayExtra("barocode");
int barocodelen = intent.getIntExtra("length", 0);
byte temp = intent.getByteExtra("barcodeType", (byte) 0);
android.util.Log.i("debug", "----codetype--" + temp);
barcodeStr = new String(barocode, 0, barocodelen);
showScanResult.append("tere");
showScanResult.append(barcodeStr);
showScanResult.append("\n");
// showScanResult.setText(barcodeStr);
sm.stopScan();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sm = new ScanDevice();
CheckBox ch = (CheckBox) findViewById(R.id.checkBox1);
if(sm.getOutScanMode()==1){
ch.setChecked(true);
}else{
ch.setChecked(false);
}
ch.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
// TODO Auto-generated method stub
if(arg1){
sm.setOutScanMode(1);
}else{
sm.setOutScanMode(0);
}
}});
showScanResult=(EditText) findViewById(R.id.editText1);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.openScanner:
System.out.println("openScanner = "+sm.getOutScanMode());
sm.openScan();
break;
case R.id.closeScanner:
sm.closeScan();
break;
case R.id.startDecode:
sm.startScan();
break;
case R.id.stopDecode:
sm.stopScan();
break;
case R.id.start_continue:
sm.setScanLaserMode(4);
break;
case R.id.stop_continue:
sm.setScanLaserMode(8);
break;
case R.id.close:
finish();
break;
default:
break;
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(sm != null) {
sm.stopScan();
}
unregisterReceiver(mScanReceiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(SCAN_ACTION);
registerReceiver(mScanReceiver, filter);
}
}
编辑:2017-04-24
我找到了一位日本博客写了一篇关于使用Delphi 10 Seattle和更新版本http://www.gesource.jp/weblog/?p=7269创建简单广播接收器的文章。我后来发现,在@alitrun提到的一个消息来源评论中提到了这一点。 因此,要在广播模式下使用扫描仪,您需要U8000S_ScanSDK.pas jar包装器来访问和控制设备。它需要在广播模式中设置扫描仪应用程序。然后你需要创建BroadcastReceiverListener类......
上面提到的Android应用程序的简单端口在这里:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
FMX.Dialogs,
FMX.Controls.Presentation, FMX.Edit,
Androidapi.JNIBridge, Androidapi.JNI.Embarcadero,
Androidapi.JNI.GraphicsContentViewText,
U8000S_ScanSDK; { U8000S_ScanSDK.jar wrapper }
type
TMyReceiver = class(TJavaLocal, JFMXBroadcastReceiverListener)
public
constructor Create;
procedure onReceive(context: JContext; intent: JIntent); cdecl;
end;
TForm1 = class(TForm)
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FMyListener: TMyReceiver;
FBroadcastReceiver: JFMXBroadcastReceiver;
ScanDevice: JScanDevice; { U8000S_ScanSDK.jar api device interface }
procedure managebarcodescan(barcode: string);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Androidapi.Helpers,
Androidapi.JNI.JavaTypes;
{$R *.fmx}
function HexToString(H: String): String;
var
I: Integer;
begin
Result := '';
for I := 1 to length(H) div 2 do
Result := Result + Char(StrToInt('$' + Copy(H, (I - 1) * 2 + 1, 2)));
end;
constructor TMyReceiver.Create;
begin
inherited;
end;
procedure TMyReceiver.onReceive(context: JContext; intent: JIntent);
var
barocode: tjavaarray<System.byte>;
len: Integer;
buffer: string;
I: Integer;
begin
if JStringToString(intent.getAction) = 'scan.rcv.message' then
begin
len := intent.getIntExtra(StringToJString('length'), 0);
barocode := intent.getByteArrayExtra(StringToJString('barocode'));
for I := 0 to len - 1 do
begin
buffer := buffer + inttohex(barocode[I], 2);
end;
buffer := HexToString(buffer);
barocode.Free;
// do something with result
Form1.managebarcodescan(buffer);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Filter: JIntentFilter;
begin
FMyListener := TMyReceiver.Create;
FBroadcastReceiver := TJFMXBroadcastReceiver.JavaClass.init(FMyListener);
Filter := TJIntentFilter.JavaClass.init;
Filter.addAction(StringToJString('scan.rcv.message'));
TAndroidHelper.context.getApplicationContext.registerReceiver(FBroadcastReceiver, Filter);
ScanDevice := TJScanDevice.Create; {creating scanner interface}
ScanDevice.setScanCodeEnterKey;
ScanDevice.setOutScanMode(0); {setting scanner to broadcast mode }
ScanDevice.openScan;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
TAndroidHelper.context.getApplicationContext.unregisterReceiver(FBroadcastReceiver);
ScanDevice.stopScan;
ScanDevice._Release;
end;
procedure TForm1.managebarcodescan(barcode: string);
begin
Edit1.Text := barcode;
end;
end.