Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   PermissionsService.RequestPermissions ist asynchron! (https://www.delphipraxis.net/203011-permissionsservice-requestpermissions-ist-asynchron.html)

skoschke 3. Jan 2020 10:25

PermissionsService.RequestPermissions ist asynchron!
 
Hallo,

da Verwendung von Delphi Rio und Devices mit Android 9 hilft das Manifest bei den Berechtigungen nicht wirklich, denn die sind nach Installation der App zwar als Berechtigungen im App-Manager gelistet aber alle abgeschaltet!

nun habe ich PermissionsService.RequestPermissions(...) gefunden, was auch die angeforderten Berechtigungen vom User bei Programmstart abfragt.

Nur kehrt leider der Aufruf von PermissionsService.RequestPermissions sofort zurück und der weitere Programmcode wird abgearbeitet während auf dem Display noch die erste Abfrage ('Speicher lesen / schreiben erlauben...') steht.

Damit aber bekomme ich Laufzeitfehler, da hier jetzt auf den Speicher zugegriffen wird aber die Berechtigung noch nicht vorliegt!

Wie löst man das bzw. bekommt man die App-Berechtigungen mit Rio auf Android 9 sofort bei Installation per Manifest abgefragt und gespeichert?

Danke
Ciao
Stefan

Der schöne Günther 3. Jan 2020 10:43

AW: PermissionsService.RequestPermissions ist asynchron!
 
Ist das nicht hier erklärt?

http://docwiki.embarcadero.com/RADSt...rmission_Model

jaenicke 3. Jan 2020 10:57

AW: PermissionsService.RequestPermissions ist asynchron!
 
Unter Android und iOS sollte alles asynchron sein. Die eigene Aktion muss schlicht in dem Callback passieren, wenn die Berechtigung vorhanden ist, nicht nach dem Aufruf an RequestPermissions.

skoschke 3. Jan 2020 11:16

AW: PermissionsService.RequestPermissions ist asynchron!
 
das habe ich ja implementiert:

Delphi-Quellcode:
  PermissionsService.RequestPermissions
    ([JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE)],
    procedure(const APermissions: TArray<string>;
      const AGrantResults: TArray<TPermissionStatus>)
    begin
      if (Length(AGrantResults) = 1) and
        (AGrantResults[0] = TPermissionStatus.Granted) then
      begin
        //erlaubt
      end
      else
      begin
         TDialogService.ShowMessage('Ohne Speicherzugriff kann das Programm nicht arbeiten und wird beendet!');
         Application.Terminate;
      end;
    end);
  // Gerätename wegschreiben
  MakeDeviceInfo(DeviceInfo.diDevice);
aber während noch "Zugriff auf Medien... erlauben" auf dem Display unbeantwortet steht wird schon die Procedure MakeDeviceInfo aufgerufen die auf den (noch nicht erlaubt) Speicher zugreifen will!

Ciao
Stefan

mensch72 3. Jan 2020 11:30

AW: PermissionsService.RequestPermissions ist asynchron!
 
nee... hast du nicht implementiert!

dein
"// Gerätename wegschreiben
MakeDeviceInfo(DeviceInfo.diDevice);"
muss da stehen, wo du "//erlaubt" (leer) hin geschrieben hast!

Du solltest dir Konzept und Funktion der asynchronen anonymen Methoden nochmal ganz in Ruhe klarmachen!

Um nicht Probleme mit Ausführung im Thread zu bekommen, könntest du bei "erlaubt" auch einen kurzen 50msec Timer starten und im OnTimer dann dein "// Gerätename wegschreiben" machen. Dann läuft das zuminest wieder im MainThread selbst ab, bzw. das bei "//erlaubt" in ein Syncronize(procedure wegschreiben) packen.

Viel Spaß und Erfolg beim Nachdenken:)

Rollo62 3. Jan 2020 13:12

AW: PermissionsService.RequestPermissions ist asynchron!
 
Das "Application.Terminate;"
sollte man auch weglassen.

Eine App kann sich so einfach nicht selbst beenden, das sollte immer der User machen.

skoschke 3. Jan 2020 13:38

AW: PermissionsService.RequestPermissions ist asynchron!
 
OK, habe das mit dem Callback kapiert :-)

Da kommt aber ein neues Problem:

Das procedure(const APermissions: TArray<string>; Callback wird gar nicht mehr aufgerufen wenn bereits alle Zugriffe erlaubt worden sind!

Ich möchte in der Programm-Unit bzw. in einem Startscreen erst alle Zugriffsrechte holen wenn nicht vorhanden und erst dann soll das eigentliche Programm starten!

Ciao
Stefan

mensch72 3. Jan 2020 14:40

AW: PermissionsService.RequestPermissions ist asynchron!
 
..."Das procedure(const APermissions: TArray<string>; Callback wird gar nicht mehr aufgerufen wenn bereits alle Zugriffe erlaubt worden sind!"...
wozu rufst du es denn auf?... du hast dir doch wohl sicher alles was du einmalig abfragen kannst schon beim ersten mal in einer eigenen z.B. SQlite DB gespeichert!?

Ansonsten gilt ganz allgemein:
alles was "nur" in der Async procedure an Daten verfügbar, muss in "globale Variablen(sinnvoller Weise des MainThreads)" gefuffert und praktischer Weise mit einem TimeStamp wann zuletzt aktualisiert versehen werden.
Nur dann kannst du im Programmablauf wenn du real irgendwann die abgefagten Sachen benutzen willst feststellen, ob du mit den DB Werten oder ev. gemäß TimeStamp den aktuelleren gepufferten AsyncDaten arbeiten willst, und/oder z.B. deine DB aktualisieren.


Und aus Erfahrung gilt praktisch:
- alles was man Async auslöst kann entweder als Result stets "gültig"/"ungültig" ODER "!TimeOut!" haben... also IMMER mindestens eine "TriState-Logik" implementieren!
- daher ist mein Vorschlag mit nem langen "max" TimerTimeout VOR dem AsyncCall und nem ändern des Timers auf ein minimales TimeOut IM AsynCall eine aus meiner Sicht sehr elegante und sichere Lösung, um alle 3 möglichen "Async-ResultStates" simpel an einer Stelle im "onTimer" im HauptThreadKontext ver/bearbeiten zu können.


TIP:
Statt eines StartScreen bietet es sich an anfangs einfach an, einen halbdurchsichtigen Frame/Dialog/... über die gesamte GUI zu legen, dann alles was nötig ist StepByStep "als Async-Kette" machen und erst wenn alles OK, bzw. irgend ein TimeOut die GUI wieder freigeben(bei TimeOut nun dem Anwender mitzuteilen was fehlt und warum nun Schluss)
- wenn schon alles frei und OK, sollte die GUI-Serre nicht länger wie 1sec dauern/sichtbar sein... sonst besser nen Progressbar oder ne Animation mit anzeigen


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz