LoginSignup
5
5

More than 1 year has passed since last update.

Hiltを使って位置情報を取得する

Last updated at Posted at 2022-03-04

位置情報の取得で、LocationManagerが将来的に廃止されるため、FusedLocationProviderClientに切り替えたました。
その際、HiltとLiveDataを使用してどこでも位置情報の変更を受信出来るようにしたので、それを説明したいと思います。

条件

  • permissionに位置情報を追加
  • permissionの許可を取得済み
  • Hiltを導入済み

ModuleにFusedLocationProviderClientを定義

@Module
@InstallIn(SingletonComponent::class)
class AppModule {
    @Provides
    @Singleton
    fun provideFusedLocationProviderClient(@ApplicationContext context: Context): FusedLocationProviderClient {
        return LocationServices.getFusedLocationProviderClient(context)
    }
}

Repositoryを作成する

FusedLocationProviderClientをInjectする。
LocationCallbackで位置情報に変化があった場合、Listenerに通知します。

@Singleton
class LocationRepository @Inject constructor(
    @ApplicationContext private val context: Context,
    private val fusedLocationProviderClient: FusedLocationProviderClient
) {

    interface OnLocationListener {

        fun onLocationChanged(location: Location)
        fun onProviderChanged(isEnable: Boolean)
    }

    private var onLocationListener: OnLocationListener? = null

    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            onLocationListener?.onLocationChanged(locationResult.lastLocation)
        }
    }

    fun start(onListener: OnLocationListener) {
        onLocationListener = onListener

        if (ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {

            return
        }

        val locationRequest = LocationRequest.create()
        locationRequest.apply {
            interval = TimeUnit.SECONDS.toMillis(5)
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
    }

    fun stop() {
        fusedLocationProviderClient.removeLocationUpdates(locationCallback)
        onLocationListener = null
    }
}

LiveDataを作成する

LocationRepositoryをInjectします。
LiveDataを作成するときにLocationRepositoryにListenerを渡します。
Listenerに変更があった場合、LiveDataのvalueに入れて通知します。

class LocationLiveData @Inject constructor(
    private val locationRepository: LocationRepository
) : LiveData<Location>() {

    private val onLocationListener = object : LocationRepository.OnLocationListener {
        override fun onLocationChanged(location: Location) {
            value = location
        }

        override fun onProviderChanged(isEnable: Boolean) {
        }
    }

    override fun onInactive() {
        super.onInactive()

        stop()
    }

    fun start() {
        locationRepository.start(onLocationListener)
    }

    fun stop() {
        locationRepository.stop()
    }
}

LocationLiveDataをモジュールに登録する

@Module
@InstallIn(SingletonComponent::class)
class AppModule {
    @Provides
    @Singleton
    fun provideFusedLocationProviderClient(@ApplicationContext context: Context): FusedLocationProviderClient {
        return LocationServices.getFusedLocationProviderClient(context)
    }

    @Provides
    @Singleton
    fun provideLocationLiveData(locationRepository: LocationRepository): LocationLiveData {
        return LocationLiveData(locationRepository)
    }
}
  • LocationLiveDataを使用する

ViewModelでLocationLiveDataをInjectすることで、位置情報が変わったらActivity/Fragmentで取得することが可能です。

class MainViewModel @Inject constructor(
    val locationLiveData: LocationLiveData
) {

  fun start() {
    locationLiveData.start()
  }
}
  viewModel.locationLiveData.observe(this) {
    // it = Location
  }

Hiltに関しては、自分の過去記事にありますので、よろしければそちらを参照してください。
LiveDataを使うことで、同じような位置情報を取得するコードを書かなくて済むようになりますので、よければ参考にしてください。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5