Firemonkey android read phone state runtime разрешение просит получить IMEI

Как я могу получить разрешение read_phone_state во время выполнения, чтобы получить номер 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;

1 ответов


EDIT: Извините, я не сделал немного больше домашней работы на FireMonkey. Вот что я получаю за то, что лезу в чужие темы. Я добавил этот контент, чтобы попытаться сделать мой ответ более заслуживающим награды.

если вы можете ограничить targetSdk в манифесте приложения до 22 (5.1 Lollipop), то пользователь должен будет предоставить разрешение на установку so HasPermission никогда не должен возвращать false. (Не уверен как это работает с помощью FireMonkey).

если вы хотите используйте возможности динамических разрешений в Marshmallow+, вот некоторая информация, которую я почерпнул из на этой странице:

вы должны иметь доступ к Activity метод обратного вызова onRequestPermissionsResult. Вот все обручи, через которые вам придется прыгать:

  • используйте инструмент с открытым исходным кодом Dex2Jar конвертировать Android classes.dex файл из Delphi обратно на Java, так что вы можете скомпилировать против FMXNativeActivity класса.
  • код подкласс FMXNativeActivity в Java это определяет native метод (назовем его onRequestPermissionsResultNative, а также переопределяет onRequestPermissionsResult метод для вызова собственного метода.
  • выполнить javac получить .файл класса с вашим подклассом
  • выполнить jar поставить .файл класса в .jar-файл
  • выполнить dx.bat в свою очередь ваш .файл jar в Android .файл DeX
  • выполнить DexMerger слить свой .dex файл в классы Delphi.файл DeX
  • теперь все, что осталось сделать, это написать какой-то хитрый код Delphi для определения вашего onRequestPermissionsResultNative метод и зарегистрировать его в среде JNI. Да, и не забудьте переключиться на правильный поток в свой собственный метод.

ссылка, на которую я ссылался, показывает, как это сделать с onActivityResult. Вам придется адаптировать эти шаги для другого метода.

и я даже не говорил о том, как обрабатывать ОС, приостанавливая приложение, чтобы попросить у пользователя разрешения и возобновить его после.

пусть это будет урок для всех: не верьте в кросс-платформенные инструменты; вы будете разочарованы.


я работаю на Java, а не на Delphi, поэтому вам придется немного экстраполировать здесь.

как и вы, я должен получить номер IMEI, и системный диалог спрашивает пользователя что-то вроде: "разрешить приложению совершать и управлять телефонными звонками?"Мне нужно объяснить пользователю, что это приложение просто получает идентификатор устройства и не собирается совершать или управлять телефонными звонками. Так что

  • проверьте, есть ли у вас разрешение
  • если у вас нет разрешения, проверьте, если вы должны отображать объяснение
  • Если вам не нужно показывать объяснение, запустите операцию запроса разрешения

я должен упомянуть об этом shouldShowRequestPermissionRationale и requestPermissions методы на Activity класса.

    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);
            }
        }
    }

в положительной кнопке этого диалога (т. е. пользователь хочет продолжить) установите mHasReadRationale флаг в true и звоните doPermissionsStuff снова. (Для отмены я отправляю пользователя обратно на предыдущий экран.)

для того, чтобы получить результат requestPermissions операция вам нужно переопределить Activity ' s onRequestPermissionsResult способ:

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
        }
    }
}

по-видимому, когда система запрашивает у пользователя разрешение, она останавливает ваше приложение, поэтому вы не можете показать пользовательский интерфейс в этот момент, чтобы сообщить пользователю, что у вас нет разрешения. Поэтому я установил флаг, и когда приложение возобновится, затем я говорю пользователю, что приложение не имеет разрешения на работу.

@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;
    }
 }

Итак, вот пример потока:

  • пользователь хочет бесплатную пробную версию и приложение должно получить IMEI, чтобы они не могли продолжать получать бесплатную пробную версию снова и снова, Боже. Приложение звонки doPermissionsStuff().
  • App звонки checkSelfPermission() и определяет, что разрешение еще не предоставлено
  • App звонки shouldShowRequestPermissionRationale(). По моему опыту, shouldShowRequestPermissionRationale() возвращает true только после того, как пользователь один раз отказал в разрешении. Так что вам не дисплей обоснование интерфейса пользователя.
  • App звонки requestPermissions()
  • система попросит пользователя " разрешить приложению совершать и управлять телефонными звонками?"
  • пользователь решает, что это WAAAAAAY слишком страшно и нажимает кнопку Нет.
  • onRequestPermissionsResult() вызывается с результатом deny и mPermissionDenied получает набор.
  • onResumeFragments() получает вызов и диалоговое окно отображается пользователю, что они не могут получить бесплатную пробную версию, потому что приложение не имеет разрешение.
  • пользователь решает попробовать еще раз. doPermissionsStuff() называется.
  • App звонки checkSelfPermission() и (снова) определяет, что разрешение еще не предоставлено
  • App звонки shouldShowRequestPermissionRationale(). На этот раз он возвращает true.
  • приложение отображает успокаивающее и успокаивающее сообщение пользователю, что нет, мы не собираемся брать на себя ваш телефон, мы просто хотим, чтобы чертов номер IMEI, вот и все, и если вы не позволяете приложению получить доступ к IMEI, вы не получите бесплатную пробную версию. Я придется провести черту где-то.
  • пользователь нажимает продолжить, так что mHasReadRationale флаг имеет значение true и doPermissionsStuff() метод вызывается снова.
  • App звонки checkSelfPermission() и - угадайте, что? разрешение еще не предоставлено
  • поскольку флаг установлен, пользователь не получает обоснование UI.
  • App звонки requestPermissions()
  • система попросит пользователя " разрешить приложению совершать и управлять телефонными звонками?"
  • пользователь покоряется судьбе и нажимает "да".
  • onRequestPermissionsResult() вызывается с предоставленным результатом, и бесплатная пробная Регистрация продвигается вперед.

вы также должны проверить пример кода Google в https://developer.android.com/samples/RuntimePermissions/index.html