The newest solution with java 17 (I guess it helps from java 11 but didn't test it)
Just follow the steps:
1.Add the universal methods to your code
fun setStaticFieldViaReflection(field: Field, value: Any) { field.isAccessible = true getModifiersField().also { it.isAccessible = true it.set(field, field.modifiers and Modifier.FINAL.inv()) } field.set(null, value) } fun getModifiersField(): Field { return try { Field::class.java.getDeclaredField("modifiers") } catch (e: NoSuchFieldException) { try { val getDeclaredFields0: Method = Class::class.java.getDeclaredMethod( "getDeclaredFields0", Boolean::class.javaPrimitiveType ) getDeclaredFields0.isAccessible = true val fields = getDeclaredFields0.invoke(Field::class.java, false) as Array<Field> for (field in fields) { if ("modifiers" == field.name) { return field } } } catch (ex: ReflectiveOperationException) { e.addSuppressed(ex) } throw e } }
2.Add these flags to gradle (it can be changed for other java classes)
android { ... testOptions { unitTests.all { jvmArgs( "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED" ) } } }
3.Examples of using
//SDK_INT setStaticFieldViaReflection(Build.VERSION::class.java.getDeclaredField("SDK_INT"), 30) //SOC_MANUFACTURER private val testSocManufacturer = "test-soc-manufacturer" setStaticFieldViaReflection(Build::class.java.getDeclaredField("SOC_MANUFACTURER"), testSocManufacturer) //SOC_MODEL private val testSocModel = "test-soc-model" setStaticFieldViaReflection(Build::class.java.getDeclaredField("SOC_MODEL"), testSocModel)