如何从此JAVA文件中提取Delphi类以用于Android?

时间:2014-11-20 11:58:28

标签: java android delphi

我的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){}
                }
            }
        }



    }

3 个答案:

答案 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时遇到了很多麻烦,但以下是我遵循的步骤谷歌搜索后(抱歉,我不记得网址)

  1. 使用包含所需类的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文件的其他方法

  2. ,请参阅brian长网站了解其他方式
  3. Java2op:它适用于干净的XP窗口:我使用虚拟机,没有安装delphi XE,安装了java jdk1.7.0_25,安装了java2op,没有安装android SDK。

  4. 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源文件)