我的Delphi XE7项目需要与FTDI FT311 Android Accessory Chip进行通信。他们有助于提供包含他们的JAVA驱动程序FT311I2CInterface.java
的Android演示(在本文后面会有所介绍)。假设我需要将此文件转换为OP,我按照using the Java2OP.exe command line tool的说明进行必要的路径添加以指向JDK(似乎由XE7安装)SET PATH=%PATH%;C:\Program Files\Java\jdk1.7.0_25\bin
将所有内容放在同一个文件夹中,我运行了以下工具:
java2op.exe -unit FT311I2CInterface.java
未收到任何错误并获得了输出文件FT311I2CInterface.java.pas
。但是,此输出文件中有一个空类,如下所示:
{*******************************************************}
{ }
{ CodeGear Delphi Runtime Library }
{ Copyright(c) 2014 Embarcadero Technologies, Inc. }
{ }
{*******************************************************}
unit FT311I2CInterface.java;
interface
uses
Androidapi.JNIBridge;
type
// ===== Forward declarations =====
// ===== Interface declarations =====
implementation
procedure RegisterTypes;
begin
end;
initialization
RegisterTypes;
end.
有人可以建议我做错了吗?
提供的原始JAVA文件如下:
//User must modify the below package with their package name
package com.I2CDemo;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
/******************************FT311 GPIO interface class******************************************/
public class FT311I2CInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.I2CDemo.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = false;
public boolean READ_ENABLE = true;
public boolean accessory_attached = false;
public handler_thread handlerThread;
private byte [] usbdata;
private byte [] writeusbdata;
private int readcount;
private byte status;
private byte maxnumbytes = 60;
public boolean datareceived = false;
public Context global_context;
public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString = "mModel=FTDII2CDemo";
public static String VersionString = "mVersion=1.0";
/*constructor*/
public FT311I2CInterface(Context context){
super();
global_context = context;
/*shall we start a thread here or what*/
usbdata = new byte[64];
writeusbdata = new byte[64];
/***********************USB handling******************************************/
usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// Log.d("LED", "usbmanager" +usbmanager);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
inputstream = null;
outputstream = null;
}
/*reset method*/
public void Reset()
{
/*create the packet*/
writeusbdata[0] = 0x34;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*SetFrequency*/
public void SetFrequency(byte freq)
{
/*check for maximum and minimum freq*/
if(freq > 92)
freq = 92;
if (freq < 23)
freq = 23;
/*create the packet*/
writeusbdata[0] = 0x31;
switch(freq)
{
case 23:
writeusbdata[1] = 10;
break;
case 44:
writeusbdata[1] = 21;
break;
case 60:
writeusbdata[1] = 30;
break;
default:
writeusbdata[1] = 56;
break;
}
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
writeusbdata[4] = 0x00;
/*send the packet over the USB*/
SendPacket(5);
}
/*write data*/
public byte WriteData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] buffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*
* if num bytes are more than maximum limit
*/
if(numBytes < 1){
actualNumBytes[0] = (byte)0x00;
/*return the status with the error in the command*/
return status;
}
/*check for maximum limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[4+count] = (byte)buffer[count];
}
/*prepare the usbpacket*/
writeusbdata[0] = 0x32;
writeusbdata[1] = i2cDeviceAddress;
writeusbdata[2] = transferOptions;
writeusbdata[3] = numBytes;
SendPacket((int)(numBytes+4));
datareceived = false;
/*wait while the data is received*/
/*FIXME, may be create a thread to wait on , but any
* way has to wait in while loop
*/
while(true){
if(datareceived == true){
break;
}
}
/*by default it error*/
status = 0x01;
/*check for the received data*/
if(usbdata[0] == 0x32)
{
/*check for return error status*/
status = usbdata[1];
/*updated the written bytes*/
actualNumBytes[0] = usbdata[3];
}
datareceived = false;
return status;
}
/*read data*/
public byte ReadData(byte i2cDeviceAddress,byte transferOptions,
byte numBytes, byte[] readBuffer,
byte [] actualNumBytes)
{
status = 0x01; /*error by default*/
/*should be at least one byte to read*/
if(numBytes < 1){
return status;
}
/*check for max limit*/
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
/*prepare the packet to send this command*/
writeusbdata[0] = 0x33; /*read data command*/
writeusbdata[1] = i2cDeviceAddress; /*device address*/
writeusbdata[2] = transferOptions; /*transfer options*/
writeusbdata[3] = numBytes; /*number of bytes*/
/*send the data on USB bus*/
SendPacket(4);
datareceived = false;
/*wait for data to arrive*/
while(true)
{
if(datareceived == true){
break;
}
}
/*check the received data*/
if(usbdata[0] == 0x33)
{
/*check the return status*/
status = usbdata[1];
/*check the received data length*/
numBytes = usbdata[3];
if(numBytes > maxnumbytes){
numBytes = maxnumbytes;
}
for(int count = 0; count<numBytes;count++)
{
readBuffer[count] = usbdata[4+count];
}
/*update the actual number of bytes*/
actualNumBytes[0] = numBytes;
datareceived = false;
}
return status;
}
/*method to send on USB*/
private void SendPacket(int numBytes)
{
try {
if(outputstream != null){
outputstream.write(writeusbdata, 0,numBytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
if(accessories != null)
{
Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
}
else
{
accessory_attached = false;
return;
}
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if( -1 == accessory.toString().indexOf(ManufacturerString))
{
Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(ModelString))
{
Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(VersionString))
{
Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
accessory_attached = true;
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
global_context.unregisterReceiver(mUsbReceiver);
if(accessory_attached == true)
{
READ_ENABLE = false;
byte i2cDeviceAddress = 1;
byte transferOptions = bOption.START_BIT;
byte numBytes = 2;
byte [] actualNumBytes = new byte[1];
byte [] readBuffer = new byte[60];
//byte deviceAddress = 1;
readBuffer[0] = 1;
ReadData(i2cDeviceAddress,transferOptions,
numBytes, readBuffer,
actualNumBytes);
try{Thread.sleep(10);}
catch(Exception e){}
}
CloseAccessory();
}
/*********************helper routines*************************************************/
public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
usbaccessory = accessory;
FileDescriptor fd = filedescriptor.getFileDescriptor();
inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
return;
}
}
handlerThread = new handler_thread(inputstream);
handlerThread.start();
}
private void CloseAccessory()
{
try{
if(filedescriptor != null)
filedescriptor.close();
}catch (IOException e){}
try {
if(inputstream != null)
inputstream.close();
} catch(IOException e){}
try {
if(outputstream != null)
outputstream.close();
}catch(IOException e){}
/*FIXME, add the notfication also to close the application*/
filedescriptor = null;
inputstream = null;
outputstream = null;
System.exit(0);
}
/***********USB broadcast receiver*******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
CloseAccessory();
}else
{
Log.d("LED", "....");
}
}
};
/*usb input data handler*/
private class handler_thread extends Thread {
FileInputStream instream;
handler_thread(FileInputStream stream ){
instream = stream;
}
public void run()
{
while(READ_ENABLE == true)
{
try
{
/*dont overwrite the previous buffer*/
if((instream != null) && (datareceived==false))
{
readcount = instream.read(usbdata,0,64);
if(readcount > 0)
{
datareceived = true;
/*send only when you find something*/
}
}
}catch (IOException e){}
}
}
}
}
答案 0 :(得分:2)
我是Android的初学者,我也尝试连接FT311。 我将与Java2OP分享我的经验,但我还不能在Delphi XE7中获得usbAccessory
UsbManager := TJUsbManager.Wrap(SharedActivityContext.getSystemService(TJContext.JavaClass.USB_SERVICE));
AccessoryList := UsbManager.getAccessoryList();
if ( AccessoryList <> nil ) then begin
if ( AccessoryList.Length > 0 ) then begin
Accessory := AccessoryList.Items[0]; <<<<<<< raise an illegal instruction , access violation..
end;
end;
我在使用java2op时遇到了很多麻烦,但以下是我遵循的步骤谷歌搜索后(抱歉,我不记得网址)
使用包含所需类的eclipse ADT创建一个.jar文件(我使用FTDI提供的FT31演示项目中的FT311GPIOInterface.java)。这并不容易,因为你必须将演示应用程序拆分为一个&#34; android项目库&#34; (将生成.jar的那个)和一个&#34; android项目&#34;演示应用程序的UI。构建和运行演示应用程序时(而不是在构建android项目库时)构建.jar。 如果要使用UI应用程序测试.jar,则必须将.jar复制到目录Libs中的UI应用程序中,然后将其部署到Android设备上 我是eclipse的新手,可能有更好的方法,但是...... 我看到了生成.jar文件的其他方法
Java2op:它适用于干净的XP窗口:我使用虚拟机,没有安装delphi XE,安装了java jdk1.7.0_25,安装了java2op,没有安装android SDK。
my jar is ft311lib.jar java2op -jar ft311lib.jar -unit com.poco.ft311lib
这产生了com.poco.ft311lib.pas
希望这个帮助
答案 1 :(得分:1)
Java2OP.exe ...是一个命令行工具 可以用来从Java库生成Delphi本机桥文件 (JAR或类文件)。
我建议您检查一下您是否正确使用了该工具:
java2op.exe -unit FT311I2CInterface.java
根据文档,-unit指定File name of the output unit
,而不是输入文件。它还说
您必须至少指定一个指示内容的输入选项 您希望包含在输出Delphi本机桥文件中的内容。
尝试改为:
java2op.exe -source .
答案 2 :(得分:1)
根据关于此命令行工具的linked documentation,我将执行以下操作:
src/
文件夹并将FT311I2CInterface.java
放入其中。使用这些参数运行java2op.exe
:
java2op.exe -source src/ -unit Android.JNI.FT311I2C
预期产出:
Android.JNI.FT311I2C.pas
-unit
arg指定输出。
-source
arg指定输入(在您的情况下,您需要一个java源文件)