Search code examples
androidkotlinsharedpreferencesandroid-context

Get shared preferences without context


Good evening everyone! I want to use shared preferences to store my token(I know that this is not secure, I am new in android development and just want to try) and then pass it to the interceptor. How can I initialize shared preferences there? Thank you! Or can you give me a tips how I can implement interceptor or store token.

Sorry, I already tried to search for this topic, and was not able to implement methods of other developers.

object NetworkModule {

    var sharedPreferences = //GET SHARED PREFERENCES THERE

    var authToken: String? = sharedPreferences.getString("Token", null)
    val baseURL = //my base url

    
    val loggingInterceptor = HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.BODY
    }


    var httpClient = OkHttpClient.Builder().addInterceptor { chain ->
        chain.proceed(
            chain.request().newBuilder().also { it.addHeader("Authorization", "Bearer $authToken") }
                .build()
        )
    }.connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .addNetworkInterceptor(loggingInterceptor)
        .build()

    val retrofit = Retrofit.Builder().baseUrl(baseURL).addConverterFactory(
        GsonConverterFactory.create()
    ).client(httpClient).build()


    val api: API by lazy { retrofit.create() }
    val apiClient = ApiClient(api)
}

Solution

  • You can access SharedPreferences anywhere from your app using ApplicationContext. It is a very common practice in Android Development and it is very safe.

    To access ApplicationContext see code below:

    1. In your Application class, add an Application Singleton.

      class MyApplication : Application() {
           override fun onCreate() {
              super.onCreate()
              instance = this
           }
      
           companion object {
               lateinit var instance: MyApplication
                   private set
           }
      }
      

      (What is an Application Class?)

    2. Use ApplicationContext anywhere within your app!

      var sharedPreferences = getApplicationContext() //here you go!
      

    This code does the job, however, if you are interested in Best Android development practices, please read this:

    Recommended 2 Options

    1. Best Practice: Create a new Manager class that is responsible for app's entire SharedPreferences usage (ex. SharedPreferenceManager). This class is a Singleton Class that is instantiated with ApplicationContext and has all the methods related CRUD operations in SharedPreferences, in your case setToken and getToken. Since the manager class is independent, it should not cause any Lifecycle errors or NullPointer errors.

      Since attaching sample code will clutter my answer, I decided to cite someone else's code here, this will teach you how to implement it.

    2. If you are too lazy to follow #2: You can use a library that has done that for you already: Pixplicity/EasyPrefs.

      • Easy to use like Manager Class ✅
      • No more errors related to SharedPreferences
      • You could always retrofit into any existing project ✅

    Let me know if you have any questions. Thanks.