Postanowienia runtime dotyczące statusu środowiska uruchomieniowego firefonkey android wymagają uzyskania IMEI - android, delphi, uprawnienia, firemonkey, delphi-10.2-tokyo

Jak uzyskać uprawnienie do read_phone_state w środowisku uruchomieniowym, aby uzyskać numer IMEI?

  if not HasPermission("android.permission.READ_PHONE_STATE") then
begin

//ASK AND GET PERMISSION ?

end;


function TForm1.HasPermission(const Permission: string): Boolean;
begin
//Permissions listed at http://d.android.com/reference/android/Manifest.permission.html
{$IF RTLVersion >= 30}
Result := TAndroidHelper.Context.checkCallingOrSelfPermission(
{$ELSE}
Result := SharedActivityContext.checkCallingOrSelfPermission(
{$ENDIF}
StringToJString(Permission)) =
TJPackageManager.JavaClass.PERMISSION_GRANTED;


end;

Odpowiedzi:

3 dla odpowiedzi № 1

EDYTOWAĆ:Przepraszam, że nie zrobiłem więcej pracy domowej na FireMonkey, a to jest to, co dostaję za wtrącanie się w tematy, do których nie należy. Dodałem tę treść, aby moja odpowiedź bardziej zasługiwała na nagrodę.

Jeśli możesz ograniczyć targetSdk w manifeście aplikacji do 22 (5.1 Lollipop), wtedy użytkownik będzie musiał udzielić pozwolenia na instalację tak HasPermission nigdy nie powinien zwracać fałszu. (Nie wiesz, jak to działa z FireMonkey).

Jeśli chcesz korzystać z dynamicznych uprawnień w programie Marshmallow +, oto kilka informacji, które zebrałem ta strona:

Musisz mieć dostęp do Activity metoda wywołania zwrotnego onRequestPermissionsResult. Oto wszystkie obręcze, przez które musisz przeskoczyć:

  • Użyj narzędzia open-source Dex2Jar przekonwertować Androida classes.dex plik z Delphi z powrotem do Javy, dzięki czemu można skompilować z FMXNativeActivity klasa.
  • Koduj podklasę FMXNativeActivity w Javie, która definiuje native metoda (nazwijmy to onRequestPermissionsResultNative a także zastępuje onRequestPermissionsResult metoda wywoływania metody natywnej.
  • biegać javac aby uzyskać plik .class z podklasą
  • biegać jar wstawić plik .class do pliku .jar
  • biegać dx.bat zmienić plik .jar w plik .dex systemu Android
  • biegać DexMerger połączyć plik .dex w plik klasy classes.dex firmy Delphi
  • Teraz pozostaje tylko napisanie jakiegoś trudnego kodu Delphi, aby zdefiniować twoje onRequestPermissionsResultNative i zarejestrować go w środowisku JNI. Aha, i nie zapomnij zmienić właściwego wątku w swojej natywnej metodzie.

Link, do którego się odwołałem, pokazuje, jak to zrobić onActivityResult. Będziesz musiał dostosować te kroki do innej metody.

I nawet nie rozmawiałem o tym, jak obsługiwać system operacyjny, wstrzymując twoją aplikację, aby poprosić użytkownika o pozwolenie i wznowić ją po.

Niech to będzie lekcja dla wszystkich: nie pokładaj wiary w narzędzia wieloplatformowe, będziesz rozczarowany.


Pracuję w Javie nie w Delphi, więc będziesz musiał trochę ekstrapolować.

Tak jak ty, muszę uzyskać numer IMEI, iokno dialogowe systemu pyta użytkownika: "Zezwól aplikacji na wykonywanie połączeń telefonicznych i zarządzanie nimi?" Muszę wyjaśnić użytkownikowi, że ta aplikacja otrzymuje właśnie identyfikator urządzenia i nie będzie wykonywać połączeń telefonicznych ani nimi zarządzać.

  • Sprawdź, czy masz pozwolenie
  • Jeśli nie masz pozwolenia, sprawdź, czy powinieneś wyświetlić wyjaśnienie
  • Jeśli nie musisz wyświetlać wyjaśnienia, rozpocznij operację żądania uprawnień

Powinienem o tym wspomnieć shouldShowRequestPermissionRationale i requestPermissions są metody na Activity klasa.

    private static final int READ_PHONE_STATE_PERMISSIONS_REQUEST = 2;

private boolean mHasReadRationale;

void doPermissionsStuff() {
// version checking code omitted, this block runs for marshmallow and later
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
// do the operation that needs the permission here
} else {
// the flag indicates if the rationale dialog has already been displayed
if (! mHasReadRationale && shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)) {
// pop a dialog that explains what"s going on to the user
} else {
requestPermissions(new String[] {Manifest.permission.READ_PHONE_STATE}, READ_PHONE_STATE_PERMISSIONS_REQUEST);
}
}
}

W dodatnim przycisku tego okna dialogowego (tzn. Użytkownik chce kontynuować) ustaw mHasReadRationale Oznacz flagę jako true i zadzwoń doPermissionsStuff jeszcze raz. (W przypadku Anulowania wysyłam użytkownika z powrotem na poprzedni ekran.)

Aby uzyskać wynik requestPermissions operacja, którą musisz zastąpić Activity"s onRequestPermissionsResult metoda:

private boolean mPermissionDenied;

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

switch (requestCode) {
case READ_PHONE_STATE_PERMISSIONS_REQUEST:
// I"m only checking for one permission, so I make assumptions here
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you can do the operation that needs the permission now
} else {
mPermissionDenied = true;  // set a flag for checking later
}
}
}

Najwyraźniej, gdy system prosi użytkownika oZgoda, zatrzymuje Twoją aplikację, więc nie możesz wyświetlić interfejsu użytkownika w tym miejscu, aby powiedzieć użytkownikowi, że nie masz uprawnień. Ustawiłem więc flagę i po wznowieniu aplikacji następnie Mówię użytkownikowi, że aplikacja nie ma uprawnień do wykonania operacji.

@Override
protected void onResumeFragments() {
super.onResumeFragments();
if (mPermissionDenied) {
// show dialog to the user that the app can"t do the operation because it doesn"t have permission
mPermissionDenied = false;
}
}

Oto przykładowy przepływ:

  • Użytkownik chce bezpłatnej wersji próbnej i aplikacji, aby uzyskać IMEI, dzięki czemu nie będą mogli uzyskać bezpłatnego okresu próbnego, jeez. doPermissionsStuff().
  • Połączenia aplikacji checkSelfPermission() i określa, czy zezwolenie nie zostało jeszcze przyznane
  • Połączenia aplikacji shouldShowRequestPermissionRationale(). Z mojego doświadczenia, shouldShowRequestPermissionRationale() zwraca tylko wartość true, gdy użytkownik odmówi zgody raz. Więc nie wyświetlasz jeszcze użytkownikowi interfejsu racjonalnego.
  • Połączenia aplikacji requestPermissions()
  • System zapyta użytkownika "Zezwól aplikacji na wykonywanie połączeń telefonicznych i zarządzanie nimi?"
  • Użytkownik decyduje, że WAAAAAAY jest zbyt przerażający i naciska przycisk Nie.
  • onRequestPermissionsResult() jest wywoływana z wynikiem deny i mPermissionDenied zostaje ustawiony.
  • onResumeFragments() zostaje wywołana i wyświetlane jest okno dialogowe, w którym użytkownik nie może uzyskać bezpłatnej wersji próbnej, ponieważ aplikacja nie ma uprawnień.
  • Użytkownik postanawia spróbować ponownie. doPermissionsStuff() jest nazywany.
  • Połączenia aplikacji checkSelfPermission() i (ponownie) określa, że ​​pozwolenie nie zostało jeszcze przyznane
  • Połączenia aplikacji shouldShowRequestPermissionRationale(). Tym razem zwraca true.
  • Aplikacja wyświetla uspokajający i kojący komunikat doużytkownik, że nie, nie przejmiemy telefonu, chcemy tylko freakin "numer IMEI, to wszystko, a jeśli nie pozwalasz aplikacji na dostęp do IMEI, nie dostaniesz darmowy okres próbny. Muszę narysować linię gdzieś.
  • Prasy użytkownika są kontynuowane, więc mHasReadRationale flaga jest ustawiona na true i doPermissionsStuff() metoda zostanie ponownie wywołana.
  • Połączenia aplikacji checkSelfPermission() i zgadnij co? pozwolenie nie zostało jeszcze udzielone
  • Ponieważ flaga jest ustawiona, użytkownik nie otrzymuje uzasadnionego interfejsu użytkownika.
  • Połączenia aplikacji requestPermissions()
  • System zapyta użytkownika "Zezwól aplikacji na wykonywanie połączeń telefonicznych i zarządzanie nimi?"
  • Użytkownik rezygnuje z własnego losowania i naciska Tak.
  • onRequestPermissionsResult() jest wywoływana z przyznanym wynikiem, a bezpłatna rejestracja próbna przesuwa się do przodu.

Powinieneś również sprawdzić kod próbny Google na stronie https://developer.android.com/samples/RuntimePermissions/index.html


Powiązane pytania