Permissão de tempo de execução do firmware read_phone_state do Firemonkey pede para obter IMEI - android, delphi, permissões, firemonkey, delphi-10.2-tokyo

Como posso obter permissão read_phone_state em tempo de execução para obter o número 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;

Respostas:

3 para resposta № 1

EDITAR:Desculpe eu não fiz um pouco mais de lição de casa no FireMonkey. Isso é o que eu ganho por furar minha cabeça em tópicos onde ele não pertence. Eu adicionei este conteúdo para tentar fazer a minha resposta mais merecedora da recompensa.

Se você puder restringir targetSdk no manifesto do aplicativo para 22 (5.1 Lollipop), em seguida, o usuário terá que conceder a permissão de instalação para HasPermission nunca deve retornar falso. (Não sei como isso funciona com o FireMonkey).

Se você quiser usar os recursos de permissões dinâmicas no Marshmallow +, aqui estão algumas informações que eu obtive esta página:

Você precisa ter acesso ao Activity método de retorno de chamada onRequestPermissionsResult. Aqui estão todos os aros que você terá que passar:

  • Use a ferramenta de código aberto Dex2Jar converter o Android classes.dex arquivo de Delphi de volta para Java para que você possa compilar contra o FMXNativeActivity classe.
  • Codifique uma subclasse de FMXNativeActivity em Java que define um native método (vamos chamá-lo onRequestPermissionsResultNative e também substitui o onRequestPermissionsResult método para chamar através do método nativo.
  • corre javac obter um arquivo .class com sua subclasse
  • corre jar colocar o arquivo .class em um arquivo .jar
  • corre dx.bat para transformar seu arquivo .jar em um arquivo .dex do Android
  • corre DexMerger mesclar seu arquivo .dex no arquivo classes.dex do Delphi
  • Agora tudo o que resta a fazer é escrever algum código Delphi complicado para definir o seu onRequestPermissionsResultNative método e registrá-lo com o ambiente JNI. Ah, e não se esqueça de mudar para o segmento correto em seu método nativo.

O link que referi mostra como fazer isso com onActivityResult. Você terá que adaptar essas etapas para o outro método.

E eu ainda não falei sobre como lidar com o sistema operacional pausando seu aplicativo para pedir permissão ao usuário e retomar o mesmo depois.

Que isso seja uma lição para todos: não ponha sua fé em ferramentas multiplataformas, você ficará desapontado.


Eu trabalho em Java e não em Delphi, então você terá que extrapolar um pouco aqui.

Como você, eu tenho que pegar o número IMEI, e oA caixa de diálogo do sistema pergunta ao usuário algo como: "Permitir que o aplicativo faça e gerencie chamadas telefônicas?" Preciso explicar ao usuário que esse aplicativo está apenas obtendo o ID do dispositivo e não vai fazer ou gerenciar chamadas telefônicas.

  • Verifique se você tem permissão
  • Se você não tem a permissão, verifique se você deve exibir uma explicação
  • Se você não precisar mostrar uma explicação, inicie a operação de solicitação de permissão

Devo mencionar que shouldShowRequestPermissionRationale e requestPermissions são métodos no Activity classe.

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

No botão positivo desta caixa de diálogo (ou seja, o usuário deseja continuar), defina mHasReadRationale sinalizar para verdadeiro e ligar doPermissionsStuff novamente. (Para Cancelar, envio o usuário de volta à tela anterior.)

Para obter o resultado do requestPermissions operação você precisa substituir o Activity"s onRequestPermissionsResult método:

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

Aparentemente, quando o sistema pede ao usuário peloCom a permissão, ele interrompe seu aplicativo, então você não pode mostrar uma interface do usuário nesse momento para informar ao usuário que você não tem permissão. Então eu defino uma bandeira e quando o aplicativo recomeça então Eu digo ao usuário que o aplicativo não tem permissão para fazer a operação.

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

Então aqui está um exemplo de fluxo:

  • O usuário quer uma avaliação gratuita e o aplicativo precisa receber o IMEI para que não continue recebendo a avaliação gratuita repetidas vezes. doPermissionsStuff().
  • Chamadas de aplicativos checkSelfPermission() e determina que a permissão ainda não foi concedida
  • Chamadas de aplicativos shouldShowRequestPermissionRationale(). Em minha experiência, shouldShowRequestPermissionRationale() só retorna true depois que o usuário negou a permissão uma vez. Portanto, você não exibe a interface lógica para o usuário ainda.
  • Chamadas de aplicativos requestPermissions()
  • O sistema perguntará ao usuário "Permitir que o aplicativo faça e gerencie chamadas telefônicas?"
  • O usuário decide que o WAAAAAAY é assustador demais e pressiona o botão Não.
  • onRequestPermissionsResult() é chamado com o resultado da negação e o mPermissionDenied fica definido.
  • onResumeFragments() é chamado e um diálogo é exibido para o usuário que eles não podem obter o teste gratuito porque o aplicativo não tem permissão.
  • O usuário decide tentar novamente. doPermissionsStuff() é chamado.
  • Chamadas de aplicativos checkSelfPermission() e (novamente) determina que a permissão ainda não foi concedida
  • Chamadas de aplicativos shouldShowRequestPermissionRationale(). Desta vez, ele retorna verdadeiro.
  • App exibe uma mensagem calmante e suave parao usuário que não, nós não estamos indo para assumir o seu telefone, nós só queremos o maldito "IMEI número, que é tudo, e se você não permitir que o aplicativo para acessar o IMEI, você don t get a teste gratuito. Eu tenho que desenhar a linha algum lugar.
  • Usuário pressiona continuar, então o mHasReadRationale flag é definido como true e doPermissionsStuff() método é chamado novamente.
  • Chamadas de aplicativos checkSelfPermission() e adivinha? a permissão ainda não foi concedida
  • Como o sinalizador está definido, o usuário não obtém a interface lógica.
  • Chamadas de aplicativos requestPermissions()
  • O sistema perguntará ao usuário "Permitir que o aplicativo faça e gerencie chamadas telefônicas?"
  • O usuário renuncia ao destino e pressiona Sim.
  • onRequestPermissionsResult() é chamado com o resultado concedido e o registro de teste gratuito avança.

Você também deve verificar o código de amostra do Google em https://developer.android.com/samples/RuntimePermissions/index.html


Perguntas relacionadas
Cardápio