J A S K I E R
J A S K I E R

Reputation: 2184

How to fix Resources$NotFoundException: String resource in Kotlin without context?

Android, Kotlin.

I want to use the RestApiService file for requests and send String value from the strings.xml file further as like that:

fun showPostsInRadius(modelSearchParams: ModelSearch, onResult: (Array<Post>?, Boolean, String?) -> Unit){

    val retrofit = ServiceBuilder.buildService(RestApi::class.java)
    retrofit.showPostsInRadius(Build.VERSION.SDK_INT, modelSearchParams).enqueue(

        object : Callback<Array<ModelSearchResult>> {

            override fun onFailure(call: Call<Array<ModelSearchResult>>, t: Throwable) {
                onResult(null, false, Resources.getSystem().getString(R.string.connection_error_login))
                println(t)
            }
...

This line gives error:

onResult(null, false, Resources.getSystem().getString(R.string.connection_error_login))

Error:

W/ResourceType: No known package when getting value for resource number 0x7f0f003c
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.jaskierltd.goodtogether, PID: 15205
    android.content.res.Resources$NotFoundException: String resource ID #0x7f0f003c
        at android.content.res.Resources.getText(Resources.java:338)
        at android.content.res.Resources.getString(Resources.java:432)
        at com.jaskierltd.goodtogether.network.RestApiService$showPostsInRadius$1.onFailure(RestApiService.kt:145)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$2.run(ExecutorCallAdapterFactory.java:79)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Should I configure anything related to strings.xml file or should I call this with another method? None of existing topics helped.

Upvotes: 0

Views: 1533

Answers (3)

I had the same issue as you and found to be better to save this kind of string in a Constant.kt file, like const val CONNECTION_ERROR = "Your error message". I use the strings.xml file for storing strings which populates the layouts.

Upvotes: 0

clamum
clamum

Reputation: 1364

I think this can depend on your exact context, but for me, I was getting this Exception while trying to set a String resource in my ViewModel.

As @CommonsWare said in a comment above, I tweaked my design slightly so my UI (Composable; I'm using Jetpack) does the conversion from the Int, since Composable functions have access to the stringResource() method.

So in my ViewModel class (TextFieldState is a data class that just holds the text value/hint for my custom text fields):

private val _firearmInitialShotCount = mutableStateOf(TextFieldState(
        hint = R.string.enter_firearm_initial_shot_count
    ))
    val firearmInitialShotCount: State<TextFieldState> = _firearmInitialShotCount

data class TextFieldState(
    val text: String = "",
    val hint: Int = 0,
    val isHintVisible: Boolean = true
)

Then in my Composable function (TransparentHintTextField is just a custom composable that adds a hint to the BasicTextField):

val initialShotCountState = viewModel.firearmInitialShotCount.value

TransparentHintTextField(
                text = initialShotCountState.text,
                hint = stringResource(id = initialShotCountState.hint),
...

Hopefully that helps someone. I know mine is particular to my case, but the idea is to hold the String Resource Int in code and then in the Composable call stringResource() on your Int.

Upvotes: 0

J A S K I E R
J A S K I E R

Reputation: 2184

Since no-one provided any answer how to avoid context, the only way is to use context or get the ID of the STRING object and send back.

Option #1:

// Place anywhere you want to get the String
fun getID(): Int{
   R.string.error_no_location
}

// Use this inside Activity
println(getString(getID()))

Option #2:

fun getID(context: Context){
   println(context.getString(R.string.error_no_location))
}

Upvotes: 2

Related Questions