0
votes

Am I developing an Android app (in Embarcadero Delphi 10.3) that will use the HamLib library for controlling radios, etc. I've compiled the library (libhamlib.so) with the NDK, and works. I can use the library from the application created with Delphi, but only if using the network connection. (the library connects to another maching, running a server to control the radio)

The goal, however, is to control the radio directly from the Android app with an USB to serial adapter connected to the Android device.

The problem is permissions. I've looked with an rooted phone that /dev/ttyUSB0 is created when the USB serial adapter is inserted. But the permissions on the device is crw------- and owned by root. So the application does not have permission to use the device.

I've tried setting permissions in AndroidManifest.xml and also added Intents (so my app gets called when inserting the USB adapter)

I have also played with the UsbManager and it says the app has permissions. The UsbManager reports the device as /dev/bus/usb/001/001 though, so something is not right. If i tell the library to use /dev/bus/usb/001/001 it fails aswell. And the /dev/bus/usb/001/001 is not the same major minor character device as /dev/ttyUSB0

Anyone out there with experience with Android and serial ports, and of course using the serial port from a shared library?

2
If I do the following as root on the phone chmod 777 /dev/ttyUSB0 setenforce 0 (setting permissions so everyone can read/write) and setting SELinux to permissive Then the applicion works. This shows it's clearly a permission problem. My app need permissions to /dev/ttyUSB0 (or some other path/device) to the USB serial adapter. This is not a solutions since the application needs to work on unrooted devicesJörgen Overgaard

2 Answers

1
votes

You could try using usb-serial-for-android library, compile it into a .jar file and add this to your Delphi project.

0
votes

I use the Comport for Android USB Serial library from Winsoft, and as you can see from this page https://www.winsoft.sk/acpusbser.htm, it has build in functions to obtain permission from the user to use the comport. I'm pasting is some code from 1 of my projects to give you an idea of how Winsoft library requires this to be handled.

procedure TfrmLiveMain.RefreshDevices;
var
  i: Integer;
  IDString: String;
  Device: JUsbDevice;
begin

  UsbDevices := UsbSerial.UsbDevices;
  if UsbDevices = nil then
    EXIT;

  if Length(UsbDevices) = 0 then
  begin
    Sound(50);
    Vibrate(25);
    FToast.MakeToast('No USB serial devices were found!');
    EXIT;
  end;

  for i := 0 to 1 {Length(UsbDevices)} - 1 do
  begin
    Device := UsbDevices[i];
    if TJBuild_VERSION.JavaClass.SDK_INT >= 21 then
      IDString := JStringToString(Device.getManufacturerName) + ' ' +
        JStringToString(Device.getProductName)
    else
      IDString := JStringToString(Device.getDeviceName);
  end;

  if not UsbSerial.IsSupported(Device) then
    raise Exception.Create(IDString + ' is not a supported device!');

  // give them 2 chances to grant permission
  if not UsbSerial.HasPermission(Device) then
  begin
    UsbSerial.RequestPermission(Device);
    if not UsbSerial.HasPermission(Device) then
    begin
      PermTimer.Enabled := True; // begin permission loop ->
      EXIT;
    end;
  end;

procedure TfrmLiveMain.PermTimerTimer(Sender: TObject);
var
  Device: JUsbDevice;
begin
  PermTimer.Enabled := False;
  Device := UsbDevices[0];
  if UsbSerial.HasPermission(Device) then
    RefreshDevices; // and try open ->
end;

Now of course, I can't say if this is what you need for the Hamlib library, so this is an extended comment, and not really an answer.