【问题标题】:Can't check permission correctly at API Level < 23无法在 API 级别 < 23 正确检查权限
【发布时间】:2017-10-16 05:10:26
【问题描述】:

我正在为 Unity3D 开发 Android 库,但在检查音频权限时遇到问题。 起初我使用 ContextCompat.checkSelfPermission(),但失败了: 问题是:

10-16 13:46:39.466 856-939/? E/Unity: AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/ContextCompat;
                                          java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/ContextCompat;
                                              at com.magikid.unityplugin.RecordManager.isGotRecordPermission(RecordManager.java:431)
                                              at com.magikid.unityplugin.RecordManager.RequestRecordPermission(RecordManager.java:370)
                                              at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
                                              at com.unity3d.player.UnityPlayer.c(Unknown Source)
                                              at com.unity3d.player.UnityPlayer$c$1.handleMessage(Unknown Source)
                                              at android.os.Handler.dispatchMessage(Handler.java:107)
                                              at android.os.Looper.loop(Looper.java:194)
                                              at com.unity3d.player.UnityPlayer$c.run(Unknown Source)
                                           Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.ContextCompat" on path: DexPathList[[zip file "/data/app/com.magikid.channel-1/base.apk"],nativeLibraryDirectories=[/data/app/com.magikid.channel-1/lib/arm, /vendor/lib, /system/lib]] at dalvik."

更新API后,android.support.v4.content.ContextCompat的使用比较混乱,添加android-support-v4.jar后问题解决了。我可以使用ContextCompat.checkSelfPermission或者PermissionChecker.checkCallingOrSelfPermission或者PermissionChecker.checkSelfPermission,不存在其他错误,但它的值总是返回PERMISSION_GRANTED。 然后我尝试在 Cannot resolve method “checkSelfPermission” 中使用 PermissionChecker.checkSelfPermission() 并添加 android-support-v4.jar,看起来一切正常:我得到了 PERMISSION_GRANTED 的检查结果,但是在那之后,当我试图拒绝该权限时,检查仍然返回PERMISSION_GRANTED。 顺便说一句,我已经区分了不同的 API lvl,这是我的代码:

public class AppUtils 
{
  private static Application application;

  public static void setApplication(Application application) 
  {
    try 
    {
      if (AppUtils.application == null) 
      {
        AppUtils.application = application;
      } 
      else 
      {
        throw new IllegalStateException("Application already holded 'application'.");
      }
    } 
    catch (Exception e) 
    {
      Log.e("UnityDebugSetApp", String.valueOf(e));
    }
  }
}
public class RecordManager
{
  public static Context getContext() 
  {
    return application.getApplicationContext();
  }

  //This method is to judge if user allows permission
  public static boolean isGotRecordPermission()
  {
    Activity activity = UnityPlayer.currentActivity;
    String permissionName = "android.permission.RECORD_AUDIO";
    String pkgName = activity.getPackageName();
    if (Build.VERSION.SDK_INT  >= 23) 
    {
      return PackageManager.PERMISSION_GRANTED == getAppContext().checkCallingOrSelfPermission (permissionName);
    } 
    else 
    {
      return PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkCallingOrSelfPermission (getAppContext(), permName);
    }
  }
}

这是我的 build.gradle:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk {
            abiFilters  "armeabi-v7a", "armeabi"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
}

dependencies {
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'
    provided files('libs/classes.jar')
    compile files('libs/wechat-sdk.jar')
    compile files('libs/flame.jar')
    compile files('libs/android-support-v4.jar')
}

如果我的问题不清楚或者您需要更多详细信息,请评论让我知道,我会尽力帮助您帮助我,非常感谢!

【问题讨论】:

  • ContextCompat.checkSelfPermission() 有什么问题?你遇到了什么错误?
  • 亲爱的@AbhayBohra,我已经为你更新了信息,谢谢。

标签: java android unity3d permissions


【解决方案1】:

Run Time permissions 在 Android 6.0(23) 中引入。在 Android 6.0 以下的设备上,只需在 AndroidManifest.xml 文件中询问权限即可。它自动返回已授予。如果您的 targetSdk 为 23 或更高,您需要询问运行时权限,但如果用户的设备小于 23,则在运行时询问权限将被忽略,如果在 AndroidManifest.xml 中询问,您将被授予权限

【讨论】:

  • URL 的坦克,我已经仔细阅读了,我无法获得较低 API 的解决方案。现在我知道了确切的原因:忽略,谢谢。
  • 没有针对较低 API 的解决方案,因为该功能是在 Android 6.0 中实现的,因为用户抱怨安全性、访问他们的文件等。引入了隐私政策和运行时权限,以便用户更好地控制他们的设备并了解请求权限的原因。以前版本没有运行时权限也意味着没有解决方案,或者您被自动授予解决方案。
【解决方案2】:

正如@Faith所说,运行时权限api在api 23下不可用,清单文件中声明的权限就足够了。

【讨论】:

  • 谢谢,但我仍然想检查权限以确保用户是否想在运行时使用记录功能进行回调:)
【解决方案3】:

android 中的所有权限都添加到 API 23 中,并且在此 API 之下,所有权限都已通过清单授予。 所以我们需要在安卓设备上检查运行操作系统版本的用户设备的 API 版本。 安卓官方文档:click here 我建议使用 这个库很方便且易于使用。

https://github.com/NikhilJogdand/PermissionManager

所有回调和操作系统版本检查相关任务都由这个库执行。

【讨论】:

    【解决方案4】:

    您可以使用 RxPermissions 在您的应用中授予权限。它非常易于使用

    RxPermissions rxPermissions = new RxPermissions(this);
    
    rxPermissions
        .request(Manifest.permission.RECORD_AUDIO)
        .subscribe(granted -> {
            if (granted) { 
                // Permission Granted
            } else {
               // Permission denied
            }
        });
    

    更多信息请点击此链接 https://github.com/tbruyelle/RxPermissions

    【讨论】:

    • 感谢您的建议,我正在尝试在“订阅”中遇到一些问题:无法解析方法“订阅()”,第二个“授予”是不兼容的类型:布尔不需要 。我该如何解决它们?
    • 你是否为 rxPermissions 库添加了 gradle 依赖?
    • 是的:
      dependencies {compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
      }
      repositories { jcenter() // 如果还没有}
    • 然后我在 gradle 中添加了 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 },存在新错误:java.lang.NoClassDefFoundError: io.reactivex.Observable,最后这个答案救了我:stackoverflow.com/questions/42048520/…
    • 需要最新的me.tatarka.retrolambda:plugins.gradle.org/plugin/me.tatarka.retrolambda
    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 2018-01-09
    • 2012-05-26
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多