Interrupted Slide Transition
I'm writing a book about cross-platform development with Delphi and in one of the chapters that covers accessing phone features, such as the camera and location services, the demo app stores a list of parks with a name, picture, and coordinates for each. I put the list of parks on the first tab and a picture along with an edit box for the park name on the second tab.
My preference for asking permissions to access services on Android devices is to hold off until the service is actually needed rather than asking for them all when the application starts. The app is designed to allow location coordinates to be taken in the "park edit" tab (there's a button at the bottom of the screen to do that), so the logical place to ask for location permissions is when the user switches to that tab. I figured the
OnUpdate event of the
TNextTabAction used for switching tabs might be a good place.
If you have non-blocking code, that wouldn't be a problem but the action's
Transition type is set to Slide, which takes a half a second or so. If the app is being run for the first time (on either an iPhone or an Android), the permission request pops up right in the middle of the tab transition, which never finishes. Of course the permission request takes most of the screen so it's not too noticeable but when the user answers the request and focus is shifted back to the app, the park edit tab is still hanging off the right edge of the screen (see the screen shot to the right).
I thought about moving the permission-requesting code somewhere else but then I remembered the highly touted parallel programming library that was added to Delphi several years ago. I rarely need multi-threading in my applications but this seemed like a perfect time to try it. The following code works perfectly to allow the slide transition to finish:
TTask.Run(procedure const PermissionAccessFineLocation = 'android.permission.ACCESS_FINE_LOCATION'; begin PermissionsService.RequestPermissions([PermissionAccessFineLocation], procedure(const APermissions: TArray
; const AGrantResults: TArray ) begin if (Length(AGrantResults) = 1) and (AGrantResults = TPermissionStatus.Granted) then LocationSensor.Active := True else TDialogServiceAsync.ShowMessage('Park location data will not be available.'); end); end);