0

I'm developing an Android library for Unity3D, and I have problems in checking Audio Permission. At first I used ContextCompat.checkSelfPermission(), but failed: the problem was:

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."

After updating API, the using of android.support.v4.content.ContextCompat is confusing, and after adding android-support-v4.jar, the problem was fixed.I can either use ContextCompat.checkSelfPermission or PermissionChecker.checkCallingOrSelfPermission or PermissionChecker.checkSelfPermission, no other error exists, but its value always return PERMISSION_GRANTED. Then I tried to use PermissionChecker.checkSelfPermission() instead in Cannot resolve method “checkSelfPermission” with adding android-support-v4.jar, it just seemed like that everything turns ok: I got the result of check which was PERMISSION_GRANTED, however after that when I tried to deny the permission, the check still returned PERMISSION_GRANTED. By the way, I've distinguished different API lvl, here are my codes:

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

Here is my 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')
}

If my question is not clear or you need more details, please comment to let me know, I'll try my best to help you to help me, thanks a lot!

Hong Duan
  • 4,234
  • 2
  • 27
  • 50

4 Answers4

1

Run Time permissions are introduced in Android 6.0(23). On a device below Android 6.0 it suffices to ask permissions inside AndroidManifest.xml file. It autmatically returns granted.If your targetSdk is 23 or above you need to ask Run Time permissions but if user's device is less than 23 asking permission in run time is ignored and you are granted the permission if it's asked inside AndroidManifest.xml

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Tanks for URL, I've read it carefully and I can't get solutions for lower API. And now I know the exact reason: Ignoring, thank you. – David.Forster Oct 16 '17 at 06:57
  • There is no solution for lower APIs because that feature is implemented in Android 6.0 because users complaining about security, accessing their files, etc. Privacy Policies and run time permissions are introduced to give users more control over their devices and to be aware of why permissions asked. There is no Run Time permission for previous versions also means there is no solution or you are automatically granted the solution. – Thracian Oct 16 '17 at 07:02
0

as @Faith said Run time permission api is not available under api 23 ,permissions declared in manifest file is enough.

himel
  • 500
  • 5
  • 14
  • Thanks, but I still want to check permission to make sure if user wants to use record function in run-time to call back :) – David.Forster Oct 16 '17 at 06:51
0

All the permission in android are added in API 23 and below this API all the permissions are granted already via manifest. so we need to check API version of user device running OS version in android device. Android official document : click here and i suggest to use this library its handy and easy to use.

https://github.com/NikhilJogdand/PermissionManager

All the callback and os version checking related task is performed by this library.

0

You can use RxPermissions to grant permissions in your app.It is very easy to use

RxPermissions rxPermissions = new RxPermissions(this);

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

For more information follow this link https://github.com/tbruyelle/RxPermissions

AbhayBohra
  • 2,047
  • 24
  • 36
  • Thanks for your advise, I'm trying and get some problems in "subscribe": cant resolve method 'subscribe ()', and the 2nd "granted" is Incompatible types: boolean is required not . How can I fix them? – David.Forster Oct 16 '17 at 07:53
  • Did you add gradle dependancy for rxPermissions library? – AbhayBohra Oct 16 '17 at 07:57
  • yep:
    dependencies {compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
    }
    repositories { jcenter() // If not already there
    }
    – David.Forster Oct 16 '17 at 07:58
  • Then I added compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } in gradle, new error exists: java.lang.NoClassDefFoundError: io.reactivex.Observable, finally this Answer saved me: https://stackoverflow.com/questions/42048520/rxandroid-and-retrofit-unable-to-create-call-adapter-for-io-reactivex-observabl – David.Forster Oct 16 '17 at 08:35
  • And need newest me.tatarka.retrolambda: https://plugins.gradle.org/plugin/me.tatarka.retrolambda – David.Forster Oct 16 '17 at 09:15