Yaron 53 Posted April 1, 2019 I am trying to save an image to the photo gallery using Delphi 10.3 and Android 6+ However, when the user accepts the access request prompt on the very first call, my entire app restarts all on it's own, is there any way to disable this behavior so my app doesn't restart? I implemented the code based on this blog post: http://blong.com/Articles/AndroidPermissions/DelphiAppPermissions.htm After calling (on form create): FPermission_READ_EXTERNAL_STORAGE := JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE); FPermission_WRITE_EXTERNAL_STORAGE := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE); I am calling this code to show the prompt and save the image: // Request permission PermissionsService.RequestPermissions([FPermission_WRITE_EXTERNAL_STORAGE, FPermission_READ_EXTERNAL_STORAGE], procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>) begin if (Length(AGrantResults) = 2) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) then Begin { Save file } BaseFolder := System.IOUtils.TPath.GetSharedPicturesPath; If DirectoryExists(BaseFolder) = True then Begin PIKAFolder := BaseFolder+System.IOUtils.TPath.DirectorySeparatorChar+clientGameName; If DirectoryExists(PIKAFolder) = False then ForceDirectories(PIKAFolder); PIKAFile := PIKAFolder+System.IOUtils.TPath.DirectorySeparatorChar+clientGameName+'_'+ReplaceStr(ReplaceStr(DateTimeToStr(Now),':','.'),'/','.')+saveImageFileExt; Try MyImage.SaveToFile(PIKAFile); Except clientFadingMessage := strErrorSavingPicture; End; If FileExists(PIKAFile) = True then clientFadingMessage := strPictureSaved else If clientFadingMessage = '' then clientFadingMessage := strErrorSavingPicture2; End Else clientFadingMessage := strPictureFolderNotFound; End else begin clientFadingMessage := strErrorSavingPicture; end; end ); Share this post Link to post
Dave Nottage 557 Posted April 1, 2019 Have you traced through the code to see where it fails? Does it reach the first line in the anonymous method? Share this post Link to post
Lars Fosdal 1792 Posted April 3, 2019 Is there a risk that ForceDirectories can fail with an exception? /offtopic: Comparisons with boolean values make me cringe. Share this post Link to post
Yaron 53 Posted April 3, 2019 @Dave Nottage I can't really debug since I constantly suffer from the "Unable to start gdbserver on port '64311'. Port is already in use.", so instead I've added many more debug output lines. I finally figured out what was going on, I was creating my bitmap inside a function that was triggered by a timage-clicked, that function then called the permission request with an anonymous function. However, once the anonymous function was triggered, the bitmap var was no longer valid. I fixed the issue by creating the bitmap within the anonymous function. Share this post Link to post
Remy Lebeau 1396 Posted April 3, 2019 11 hours ago, Lars Fosdal said: Is there a risk that ForceDirectories can fail with an exception? It shouldn't. It has a Boolean return value, it should just return False on failure. @Yaron the code you have showed can be simplified a little bit: // Request permission PermissionsService.RequestPermissions( [FPermission_WRITE_EXTERNAL_STORAGE, FPermission_READ_EXTERNAL_STORAGE], procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>) var fmt: TFormatSettings; begin if (Length(AGrantResults) = 2) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) then begin { Save file } PIKAFolder := System.IOUtils.TPath.GetSharedPicturesPath; if PIKAFolder <> '' then PIKAFolder := TPath.Combine(PIKAFolder, clientGameName); if ForceDirectories(PIKAFolder) then begin fmt := TFormatSettings.Create; fmt.DateSeparator := '.'; fmt.TimeSeparator := '.'; PIKAFile := TPath.Combine(PIKAFolder, clientGameName + '_' + DateTimeToStr(Now, fmt) + saveImageFileExt); try MyImage.SaveToFile(PIKAFile); clientFadingMessage := strPictureSaved; except clientFadingMessage := strErrorSavingPicture; end; end else clientFadingMessage := strPictureFolderNotFound; end else clientFadingMessage := strErrorSavingPicture; end ); Share this post Link to post
Lars Fosdal 1792 Posted April 4, 2019 Actually, http://docwiki.embarcadero.com/CodeExamples/Rio/en/DirListBoxUpdate_(C%2B%2B) says Quote Note: A EInOutError occurs if you add a directory that already exists. You must also add the new directory to your current directory. and a look at it in the source code verifies it. Share this post Link to post
Remy Lebeau 1396 Posted April 4, 2019 (edited) 10 hours ago, Lars Fosdal said: Actually, http://docwiki.embarcadero.com/CodeExamples/Rio/en/DirListBoxUpdate_(C%2B%2B) says Quote Note: A EInOutError occurs if you add a directory that already exists. You must also add the new directory to your current directory. and a look at it in the source code verifies it. Last time I checked, ForceDirectories() DOES NOT raise an exception if the specified directory already exists. Are you sure the documentation you quoted is referring to ForeceDirectories() and not TDirListBox? Which source code did you "verify" exactly? The ForceDirectories() documentation does warn against calling it with a blank string, which I accidentally did in my example above if TPath.GetSharedPicturePath() returns a blank string. Edited April 4, 2019 by Remy Lebeau Share this post Link to post
Lars Fosdal 1792 Posted April 8, 2019 function SelectDirectory calls ForceDirectories, and there is no raise in the TDirectoryListBox class. Anyways - ForceDirectories can cause an exception under the specified circumstances - so the real question is: What is the content of PIKAFolder when it is passed to ForceDirectories, and - if not blank - what happens if the folder already exists? Share this post Link to post
Remy Lebeau 1396 Posted April 8, 2019 15 hours ago, Lars Fosdal said: Anyways - ForceDirectories can cause an exception under the specified circumstances Which circumstances exactly? 15 hours ago, Lars Fosdal said: if not blank - what happens if the folder already exists? ForceDirectories() SHOULD succeed without error in that case. Its job is to ensure a path exists, not to report an error if it does exist. The only time it should ever raise an exception is if the input path is blank. Anything else should cause it to simply return True if the path already exists or was successfully created, or False otherwise. If it is not working that way, that is a bug for Embarcadero to fix. Share this post Link to post