androidandroid-jetpack-composeandroid-resourcesmulti-module

Android multi-module: How to get the title of a 'game' in the database?


I am building a multimodule gameapp with Compose and Koin dependency injection. Every module manages its own screens and navigation. The structure is this:

app:
core:
|- common
feature:
|-games:
| |-general:
| |-meaninggame:
| |-completiongame:
|
|-highscores

etc.

There are multiple gamemodes, each implemented as a seperate module. MeaningGame and Completiongame are examples of those. Each gamemodule has to implement an interface so it can be registered in the list of games.

GameApi:

interface GameApi {

    fun registerGame(
        navGraphBuilder: NavGraphBuilder,
        navController: NavHostController,
        modifier: Modifier = Modifier
    )

    fun gameRoute():GameRoutes

    fun title(): Int

    fun id():Int
}

The gameRoute() returns the route to navigate to the game, the id() the unique id of the game. This id is used to store the score of the game on a server, show a list of highscores (retrieved from the server) etc. And the title() returns the resource-identifier from R.string.title. This resource file is contained in the module.

The problem is this. In the highscore module I want to show the title of the game in the language of the user. So if an American watches the highscores, he sees the title in English, but a German would see the German variant, a Frenchman the French variant and so on.

How can I access the resource from a gamemodule in the highscore module?

I tried to build a function in the gameApi Interface to register the string in a local database (which would be in the core: module) but I am unsuccesfull as I do not have access to the Context in the gameApi implementation, so stringResource does not work and context.resources.getString(..) also does not work.

Does anyone has an idea?


Solution

  • So usually i would define the string resource with other localization

    you can see more in this documentation String Localization.Then i would modify the title with parameter Locale, Then if you can't access the Context for some reason, give the context responsible to other's using dependency injection usually i use koin but you can use other thing.

    for example

    interface GameApi {
    
        fun registerGame(
            navGraphBuilder: NavGraphBuilder,
            navController: NavHostController,
            modifier: Modifier = Modifier
        )
    
        fun gameRoute():GameRoutes
    
        //return string, so we don't need to care what id need to be used
        fun title(locale: Locale): String
    
        fun id():Int
    }
    //the impl
    class HighscoreGameApi(context: Context) : GameApi{
    
       private val applicationContext = context.applicationContext
       //other code
    
       override fun title(locale: Locale): String {
          val config = applicationContext.resources.configuration
          config.setLocale(locale)
          val localizedResource = applicationContext.createConfigurationContext(config).resources
          return localizedResource.getString(R.string.the_title_text)
       }
    }
    //injection
    //im using koin, this is just registering the module
    //not the full implementation of koin injection, see more
    //https://insert-koin.io/docs/reference/koin-android
    val gameModules = modules {
       single {
          HighscoreGameApi(androidContext())
       }
    }
    
    

    Hope this helpful