Jump to content

Dave Nottage

Members
  • Content Count

    1331
  • Joined

  • Last visited

  • Days Won

    29

Posts posted by Dave Nottage


  1. 12 hours ago, Kas Ob. said:

    The question is : Is there right way to handle this ? 

    This is one way:

    if TOSVersion.Check(21) then
    begin
      // Do the TELECOM_SERVICE stuff
    end;

    TELECOM_SERVICE was introduced in API level 21. Another way is:

    if TJBuild_VERSION.JavaClass.SDK_INT >= 21 then
    begin
      // Do the TELECOM_SERVICE stuff
    end;

     


  2. 12 hours ago, Keda said:

    However, I hit a snag... I can't find information online on about how can I save progress and use leaderboards using google play services.

    On Unity it was pretty easy, but like I have said, I can't stand C# and Unity its not human friendly. At least not to my taste.

    Unless someone has done it already, I expect you're going to need to spend a fair amount of time on it.

     

    This is a starting point for the leaderboard/game saving parts: 

     

    https://developers.google.com/games/services/android/leaderboards

     

    It would be a case of:

    • Reading the documentation, and working out which parts you want to implement
    • Working out which packages the relevant classes are in
    • Doing imports of those classes into Delphi code
    • Working out whether there are any classes you need to create descendants for, and writing the appropriate Java and associated Delphi code for them
    • Implementing the various parts in Delphi

    Alternatively, you could implement a large portion of it in Java, create a .jar that Delphi would use and import the relevant parts into Delphi code.

     

    I note that it requires Google Sign-in, so for that part you might want to take a look at this: 

    https://github.com/grijjy/DelphiGoogleSignIn

     

    Which is related to Firebase, however the Google Sign-In parts would be relevant.

    • Like 1

  3. 3 hours ago, Maher Tannous said:

    But the problem is how to call : getCallCapablePhoneAccounts

    There's an import for TelecomManager, here:

     

    https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.TelecomManager.pas

     

    Be aware that Java2Pas (which was used for the import) sometimes puts instance methods where the class methods are, so they should be removed from there in the import.

     

    getCallCapablePhoneAccounts is an instance method that returns a JList, containing instances of JPhoneAccountHandle, so one way to access them is to do this:

     

    var
      LService: JObject;
      LAccounts: JList;
      LPhoneAccountHandle: JPhoneAccountHandle;
      I: Integer;
    begin
      Result := False;
      LService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELECOM_SERVICE);
      LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService)).getCallCapablePhoneAccounts;
      for I := 0 to LAccounts.size - 1 do
      begin
        LPhoneAccountHandle := TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID(LAccounts.get(I)));
        // Do whatever with the LPhoneAccountHandle here
      end;
    end;

    An import for PhoneAccountHandle is here:

     

    https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.PhoneAccountHandle.pas

     

    Note that getCallCapablePhoneAccounts was introduced in API level 23.


  4. 16 hours ago, Sherlock said:

    And what does that line look like?

    The simplified version (as per the example) would look like this:

    LSockAddrIPv6.sin6_scope_id = 4;

    Because the index of the interface in question is 4.

     

    I've been working on some "home grown" (i.e. not Indy) code that includes retrieving the local addresses and interface indexes so that they can be used for this kind of thing (amongst others).

     

    The purpose is to have a reliable, functional means of advertising that works on all platforms, using IPv4, IPv6 and works on IPv6 only networks. I've diverged from Indy because I was having to jump through too many hoops in order to make it all work, and to simplify everything.

     

    I plan on publishing the code when it is complete.

    • Thanks 1

  5. I was originally using some Indy code, however I figured I strip back the code to the absolute basics in order to try and find out what is going wrong. This is the result:

    uses
      Posix.SysSocket, Posix.NetinetIn, Posix.ArpaInet;
    
    const
      // IPv6 address of en0 on my Mac
      cIPv6 = 'fe80::ca9:418d:c487:cba';
      cPort = 9099;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      LHandle, LOption, LError: Integer;
      LSockAddrIPv6: sockaddr_in6;
      LNetAddrIPv6: in6_addr;
      LMarshaller: TMarshaller;
      LMsg: string;
    begin
      LHandle := socket(AF_INET6, SOCK_DGRAM, 0);
      if LHandle > 0 then
      begin
        LOption := 1;
        if setsockopt(LHandle, SOL_SOCKET, SO_REUSEADDR, LOption, SizeOf(LOption)) = 0 then
        begin
          if inet_pton(AF_INET6, LMarshaller.AsAnsi(cIPv6).ToPointer, @LNetAddrIPv6) = 1 then
          begin
            FillChar(LSockAddrIPv6, SizeOf(LSockAddrIPv6), 0);
            LSockAddrIPv6.sin6_len := SizeOf(LSockAddrIPv6);
            LSockAddrIPv6.sin6_family := AF_INET6;
            LSockAddrIPv6.sin6_addr := LNetAddrIPv6;
            LSockAddrIPv6.sin6_port := htons(cPort);
            if bind(LHandle, PSockAddr(@LSockAddrIPv6)^, SizeOf(LSockAddrIPv6)) = -1 then
            begin
              LError := GetLastError;
              ShowMessage(SysErrorMessage(LError));
            end;
          end;
        end;
      end;
    end;

    The bind fails, however I'm yet to be able to ascertain why. The error code returned in LError is 49, which apparently equates to: "Can't assign requested address". 

     

    Any ideas on what the problem might be? The same code also fails on iOS (using a valid IPv6 address), so is it perhaps an Apple thing?


  6. Your code does not match the Java equivalent that has been sent to you. This is the equivalent:

    uses
      Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net, Androidapi.Helpers;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      MobileNumber: string;
      Intent: JIntent;
    begin
      MobileNumber := '*155#';
      Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
      Intent.putExtra(StringToJString('com.android.phone.extra.slot'), 1);
      Intent.putExtra(StringToJString('simSlot'), 1);
      Intent.setData(TJnet_Uri.JavaClass.parse(StringtoJString('tel:' + MobileNumber)));
      TAndroidHelper.Context.startActivity(Intent);
    end;

    I don't have a dual SIM device to test this.

     

    21 minutes ago, Maher Tannous said:

    I replaced "com.android.phone.extra.slot" with TJIntent.JavaClass.EXTRA_PHONE_NUMBER

    Those are not equivalent. TJIntent.JavaClass.EXTRA_PHONE_NUMBER is "android.intent.extra.PHONE_NUMBER", not "com.android.phone.extra.slot"

    • Like 1

  7. 5 hours ago, TomDevOps said:

    using native sensors, location", have not found big issues so far

    If you're not doing anything beyond using them while the app is in the foreground, then you probably won't have any issues. Try using them (on iOS or Android) when the app is in the background, or not running.

     

    5 hours ago, TomDevOps said:

    they are not a part of FMX anyway

    Rollo may have been referring to them as being supported in the RTL, rather than users having to write more code to use them, such as Xcode and Android Studio developers do.


  8. 32 minutes ago, stevehodges60 said:

    How do you change the the minSdkVersion on RIO 3 3 with the file path??

    You can change it in AndroidManifest.Template.xml, i.e. replace %minSdkVersion% with whatever value you think should be the minimum. As per the previous replies, making this value higher will exclude as many users that have a lower version.


  9. From the pic, you've created a profile for a Windows PAServer. If deploying to iOS simulator, you need to create/use one for macOS. 

     

    If you are using macOS 10.15.x, it will all be for nought because the 32-bit portion of PAServer will not run. If your macOS version is earlier, read on....

     

    You'll also need to install an iOS 10.3 simulator (using Xcode) because Delphi does not currently support later simulators. In the Xcode menu click Window > Devices and Simulators, select the Simulators tab and click the "+" button in the bottom left:

     

    image.thumb.png.61f682a8199fedcd830ab336878f6cf0.png

     

     


  10. If FStillImageOutput is a AVCaptureStillImageOutput, you could do this:

      AVCaptureStillImageOutput = interface(iOSapi.AVFoundation.AVCaptureStillImageOutput)
        ['{A1669519-9901-489E-BDD1-A0E697C8C6CB}']
        procedure addObserver(observer: NSObject; forKeyPath: NSString; options: NSKeyValueObservingOptions; context: Pointer); cdecl; 
      end;
      TAVCaptureStillImageOutput = class(TOCGenericImport<AVCaptureStillImageOutputClass, AVCaptureStillImageOutput>)
      end;
    
      ...
    
      TAVCaptureStillImageOutput.Wrap(FStillImageOutput).addObserver(FVideoCaptureDelegate, NSObjectToID(StrToNSStr('capturingStillImage')), NSKeyValueObservingOptionNew, NSObjectToID(FAVCaptureStillImageIsCapturingStillImageContext));

    NSObjectToID comes from Macapi.Helpers

    • Like 1

  11. This line is interesting:

     

    12-06 00:30:44.030: I/agamama.orderc(31926): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.arch.lifecycle.LifecycleOwner" on path: DexPathList[[zip file "/data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/base.apk"],nativeLibraryDirectories=[/data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/lib/arm, /data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]

    12-06 00:30:44.030: I/agamama.orderc(31926): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.arch.lifecycle.LifecycleOwner" on path: DexPathList[[zip file "/data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/base.apk"],nativeLibraryDirectories=[/data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/lib/arm, /data/app/cy.com.wagamama.ordercy-qsEct8E2Xh8zg2XEtOetZg==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]

    Because android.arch.lifecycle.LifecycleOwner has long been deprecated:

     

      https://developer.android.com/reference/android/arch/lifecycle/LifecycleOwner

     

    Is there perhaps some 3rd party library you're using that's expecting this class to be present? It may be present on the devices (for compatibility) that your app works on. Not sure if this is the root cause of your problem, but it might be worth looking at.


  12. You realise you don't actually need to subclass the Activity? You do however need to have a class that implements EMDKListener, StatusListener, DataListener. 

     

    I went through the process of implementing this a couple of years ago. Looking at the code now, it might even be possible to do it completely in Delphi.


  13.  

    11 hours ago, limelect said:

    So in my opinion ,and i mite be wrong, dw-webchromeclient.jar  is the problem.

    It's not the problem, since it compiles fine for me, and others - see this link:

     

    i.e. Yaron has been able to compile using the .jar

     

    On my machine, I have Android SDK 25.2.5, and the following settings reflected in the Delphi SDK manager:

     

    Build tools: 28.0.3 (this path is used for things like ZipAlign.exe and Aapt.exe)

     

    Platform: android-28

     

    JDK: 1.8.0_191   (C:\Program Files\Java\jdk1.8.0_191\bin is the *only* entry pointing to a JDK in the PATH environment variable)

     

    I'm pretty sure those are the ones that matter.

×