I want to create a channel to receive push notifications from Firebase on Android.
I added in project/options/application/Services/Default notifications channel id "MyChannel" and implemented the code below that I found in this question
Delphi 10.4.2 FMX How to make a head up notification? to-make-a-head-up-notification/70517137#70517137.
For testing I'm using a device with android 8.1.0, API 26, notifications are normally received by the device, but when I run the code the app crashes (freezes the screen).
what can be wrong?
procedure TForm1.SetupNotificationChannel;
var
LChannel: TChannel;
begin
LChannel := NotificationCenter.CreateChannel;
try
LChannel.Id := 'MyChannel';
LChannel.Title := LChannel.Id;
LChannel.Importance := TImportance.High;
NotificationCenter.CreateOrUpdateChannel(LChannel);
finally
LChannel.Free;
end;
end;
Related
I have a common problem on Android only that I don't know how to reproduce on demand. It happens on Android 7, 9 and 11. Internet permission is enable and accepted on the app.
When we open the application, a call to my server is done.
function TXXVersion.GetVersion : IXXVersion;
var
LVSPortType : VersionServicePortType; // generate from wsdl
LIdURI: TIdURI;
begin
Result := nil;
if Assigned(FWebServiceHelper.PrepareCall(VersionServicePortType, LVSPortType, false)) then
begin
LIdURI := TIdURI.Create('https://my-backend.test.com');
try
Result := ParseVersion(LVSPortType.GetVersion, LIdURI.Host);
finally
LIdURI.Free;
end;
end;
end;
I got the system error message :
An unexpected error (EIdResolveError) occurred with message:
Error resolving Address my-backend.test.com:
No address associated with hostname (7)
If I try
to ping my-backend.test.com or access with a webbrowser it's ok
try several times I'll end up with a EIdConnectTimeout
If I reboot my phone, it works until 2-3 days and then I will get this error again.
I never got this problem on other plateform, that's only on Android. I see nothing other with adb.
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?
You could try using usb-serial-for-android library, compile it into a .jar file and add this to your Delphi project.
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.
Thanks to the help of many Stackoverflow contributors, I have successfully completed my Windows VCL project to, ping a number of IP Addresses, add them to an SQLtable, sort them by ping time and automatically set the IpV4 DNS settings to the fastest 2 addresses. This works perfectly under Windows.
I am now trying to create a similar application running under Android. I am using idIcmpclient to ping the addreses and pick up the IdICMPClient1.ReplyStatus.MsRoundTripTime. The code compiles and installs on my Android test device(s). However when run under Android, I receive a Socket #1 error. The testing code is below.
procedure TForm1.Button1Click(Sender: TObject);
var
ipAddr: string;
begin
ipAddr := '188.132.234.170';
IdIcmpClient1.ReceiveTimeout := 200;
IdIcmpClient1.Host := ipAddr;
IdIcmpClient1.ping();
if IdIcmpClient1.ReplyStatus.ReplyStatusType = rsEcho then
begin
Memo1.Lines.Add(IntToStr(IdIcmpClient1.ReplyStatus.MsRoundTripTime));
Memo1.Lines.Add(IdIcmpClient1.ReplyStatus.Msg)
end
else if IdIcmpClient1.ReplyStatus.ReplyStatusType = rsTimeout then
begin
// have a timeout, link is down
end
else
begin
// do something else
end;
end;
I have looked to see if there are peculiarities with IdIcmpclient and other OS's and have found out that it does not work with iOS , something to do with Raw Sockets.
I am assuming that maybe the same case applies to Android, which leaves me with a bit of a problem and possibly an untimely end to my new Android project.
If IdIcmpClient.Ping does not work under Android, is there an alternative method to Ping addresses and get the return times.
Any help much appreciated
I've created a test application with Bluetooth Low Energy (BLE) to perform pooling on the BLE device every 500ms, sending request and receiving response. The BLE device has a "Characteristic" with "Read, Write and Notify Descriptors". After signing in to BLE, an Subscribe is executed on that "Characteristic" via CurrentBLEDevice.SetCharacteristicNotification. The value of "Characteristic" is read in the CurrentBLEDevice.OnCharacteristicRead event (where OnCharacteristicRead = DidCharacteristicRead). Everything works fine until the CurrentBLEDevice.OnCharacteristicRead event stops responding for no reason. (Delphi 10.2.1, Android 5.0).
I have not been able to simulate the error yet and would like to know if there is any test I can do to simulate or fix error.
procedure DidCharacteristicRead(const Sender: TObject;
const ACharacteristic: TBluetoothGattCharacteristic;
AGattStatus: TBluetoothGattStatus);
var FCharactValueGet: TBytes;
begin
if AGattStatus <> TBluetoothGattStatus.Success then Exit;
FCharactValueGet:= [];
FCharactValueGet := ACharacteristic.Value;
end;
I am using Delphi's tethering to connect a FMX Android app to a VCL desktop app.
When the user closes the Android app on their phone, I would like the desktop to show that it is no longer tethered.
I am using the following:
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
begin
for I := TetheringManager1.PairedManagers.Count - 1 downto 0 do
TetheringManager1.UnPairManager(TetheringManager1.PairedManagers[I]);
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
TetheringAppProfile1.Enabled:=False;
TetheringManager1.Enabled:=False;
end;
This works perfectly, as long as the user closes the Android app using the back button. If you go to the open app list and close the app from there, then nothing fires off at all.
Have tried FormClose, FormDestroy, FormDeactivate none of the events seem to fire.
Delphi 10 Berlin
Android 6.0.1