-
Content Count
1337 -
Joined
-
Last visited
-
Days Won
29
Posts posted by Dave Nottage
-
-
12 hours ago, vedat said: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;
-
16 minutes ago, Maher Tannous said:I tried to get IMEI number and succeeded in all Android versions except 10-11-12-13
Yes, this value can no longer be accessed by regular apps on Android since version 10.
It might help to know why you need this value
-
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;
-
5 minutes ago, omnibrain said:I guess I can't use TThread.Synchronize because that's a whole different library?
I do not see why you would not be able to use it. Did you see whether your example worked?
-
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.
-
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 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
- Delete the SDK from SDK Manager in Delphi
- Delete the MacOSX13 SDK folder from C:\Users\(username)\Documents\Embarcadero\Studio\SDKs
- Delete the cache-dir folders from the scratch-dir folder on the Mac
- Re-import the SDK
-
19 minutes ago, GPRSNerd said:Both may have been fixed in Delphi 11.3 released today
Both are in the list of fixes: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/New_features_and_customer_reported_issues_fixed_in_RAD_Studio_11.3
-
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:
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 🙂
-
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
-
2
-
-
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.-
1
-
1
-
-
2 minutes ago, at3s said:Erik@Grijjy already done required changes:
Weird.. I could have sworn when I checked earlier there had not been any commits for that file since my first reply. Thanks!
-
4 hours ago, Bertifox said:Where should I make the change?
As per the earlier replies, in Grijjy.ErrorReporting.pas. Please read the replies to see exactly where in that unit, and what to change.
-
1 minute ago, Delpher2600 said:How make it?
Are you saying you do not understand this part?
2 minutes ago, Delpher2600 said:you may need to execute the code that starts it in the OnShow event of the main form
-
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.
-
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 🙂
-
1 hour ago, krucifix said:Now getting EJNIFatal with message 'Fatal error invoking interface' at
Might help to show your code for whatever implements JServiceConnection.
-
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.
-
1
-
-
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
-
1 minute ago, KenR said:Where XXXXXX is your Team ID and YYYYYY is your Application ID
I assume this worked? Thanks for the info!
-
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.
-
15 minutes ago, Dave Nottage said:Was the profile that you included (as embedded.provisionprofile) the App Store provisioning profile?
Never mind - it looks like it's an additional problem: https://developer.apple.com/forums/thread/689377
Delphi is not including the information mentioned in that thread. Yet another thing to work around 😞 More later when I work out what needs to be added
-
9 hours ago, KenR said:"Not Available for Testing
Was the profile that you included (as embedded.provisionprofile) the App Store provisioning profile?
-
11 hours ago, schaumermal said:I added the following section in the AndroidManifest.template.xml:
That doesn't match this pattern: https://developer.android.com/training/sharing/receive#update-manifest
I suggest also reading the rest of that page in regards to handling the incoming intent
-
1
-
Error Message after Update to 11.2
in General Help
Posted
In what location? Please provide the exact error message.