Firemonkey android read_phone_state运行时权限要求获取IMEI [英] Firemonkey android read_phone_state runtime permission asks to get IMEI

查看:145
本文介绍了Firemonkey android read_phone_state运行时权限要求获取IMEI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在运行时获取read_phone_state权限以获取IMEI号码?

How can I get read_phone_state permission at runtime to get IMEI number?

  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;

推荐答案

对不起,我没有在FireMonkey上做更多的功课.这就是我将注意力投向不属于它的主题的结果.我添加了此内容,以使我的答案更应得的赏金.

Sorry I didn't do a little more homework on FireMonkey. This is what I get for sticking my head into topics where it doesn't belong. I've added this content to try to make my answer more deserving of the bounty.

如果您可以将应用清单上的targetSdk限制为22(5.1 Lollipop),则用户将必须授予安装权限,因此HasPermission绝不应返回false. (不确定如何与FireMonkey配合使用.)

If you can restrict the targetSdk on the app manifest to 22 (5.1 Lollipop) then the user will have to grant the permission on install so HasPermission should never return false. (Not sure how that works with FireMonkey).

如果您想使用棉花糖+中的动态权限功能,这里是一些我从

If you want to use the dynamic permissions capabilities in Marshmallow+, here is some information that I gleaned from this page:

您需要有权使用Activity回调方法onRequestPermissionsResult.这是您必须克服的所有障碍:

You need to have access to the Activity callback method onRequestPermissionsResult. Here's all the hoops you will have to jump through:

  • 使用开源工具Dex2Jar将Android classes.dex文件从Delphi转换回Java,以便您可以针对FMXNativeActivity类进行编译.
  • 用Java编写FMXNativeActivity的子类,该子类定义了native方法(我们称其为onRequestPermissionsResultNative,并且覆盖了onRequestPermissionsResult方法以调用本机方法.
  • 运行javac以获得带有您的子类的.class文件
  • 运行jar将.class文件放入.jar文件
  • 运行dx.bat将您的.jar文件转换为Android .dex文件
  • 运行DexMerger将您的.dex文件合并到Delphi的classes.dex文件中
  • 现在剩下要做的就是编写一些棘手的Delphi代码来定义您的onRequestPermissionsResultNative方法并将其注册到JNI环境中.哦,别忘了在您的本机方法中切换到正确的线程.
  • Use the open-source tool Dex2Jar convert the Android classes.dex file from Delphi back to Java so you can compile against the FMXNativeActivity class.
  • Code a subclass of FMXNativeActivity in Java that defines a native method (let's call it onRequestPermissionsResultNative and also overrides the onRequestPermissionsResult method to call through to the native method.
  • run javac to get a .class file with your subclass
  • run jar to put the .class file into a .jar file
  • run dx.bat to turn your .jar file into an Android .dex file
  • run DexMerger to merge your .dex file into Delphi's classes.dex file
  • Now all that's left to do is to write some tricky Delphi code to define your onRequestPermissionsResultNative method and register it with the JNI Environment. Oh, and don't forget to switch to the correct thread in your native method.

我引用的链接显示了如何使用onActivityResult执行此操作.您必须将这些步骤调整为其他方法.

The link I referenced shows how to do this with onActivityResult. You'll have to adapt these steps for the other method.

我什至没有谈论过如何处理操作系统暂停您的应用程序以请求用户许可并在以后恢复它的方法.

And I haven't even talked about how to handle the OS pausing your app to ask the user for permission and resuming it after.

这是对所有人的一个教训:不要相信跨平台工具;不要相信跨平台工具.您会很失望的.

Let this be a lesson to all: Don't put your faith in cross-platform tools; you will be disappointed.

我在Java中工作的不是Delphi,因此您必须在这里进行一点推断.

I work in Java not Delp so you'll have to extrapolate a little bit here.

像您一样,我必须获取IMEI号码,然后系统对话框询问用户类似信息:允许应用程序拨打和管理电话吗?"我需要向用户说明该应用程序只是获取设备ID,而不会拨打或管理电话.所以

Like you, I have to get the IMEI number, and the system dialog asks the user something like: "Allow app to make and manage phone calls?" I need to explain to the user that that app is just getting the device ID and isn't going to make or manage phone calls. So

  • 检查您是否具有权限
  • 如果没有权限,请检查是否应显示说明
  • 如果不需要显示说明,请开始权限请求操作

我应该提到shouldShowRequestPermissionRationalerequestPermissionsActivity类上的方法.

I should mention that shouldShowRequestPermissionRationale and requestPermissions are methods on the Activity class.

    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. (对于取消",我将用户送回上一屏幕.)

In the positive button of this dialog (i.e. user wants to continue) set the mHasReadRationale flag to true and call doPermissionsStuff again. (For Cancel, I send the user back to the previous screen.)

为了获得requestPermissions操作的结果,您需要覆盖ActivityonRequestPermissionsResult方法:

In order to get the result of the requestPermissions operation you need to override the Activity's onRequestPermissionsResult method:

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

显然,当系统向用户询问权限时,它会停止您的应用程序,因此您此时无法显示UI来告诉用户您没有权限.因此,我设置了一个标志,当应用恢复时,然后告诉用户该应用无权执行操作.

Apparently when the system asks the user for the permission, it stops your app, so you can't show a UI at that point to tell the user you don't have permission. So I set a flag and when the app resumes, then I tell the user that the app doesn't have permission to do the operation.

@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,这样他们就无法一遍又一遍地获得免费试用,jeez.应用调用doPermissionsStuff().
  • 应用程序调用checkSelfPermission()并确定尚未授予该权限
  • 应用调用shouldShowRequestPermissionRationale().以我的经验,shouldShowRequestPermissionRationale()仅在用户拒绝一次权限后才返回true.因此,您尚未向用户显示基本界面.
  • 应用调用requestPermissions()
  • 系统将询问用户是否允许应用程序拨打和管理电话?"
  • 用户认为这太可怕了,然后按否"按钮.
  • 调用
  • onRequestPermissionsResult()并显示拒绝结果,并设置mPermissionDenied.
  • onResumeFragments()被调用,并向用户显示一个对话框,提示他们由于该应用没有权限而无法获得免费试用.
  • 用户决定重试. doPermissionsStuff()被调用.
  • 应用程序调用checkSelfPermission(),并且(再次)确定尚未授予该权限
  • 应用调用shouldShowRequestPermissionRationale().这次返回true.
  • 应用程序向用户显示了一个令人放松和放松的信息,否,我们不会接管您的电话,我们只想要那些怪异的IMEI号码,仅此而已,如果您不允许该应用程序访问IMEI,您将无法获得免费试用.我必须在某处画一条线.
  • 用户继续按下,因此将mHasReadRationale标志设置为true,并再次调用doPermissionsStuff()方法.
  • 应用调用checkSelfPermission()和—你猜怎么了?该权限尚未授予
  • 由于设置了该标志,用户无法获得基本原理UI.
  • 应用调用requestPermissions()
  • 系统将询问用户是否允许应用程序拨打和管理电话?"
  • 用户放弃自我命运,然后按是".
  • 会调用
  • onRequestPermissionsResult()并授予结果,免费试用注册会继续进行.
  • User wants a free trial & app needs to get IMEI so they can't keep getting the free trial over and over again, jeez. App calls doPermissionsStuff().
  • App calls checkSelfPermission() and determines the permission isn't granted yet
  • App calls shouldShowRequestPermissionRationale(). In my experience, shouldShowRequestPermissionRationale() only returns true after the user has denied the permission once. So you don't display the rationale UI to the user yet.
  • App calls requestPermissions()
  • The system will ask the user "Allow application to make and manage phone calls?"
  • User decides this is WAAAAAAY too scary and presses the No button.
  • onRequestPermissionsResult() is called with the deny result and the mPermissionDenied gets set.
  • onResumeFragments() gets called and a dialog is displayed to the user that they can't get the free trial because the app doesn't have permission.
  • User decides to try again. doPermissionsStuff() is called.
  • App calls checkSelfPermission() and (again) determines the permission isn't granted yet
  • App calls shouldShowRequestPermissionRationale(). This time it returns true.
  • App displays a calming and soothing message to the user that no, we aren't going to take over your phone, we just want the freakin' IMEI number, that's all, and if you don't allow the app to access the IMEI, you don't get a free trial. I have to draw the line somewhere.
  • User presses continue, so the mHasReadRationale flag is set to true and doPermissionsStuff() method gets called again.
  • App calls checkSelfPermission() and — guess what? the permission isn't granted yet
  • Since the flag is set, the user doesn't get the rationale UI.
  • App calls requestPermissions()
  • The system will ask the user "Allow application to make and manage phone calls?"
  • User resigns self to fate and presses Yes.
  • onRequestPermissionsResult() is called with the granted result and the free trial registration moves forward.

您还应该在 https://developer.android中查看Google的示例代码. com/samples/RuntimePermissions/index.html

这篇关于Firemonkey android read_phone_state运行时权限要求获取IMEI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆