无法在API级别正确检查权限< 23

时间:2017-10-16 05:10:27

标签: java android unity3d permissions

我正在为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')
}

如果我的问题不明确或您需要更多详情,请发表评论告诉我,我会尽力帮助您,非常感谢!

4 个答案:

答案 0 :(得分:1)

Android 6.0(23)中引入了

Run Time permissions。在Android 6.0以下的设备上,只需在AndroidManifest.xml文件中询问权限即可。它自动返回grant.If你的targetSdk是23或更高,你需要询问运行时权限,但如果用户的设备小于23,则忽略运行时间的请求权限,如果在AndroidManifest.xml中询问,则授予您权限

答案 1 :(得分:0)

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

答案 2 :(得分:0)

Android中的所有权限都在API 23中添加,在此API下方,所有权限都已通过清单授予。 所以我们需要检查在Android设备上运行OS版本的用户设备的API版本。 Android官方文档:click here 我建议使用 这个库很方便易用。

https://github.com/NikhilJogdand/PermissionManager

所有回调和os版本检查相关的任务都由此库执行。

答案 3 :(得分:0)

您可以使用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