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