Home > Mobile >  android.content.SharedPreferences is not nullable, but is being provided by @Singleton @Provides @or
android.content.SharedPreferences is not nullable, but is being provided by @Singleton @Provides @or

Time:09-02

I am developing new app and implemented shared preferences in my appModule.kt but when I run project I am getting following errors

Task :app:hiltJavaCompileDebug C:\Users\Yodgorbek\RunTrackerApp\app\build\generated\hilt\component_sources\debug\com\example\runtrackerapp\BaseApplication_HiltComponents.java:136: error: [Dagger/Nullable] android.content.SharedPreferences is not nullable, but is being provided by @Singleton @Provides @org.jetbrains.annotations.Nullable android.content.SharedPreferences com.example.runtrackerapp.di.AppModule.provideSharedPreferences(@dagger.hilt.android.qualifiers.ApplicationContext android.content.Context) public abstract static class SingletonC implements BaseApplication_GeneratedInjector, ^ android.content.SharedPreferences is injected at com.example.runtrackerapp.di.AppModule.provideWeight(sharedPref) java.lang.Float is injected at com.example.runtrackerapp.ui.fragments.TrackingFragment.setWeight(<set-?>) com.example.runtrackerapp.ui.fragments.TrackingFragment is injected at com.example.runtrackerapp.ui.fragments.TrackingFragment_GeneratedInjector.injectTrackingFragment(com.example.runtrackerapp.ui.fragments.TrackingFragment) [com.example.runtrackerapp.BaseApplication_HiltComponents.SingletonC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityRetainedC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityC ? com.example.runtrackerapp.BaseApplication_HiltComponents.FragmentC] C:\Users\Yodgorbek\RunTrackerApp\app\build\generated\hilt\component_sources\debug\com\example\runtrackerapp\BaseApplication_HiltComponents.java:136: error: [Dagger/Nullable] android.content.SharedPreferences is not nullable, but is being provided by @Singleton @Provides @org.jetbrains.annotations.Nullable android.content.SharedPreferences com.example.runtrackerapp.di.AppModule.provideSharedPreferences(@dagger.hilt.android.qualifiers.ApplicationContext android.content.Context) public abstract static class SingletonC implements BaseApplication_GeneratedInjector, ^ android.content.SharedPreferences is injected at com.example.runtrackerapp.ui.fragments.SetupFragment.sharedPref com.example.runtrackerapp.ui.fragments.SetupFragment is injected at com.example.runtrackerapp.ui.fragments.SetupFragment_GeneratedInjector.injectSetupFragment(com.example.runtrackerapp.ui.fragments.SetupFragment) [com.example.runtrackerapp.BaseApplication_HiltComponents.SingletonC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityRetainedC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityC ? com.example.runtrackerapp.BaseApplication_HiltComponents.FragmentC] C:\Users\Yodgorbek\RunTrackerApp\app\build\generated\hilt\component_sources\debug\com\example\runtrackerapp\BaseApplication_HiltComponents.java:136: error: [Dagger/Nullable] android.content.SharedPreferences is not nullable, but is being provided by @Singleton @Provides @org.jetbrains.annotations.Nullable android.content.SharedPreferences com.example.runtrackerapp.di.AppModule.provideSharedPreferences(@dagger.hilt.android.qualifiers.ApplicationContext android.content.Context) public abstract static class SingletonC implements BaseApplication_GeneratedInjector, ^ android.content.SharedPreferences is injected at com.example.runtrackerapp.di.AppModule.provideFirstTimeToggle(sharedPref) java.lang.Boolean is injected at com.example.runtrackerapp.ui.fragments.SetupFragment.setFirstAppOpen(<set-?>) com.example.runtrackerapp.ui.fragments.SetupFragment is injected at com.example.runtrackerapp.ui.fragments.SetupFragment_GeneratedInjector.injectSetupFragment(com.example.runtrackerapp.ui.fragments.SetupFragment) [com.example.runtrackerapp.BaseApplication_HiltComponents.SingletonC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityRetainedC ? com.example.runtrackerapp.BaseApplication_HiltComponents.ActivityC ? com.example.runtrackerapp.BaseApplication_HiltComponents.FragmentC] 3 errors

below my appModule.kt

@Module
@InstallIn(SingletonComponent::class)
object AppModule {


    @Singleton
    @Provides
    fun provideRunningDatabase(
        @ApplicationContext app: Context
    ) = Room.databaseBuilder(
        app,
        RunningDatabase::class.java,
        RUNNING_DATABASE_NAME
    ).build()

    @Singleton
    @Provides
    fun provideRunDao(db: RunningDatabase) = db.getRunDao()
    @Singleton
    @Provides
    fun provideSharedPreferences(@ApplicationContext app: Context): SharedPreferences? {
        val sharedPreferences = app.getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE)
        return sharedPreferences
    }

    @Singleton
    @Provides
    fun provideName(sharedPref: SharedPreferences) = sharedPref.getString(KEY_NAME, "") ?: ""

    @Singleton
    @Provides
    fun provideWeight(sharedPref: SharedPreferences) = sharedPref.getFloat(KEY_WEIGHT, 80f)

    @Singleton
    @Provides
    fun provideFirstTimeToggle(sharedPref: SharedPreferences) =
        sharedPref.getBoolean(KEY_FIRST_TIME_TOGGLE, true)
}

below SetupFragment.kt

@AndroidEntryPoint
class SetupFragment : Fragment() {
    private var _binding: FragmentSetupBinding? = null
    private val binding get() = _binding!!
    @Inject
    lateinit var sharedPref: SharedPreferences


    @set:Inject
    var isFirstAppOpen = true
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        // inflate the layout and bind to the _binding
        _binding = FragmentSetupBinding.inflate(inflater, container, false)

        return binding.root
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if(!isFirstAppOpen){
            val navOptions = NavOptions.Builder()
                .setPopUpTo(R.id.setupFragment, true)
                .build()
            findNavController().navigate(
                R.id.action_setupFragment_to_runFragment,
            savedInstanceState,
            navOptions)
        }
        binding.tvContinue.setOnClickListener {
            val success = writePersonalDataToSharedPref()
            if (success){
                findNavController().navigate(R.id.action_setupFragment_to_runFragment)
            }else{
                Snackbar.make(requireView(), "Please enter all the fields", Snackbar.LENGTH_SHORT).show()
            }

        }


    }
    private fun writePersonalDataToSharedPref(): Boolean {
        val name = binding.etName.text.toString()
        val weight = binding.etWeight.text.toString()
        if(name.isEmpty() || weight.isEmpty()) {
            return false
        }
        sharedPref.edit()
            .putString(KEY_NAME, name)
            .putFloat(KEY_WEIGHT, weight.toFloat())
            .putBoolean(KEY_FIRST_TIME_TOGGLE, false)
            .apply()
        val toolbarText = "Let's go, $name!"
        (requireActivity() as ActivityMainBinding).tvToolbarTitle.text = toolbarText
        return true
    }

}

below TrackingFragment.kt

@AndroidEntryPoint
class TrackingFragment : Fragment(R.layout.fragment_tracking) {

    private val viewModel: MainViewModel by viewModels()

    private var isTracking = false
    private var pathPoints = mutableListOf<Polyline>()

    private var map: GoogleMap? = null

    private var curTimeInMillis = 0L
    private var _binding: FragmentTrackingBinding? = null
    private val binding get() = _binding!!

    private var menu: Menu? = null

    @set:Inject
     var weight = 80f

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        setHasOptionsMenu(true)
        _binding = FragmentTrackingBinding.inflate(inflater, container, false)
        return binding.root

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.mapView.onCreate(savedInstanceState)
        binding.btnToggleRun.setOnClickListener {
            toggleRun()
        }
        binding.btnFinishRun.setOnClickListener {
            zoomToSeeWholeTrack()
            endRunAndSaveToDb()
        }
        binding.mapView.getMapAsync {
            map = it
            addAllPolylines()
        }

        subscribeToObservers()
    }

    private fun subscribeToObservers() {
        TrackingService.isTracking.observe(viewLifecycleOwner, Observer {
            updateTracking(it)
        })

        TrackingService.pathPoints.observe(viewLifecycleOwner, Observer {
            pathPoints = it
            addLatestPolyline()
            moveCameraToUser()
        })

        TrackingService.timeRunInMillis.observe(viewLifecycleOwner, Observer {
            curTimeInMillis = it
            val formattedTime = TrackingUtility.getFormattedStopWatchTime(curTimeInMillis, true)
            binding.tvTimer.text = formattedTime
        })
    }

    private fun toggleRun() {
        if(isTracking) {
            menu?.getItem(0)?.isVisible = true
            sendCommandToService(ACTION_PAUSE_SERVICE)
        } else {
            sendCommandToService(ACTION_START_OR_RESUME_SERVICE)
        }
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        inflater.inflate(R.menu.toolbar_tracking_menu, menu)
        this.menu = menu
    }

    override fun onPrepareOptionsMenu(menu: Menu) {
        super.onPrepareOptionsMenu(menu)
        if(curTimeInMillis > 0L) {
            this.menu?.getItem(0)?.isVisible = true
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId) {
            R.id.miCancelTracking -> {
                showCancelTrackingDialog()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    private fun showCancelTrackingDialog() {
        val dialog = MaterialAlertDialogBuilder(requireContext(), R.style.AlertDialogTheme)
            .setTitle("Cancel the Run?")
            .setMessage("Are you sure to cancel the current run and delete all its data?")
            .setIcon(R.drawable.ic_delete)
            .setPositiveButton("Yes") { _, _ ->
                stopRun()
            }
            .setNegativeButton("No") { dialogInterface, _ ->
                dialogInterface.cancel()
            }
            .create()
        dialog.show()
    }

    private fun stopRun() {
        sendCommandToService(ACTION_STOP_SERVICE)
        findNavController().navigate(R.id.action_trackingFragment_to_runFragment)
    }

    private fun updateTracking(isTracking: Boolean) {
        this.isTracking = isTracking
        if(!isTracking) {
            binding.btnToggleRun.text = "Start"
            binding.btnFinishRun.visibility = View.VISIBLE
        } else {
            binding.btnToggleRun.text = "Stop"
            menu?.getItem(0)?.isVisible = true
            binding.btnFinishRun.visibility = View.GONE
        }
    }

    private fun moveCameraToUser() {
        if(pathPoints.isNotEmpty() && pathPoints.last().isNotEmpty()) {
            map?.animateCamera(
                CameraUpdateFactory.newLatLngZoom(
                    pathPoints.last().last(),
                    MAP_ZOOM
                )
            )
        }
    }

    private fun zoomToSeeWholeTrack(){
      val bounds = LatLngBounds.builder()
        for(polyline in pathPoints){
            for(pos in polyline){
                bounds.include(pos)
            }
        }
        map?.moveCamera(
            CameraUpdateFactory.newLatLngBounds(
                bounds.build(),
                binding.mapView.width,
                binding.mapView.height,
                (binding.mapView.height  * 0.05f).toInt()

            )
        )
    }
    private fun endRunAndSaveToDb(){
        map?.snapshot { bmp ->
        var distanceInMeters = 0
        for (polyline in pathPoints){
            distanceInMeters = TrackingUtility.calculatePolylineLength(polyline).toInt()

        }
            val avgSpeed = round((distanceInMeters / 1000f) / (curTimeInMillis / 1000f / 60 / 60) * 10) / 10f
            val dataTimestamp = Calendar.getInstance().timeInMillis
            val caloriesBurned = ((distanceInMeters / 1000f) * weight).toInt()
            val run = Run(bmp,dataTimestamp, avgSpeed,distanceInMeters, curTimeInMillis, caloriesBurned)
            viewModel.insertRun(run)
            Snackbar.make(
                requireActivity().findViewById(R.id.rootView),
                "Run saved successfully",
                Snackbar.LENGTH_LONG
            ).show()
            stopRun()

        }
    }

    private fun addAllPolylines() {
        for(polyline in pathPoints) {
            val polylineOptions = PolylineOptions()
                .color(POLYLINE_COLOR)
                .width(POLYLINE_WIDTH)
                .addAll(polyline)
            map?.addPolyline(polylineOptions)
        }
    }

    private fun addLatestPolyline() {
        if(pathPoints.isNotEmpty() && pathPoints.last().size > 1) {
            val preLastLatLng = pathPoints.last()[pathPoints.last().size - 2]
            val lastLatLng = pathPoints.last().last()
            val polylineOptions = PolylineOptions()
                .color(POLYLINE_COLOR)
                .width(POLYLINE_WIDTH)
                .add(preLastLatLng)
                .add(lastLatLng)
            map?.addPolyline(polylineOptions)
        }
    }

    private fun sendCommandToService(action: String) =
        Intent(requireContext(), TrackingService::class.java).also {
            it.action = action
            requireContext().startService(it)
        }

    override fun onResume() {
        super.onResume()
        binding.mapView?.onResume()
    }

    override fun onStart() {
        super.onStart()
        binding.mapView?.onStart()
    }

    override fun onStop() {
        super.onStop()
        binding.mapView?.onStop()
    }

    override fun onPause() {
        super.onPause()
        binding.mapView?.onPause()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        binding.mapView?.onLowMemory()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        binding.mapView?.onSaveInstanceState(outState)
    }
}

I want to know where I am making mistake I have followed all stackoverflow answer it did not solve my issue

CodePudding user response:

A provider should not be nullable in your case provideSharedPreferences.. Remove Nullble from return type.

@Singleton
@Provides
fun provideSharedPreferences(@ApplicationContext app: Context): SharedPreferences {
    val sharedPreferences = app.getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE)
    return sharedPreferences
}
  • Related