Firemonkey android read_phone_state运行时权限要求获取IMEI

2023-12-27

如何在运行时获得 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;

编辑:抱歉我没有在 FireMonkey 上做更多的功课。这就是我把注意力集中在不属于它的话题上所得到的结果。我添加此内容是为了使我的答案更值得赏金。

如果你可以限制targetSdk将应用程序清单上的 22 (5.1 Lollipop) 设置为 22 (5.1 Lollipop),然后用户必须授予安装权限,以便HasPermission永远不应该返回 false。 (不知道 FireMonkey 是如何工作的)。

如果您想使用 Marshmallow+ 中的动态权限功能,这里是我收集的一些信息这一页 http://blong.com/Articles/DelphiXE5AndroidActivityResult/ActivityResult.htm#HandlingResult:

您需要有权访问Activity回调方法onRequestPermissionsResult。以下是您必须跨越的所有障碍:

  • 使用开源工具Dex2Jar转换Androidclasses.dex文件从 Delphi 返回到 Java,以便您可以针对FMXNativeActivity class.
  • 编写子类的代码FMXNativeActivity在Java中定义了一个native方法(我们称之为onRequestPermissionsResultNative并且还覆盖onRequestPermissionsResult方法来调用本机方法。
  • run javac获取包含子类的 .class 文件
  • run jar将 .class 文件放入 .jar 文件中
  • run dx.bat将您的 .jar 文件转换为 Android .dex 文件
  • run DexMerger将.dex 文件合并到Delphi 的classes.dex 文件中
  • 现在剩下要做的就是编写一些棘手的 Delphi 代码来定义您的onRequestPermissionsResultNative方法并将其注册到 JNI 环境。哦,不要忘记在本机方法中切换到正确的线程。

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

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

让这成为所有人的一个教训:不要相信跨平台工具;不要相信跨平台工具。你会失望的。


我使用 Java 而不是 Delphi,所以你必须在这里进行一些推断。

和你一样,我必须获取 IMEI 号码,系统对话框会询问用户类似以下内容:“允许应用拨打和管理电话吗?”我需要向用户解释该应用程序只是获取设备 ID,不会拨打或管理电话。所以

  • 检查是否有权限
  • 如果您没有权限,请检查是否应该显示说明
  • 如果不需要出示说明,则启动权限请求操作

我应该提一下shouldShowRequestPermissionRationale and requestPermissions是方法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再次。 (对于取消,我将用户带回到上一个屏幕。)

为了得到结果requestPermissions您需要覆盖的操作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 来告诉用户您没有权限。所以我设置了一个标志,当应用程序恢复时,then我告诉用户该应用程序没有执行该操作的权限。

@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().
  • 应用程序调用checkSelfPermission()并确定尚未授予权限
  • 应用程序调用shouldShowRequestPermissionRationale()。在我的经验中,shouldShowRequestPermissionRationale()仅在用户拒绝一次权限后返回 true。因此,您还没有向用户显示基本原理 UI。
  • 应用程序调用requestPermissions()
  • 系统将询问用户“允许应用程序拨打和管理电话吗?”
  • 用户认为这太可怕了,并按下“否”按钮。
  • onRequestPermissionsResult()被调用并返回拒绝结果mPermissionDenied设置完毕。
  • onResumeFragments()被调用并向用户显示一个对话框,表明他们无法获得免费试用,因为该应用程序没有权限。
  • 用户决定再试一次。doPermissionsStuff()叫做。
  • 应用程序调用checkSelfPermission()并(再次)确定尚未授予许可
  • 应用程序调用shouldShowRequestPermissionRationale()。这次返回true。
  • 应用程序会向用户显示一条平静且舒缓的消息,表明不,我们不会接管您的手机,我们只是想要该死的 IMEI 号码,仅此而已,如果您不允许该应用程序访问 IMEI,您无法获得免费试用。我必须划清界限某处.
  • 用户按下继续,所以mHasReadRationale标志设置为 true 并且doPermissionsStuff()方法再次被调用。
  • 应用程序调用checkSelfPermission()你猜怎么着?尚未授予该权限
  • 由于设置了该标志,用户不会获得基本原理 UI。
  • 应用程序调用requestPermissions()
  • 系统将询问用户“允许应用程序拨打和管理电话吗?”
  • 用户听天由命并按“是”。
  • onRequestPermissionsResult()被调用并获得已授予的结果,免费试用注册将继续进行。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Firemonkey android read_phone_state运行时权限要求获取IMEI 的相关文章

随机推荐