Jump to content

Dave Nottage

Members
  • Content Count

    1337
  • Joined

  • Last visited

  • Days Won

    29

Posts posted by Dave Nottage


  1. 12 hours ago, vedat said:

    In  this link, there is an answer by  @Greg T . I've tested his code-script on Android platform but I was not able to show device storage in Mb correctly

    Probably because his answer is for memory, not storage. If you're after the latter, there's an answer in Java here that should be relatively easily translated. Some time ago I added an import for the relevant classes (Environment and StatFs) in this unit, but I'll repeat the code just for those classes if that's all you are looking for:

     

      JEnvironmentClass = interface(JObjectClass)
        ['{847171A2-7B65-4251-9BD3-E0BC89DE31FD}']
        {class} function _GetDIRECTORY_ALARMS: JString; cdecl;
        {class} procedure _SetDIRECTORY_ALARMS(Value: JString); cdecl;
        {class} function _GetDIRECTORY_AUDIOBOOKS: JString; cdecl;
        {class} procedure _SetDIRECTORY_AUDIOBOOKS(Value: JString); cdecl;
        {class} function _GetDIRECTORY_DCIM: JString; cdecl;
        {class} function _GetDIRECTORY_DOCUMENTS: JString; cdecl;
        {class} function _GetDIRECTORY_DOWNLOADS: JString; cdecl;
        {class} procedure _SetDIRECTORY_DOWNLOADS(Value: JString); cdecl;
        {class} function _GetDIRECTORY_MOVIES: JString; cdecl;
        {class} function _GetDIRECTORY_MUSIC: JString; cdecl;
        {class} procedure _SetDIRECTORY_MUSIC(Value: JString); cdecl;
        {class} function _GetDIRECTORY_NOTIFICATIONS: JString; cdecl;
        {class} procedure _SetDIRECTORY_NOTIFICATIONS(Value: JString); cdecl;
        {class} function _GetDIRECTORY_PICTURES: JString; cdecl;
        {class} function _GetDIRECTORY_PODCASTS: JString; cdecl;
        {class} procedure _SetDIRECTORY_PODCASTS(Value: JString); cdecl;
        {class} function _GetDIRECTORY_RINGTONES: JString; cdecl;
        {class} function _GetDIRECTORY_SCREENSHOTS: JString; cdecl;
        {class} procedure _SetDIRECTORY_SCREENSHOTS(Value: JString); cdecl;
        {class} function _GetMEDIA_BAD_REMOVAL: JString; cdecl;
        {class} function _GetMEDIA_CHECKING: JString; cdecl;
        {class} function _GetMEDIA_EJECTING: JString; cdecl;
        {class} function _GetMEDIA_MOUNTED: JString; cdecl;
        {class} function _GetMEDIA_MOUNTED_READ_ONLY: JString; cdecl;
        {class} function _GetMEDIA_NOFS: JString; cdecl;
        {class} function _GetMEDIA_REMOVED: JString; cdecl;
        {class} function _GetMEDIA_SHARED: JString; cdecl;
        {class} function _GetMEDIA_UNKNOWN: JString; cdecl;
        {class} function _GetMEDIA_UNMOUNTABLE: JString; cdecl;
        {class} function _GetMEDIA_UNMOUNTED: JString; cdecl;
        {class} function init: JEnvironment; cdecl;
        {class} function getDataDirectory: JFile; cdecl;
        {class} function getDownloadCacheDirectory: JFile; cdecl;
        {class} function getExternalStorageDirectory: JFile; cdecl;
        {class} function getExternalStoragePublicDirectory(&type: JString): JFile; cdecl;
        {class} function getExternalStorageState: JString; cdecl; overload;
        {class} function getExternalStorageState(path: JFile): JString; cdecl; overload;
        {class} function getRootDirectory: JFile; cdecl;
        {class} function getStorageState(path: JFile): JString; cdecl;
        {class} function getStorageDirectory: JFile; cdecl; // **** Android 11 ****
        {class} function isExternalStorageEmulated: Boolean; cdecl; overload;
        {class} function isExternalStorageEmulated(path: JFile): Boolean; cdecl; overload;
        {class} function isExternalStorageLegacy: Boolean; cdecl; overload; // **** Android 10 ****
        {class} function isExternalStorageLegacy(path: JFile): Boolean; cdecl; overload; // **** Android 10 ****
        {class} function isExternalStorageManager: Boolean; cdecl; overload; // **** Android 11 ****
        {class} function isExternalStorageManager(path: JFile): Boolean; cdecl; overload; // **** Android 11 ****
        {class} function isExternalStorageRemovable: Boolean; cdecl; overload;
        {class} function isExternalStorageRemovable(path: JFile): Boolean; cdecl; overload;
        {class} property DIRECTORY_ALARMS: JString read _GetDIRECTORY_ALARMS write _SetDIRECTORY_ALARMS;
        {class} property DIRECTORY_AUDIOBOOKS: JString read _GetDIRECTORY_AUDIOBOOKS write _SetDIRECTORY_AUDIOBOOKS; // **** Android 10 ****
        {class} property DIRECTORY_DCIM: JString read _GetDIRECTORY_DCIM;
        {class} property DIRECTORY_DOCUMENTS: JString read _GetDIRECTORY_DOCUMENTS;
        {class} property DIRECTORY_DOWNLOADS: JString read _GetDIRECTORY_DOWNLOADS write _SetDIRECTORY_DOWNLOADS;
        {class} property DIRECTORY_MOVIES: JString read _GetDIRECTORY_MOVIES;
        {class} property DIRECTORY_MUSIC: JString read _GetDIRECTORY_MUSIC write _SetDIRECTORY_MUSIC;
        {class} property DIRECTORY_NOTIFICATIONS: JString read _GetDIRECTORY_NOTIFICATIONS write _SetDIRECTORY_NOTIFICATIONS;
        {class} property DIRECTORY_PICTURES: JString read _GetDIRECTORY_PICTURES;
        {class} property DIRECTORY_PODCASTS: JString read _GetDIRECTORY_PODCASTS write _SetDIRECTORY_PODCASTS;
        {class} property DIRECTORY_RINGTONES: JString read _GetDIRECTORY_RINGTONES;
        {class} property DIRECTORY_SCREENSHOTS: JString read _GetDIRECTORY_SCREENSHOTS write _SetDIRECTORY_SCREENSHOTS; // **** Android 10 ****
        {class} property MEDIA_BAD_REMOVAL: JString read _GetMEDIA_BAD_REMOVAL;
        {class} property MEDIA_CHECKING: JString read _GetMEDIA_CHECKING;
        {class} property MEDIA_EJECTING: JString read _GetMEDIA_EJECTING;
        {class} property MEDIA_MOUNTED: JString read _GetMEDIA_MOUNTED;
        {class} property MEDIA_MOUNTED_READ_ONLY: JString read _GetMEDIA_MOUNTED_READ_ONLY;
        {class} property MEDIA_NOFS: JString read _GetMEDIA_NOFS;
        {class} property MEDIA_REMOVED: JString read _GetMEDIA_REMOVED;
        {class} property MEDIA_SHARED: JString read _GetMEDIA_SHARED;
        {class} property MEDIA_UNKNOWN: JString read _GetMEDIA_UNKNOWN;
        {class} property MEDIA_UNMOUNTABLE: JString read _GetMEDIA_UNMOUNTABLE;
        {class} property MEDIA_UNMOUNTED: JString read _GetMEDIA_UNMOUNTED;
      end;
    
      [JavaSignature('android/os/Environment')]
      JEnvironment = interface(JObject)
        ['{8A8591BC-BC01-4338-91D8-2671DAB231F8}']
      end;
      TJEnvironment = class(TJavaGenericImport<JEnvironmentClass, JEnvironment>) end;
    
      JStatFsClass = interface(JObjectClass)
        ['{F97A99DF-CDC1-4842-80F2-2EA53A906E3E}']
        {class} function init(path: JString): JStatFs; cdecl;
      end;
    
      [JavaSignature('android/os/StatFs')]
      JStatFs = interface(JObject)
        ['{C34856EE-443F-42CB-B25B-DEC0B8C938D0}']
        function getAvailableBlocks: Integer; cdecl;
        function getAvailableBlocksLong: Int64; cdecl;
        function getAvailableBytes: Int64; cdecl;
        function getBlockCount: Integer; cdecl;
        function getBlockCountLong: Int64; cdecl;
        function getBlockSize: Integer; cdecl;
        function getBlockSizeLong: Int64; cdecl;
        function getFreeBlocks: Integer; cdecl;
        function getFreeBlocksLong: Int64; cdecl;
        function getFreeBytes: Int64; cdecl;
        function getTotalBytes: Int64; cdecl;
        procedure restat(path: JString); cdecl;
      end;
      TJStatFs = class(TJavaGenericImport<JStatFsClass, JStatFs>) end;

     


  2. Is the original question about retrieving local IP addresses? This code still works for me with a target SDK of 31+:

     

    uses
      IdStack;
    
    procedure GetLocalAddressList(const AAddresses: TIdStackLocalAddressList);
    
    implementation
    
    uses
      System.SysUtils,
      Androidapi.JNI.Java.Net, Androidapi.JNI.JavaTypes, Androidapi.Helpers,  Androidapi.JNIBridge,
      IdGlobal;
    
    procedure GetLocalAddressList(const AAddresses: TIdStackLocalAddressList);
    var
      LInterfaces, LAddresses: JEnumeration;
      LInterface: JNetworkInterface;
      LAddress: JInetAddress;
      LName, LHostAddress: string;
    begin
      AAddresses.Clear;
      LInterfaces := TJNetworkInterface.JavaClass.getNetworkInterfaces;
      while LInterfaces.hasMoreElements do
      begin
        LInterface := TJNetworkInterface.Wrap(LInterfaces.nextElement);
        LAddresses := LInterface.getInetAddresses;
        while LAddresses.hasMoreElements do
        begin
          LAddress := TJInetAddress.Wrap(LAddresses.nextElement);
          if LAddress.isLoopbackAddress then
            Continue;
          // Hack until I can find out how to check properly
          LName := JStringToString(LAddress.getClass.getName);
          LHostAddress := JStringToString(LAddress.getHostAddress);
          // Trim excess stuff
          if LHostAddress.IndexOf('%') > -1 then
            LHostAddress := LHostAddress.Substring(0, LHostAddress.IndexOf('%'));
          if LName.Contains('Inet4Address') then
            TIdStackLocalAddressIPv4.Create(AAddresses, LHostAddress, '')
          else if LName.Contains('Inet6Address') then
            TIdStackLocalAddressIPv6.Create(AAddresses, LHostAddress);
        end;
      end;
    end;

     


  3. 47 minutes ago, Remy Lebeau said:

    I don't see any tickets open in QualityPortal about that issue yet.

    Indeed. According to the docs, setting a scheduled notification in this demo: https://github.com/Embarcadero/RADStudio11Demos/tree/main/Object Pascal/Mobile Snippets/Notifications/SendCancelNotification
    Should fail, but it doesn't. At this point I have no idea why - the target SDK level is 32, and a PendingIntent is being created without the MUTABLE or IMMUTABLE flags being included.

     

    Back to the drawing board:

    18 hours ago, nufus42 said:

    java.lang.IllegalArgumentException: <appname> Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

    You'll need to provide a reproducible example.


  4. 2 hours ago, nufus42 said:

    I developed an app with 11.1 for Android target 30 including push notifications and local notifications

     

    2 hours ago, nufus42 said:

    java.lang.IllegalArgumentException: <appname> Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

     

    2 hours ago, nufus42 said:

    Would updating Delphi to 11.2 or 11.3 really help?

    Unfortunately, no.. and I don't know why it was missed. There's a couple of spots in System.Android.Notification.pas (local notification support) where a PendingIntent is used and the flag is not being included. Best you could do right now is to copy the unit, put it somewhere in your project path and make the necessary modifications.


  5. 5 minutes ago, softtouch said:

    Should the 11.3 be compatible to macos sdk 13.1? I at least cant use that sdk, I get

     

    [dccosx64 Error] E2597 ld: file not found: /System/Library/PrivateFrameworks/AVFCapture.framework/Versions/A/AVFCapture for architecture x86_64

    1. Delete the SDK from SDK Manager in Delphi
    2. Delete the MacOSX13 SDK folder from C:\Users\(username)\Documents\Embarcadero\Studio\SDKs
    3. Delete the cache-dir folders from the scratch-dir folder on the Mac
    4. Re-import the SDK

  6. 4 minutes ago, softtouch said:

    Is there a single function to retrieve the path to the Desktop which works on Windows and macOS?

    It appears there is not a single function "out of the box", but it wouldn't be too difficult to implement. TPath.GetHomePath is supposed to return /Users/<username> on macOS:

     

    https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms

     

    So appending "Desktop" should be reliable.

     

    For Windows you'd need to do a bit more work. TPath.GetDocumentsPath on Windows gives, for example: C:\Users\<username>\Documents, so you could remove the Documents part and add Desktop 🙂

     


  7. On 2/22/2023 at 8:57 AM, Dave Nottage said:

    Next week I plan to release version 1.6 of Codex - the changes include functionality that is intended to help with this process.

    I've now released Codex 1.6, which has the functionality I mentioned, and I had a crack at implementing Firebase Crashlytics, but I was unable to make it work. I guess I'm missing something; I just don't know what 🙂

     

    There's a test project in the Playground repo: https://github.com/DelphiWorlds/Playground/tree/main/Demos/Crashlytics if anyone is interested in the work in progress

     

    • Like 2

  8. On 1/28/2023 at 7:10 PM, kdevil89 said:

    but can't find any information about crashlytics

    There's info about it here: https://firebase.google.com/docs/crashlytics/ndk-reports. There is also: https://firebase.google.com/docs/crashlytics/get-started?platform=android#java however since Delphi apps are native, I expect the former is more relevant, and it includes the SDK version as well anyway.

     

    A quick glance tells me that it should be able to be integrated into a Delphi app, however it appears it may need the same treatment as described in: https://quality.embarcadero.com/browse/RSP-20000

    Next week I plan to release version 1.6 of Codex - the changes include functionality that is intended to help with this process.

    • Like 1
    • Thanks 1

  9. 1 hour ago, Delpher2600 said:

    Calling from main project:

    That doesn't show where in the project the code is executed. In later versions of Android, you a service needs to be started when the application is in the foreground, so you may need to execute the code that starts it in the OnShow event of the main form, or possibly add a listener for the BecameActive application event, and execute it then.

     

    Also, this code:

    1 hour ago, Delpher2600 said:

    FService.StartService('F');

    Does not match the exception in the image, since 'Z' <> 'F'. I assume a typo, or you renamed the service.

     


  10. 27 minutes ago, krucifix said:

    Common := TJIAsoftPOS.Wrap((ServiceConnection as ILocalObject).GetObjectID);

    This code is not going to work. I suggest looking at the code for TLocalServiceConnection.TJavaServiceConnection.onServiceConnected in the System.Android.Service unit in the Delphi source code. Warning: it's not for the faint of heart 🙂

     


  11. 6 hours ago, santycg said:

    However, if I run the app in device, I only see a black screen and nothing happens. The app worked perfectly with previous targetSdkVersion (30).

    One reason may be that your startup code is attempting to access something that requires additional runtime permissions. I suggest using a logcat viewer to see what warnings or errors are emitted - personally, I use Device Lens (my own product). Alternatively, isolate what your code does at startup (including components on the main form that access OS resources e.g. Bluetooth) until you find the culprit.

    • Like 1

  12. 10 minutes ago, Dave Nottage said:
    12 minutes ago, KenR said:

    Where XXXXXX is your Team ID and YYYYYY is your Application ID

    I assume this worked? Thanks for the info!

    I just tested it myself, without the changes to info.plist.TemplateOSX.xml and it worked. Thanks again! I'll be updating the report


  13. 4 hours ago, Dave Nottage said:

    More later when I work out what needs to be added

    An example of what probably needs to be added to info.plist.TemplateOSX.xml (inside of the dict tag): 

    <key>DTPlatformBuild</key>
    <string>22C65</string>
    <key>DTPlatformName</key>
    <string>macosx</string>
    <key>DTPlatformVersion</key>
    <string>13.1</string>
    <key>DTSDKBuild</key>
    <string>22C55</string>
    <key>DTSDKName</key>
    <string>macosx13.1</string>
    <key>DTXcode</key>
    <string>1420</string>
    <key>DTXcodeBuild</key>
    <string>14C18</string>

    DTPlatformBuild is (as I understand) the value for the OS used to build the app. In my case I have Ventura 13.1
    DTSDKBuild the build value for the SDK. Here it is for macOS 13.1 SDK
    DTXcode is the version of Xcode with no periods i.e. here it is 14.2.0 (or just 14.2)

    DTXcodeBuild is the build value for the version of Xcode used

     

    I expect the most important values are DTPlatformBuild, DTSDKBuild and DTXcodeBuild - it may be that the others can be omitted. No guarantee that all the values are correct here - I had to do some Googling to find them.

×