PermissionのチェックをHiltでやってみようと思います。
条件
- Hilt導入済み
Listenerを作成
interface PermissionListener {
fun permissionGranted()
fun permissionDenied()
}
Lifecycleと紐付ける
Lifecycleと紐付けるため、継承出来るようにします。
abstract class AbstractPermissionObserver : DefaultLifecycleObserver {
var isGranted: Boolean = false
var permissionListener: PermissionListener? = null
abstract fun launch()
abstract fun checkPermission(): Boolean
}
位置情報のPermissionチェック
位置情報以外でも好きなPermissionをlaunch()とcheckPermission()でチェックしてください。
@ActivityScoped
class LocationPermissionObserver @Inject constructor(
@ActivityContext private val context: Context
) : AbstractPermissionObserver() {
private var requestPermission: ActivityResultLauncher<Array<String>>? = null
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
if (context is AppCompatActivity) {
requestPermission =
context.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
permissions.entries.forEach {
isGranted = it.value
if (!it.value) {
return@forEach
}
}
if (isGranted) {
permissionListener?.permissionGranted()
} else {
permissionListener?.permissionDenied()
}
}
}
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
requestPermission = null
}
override fun launch() {
requestPermission?.launch(
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}
override fun checkPermission(): Boolean {
val fineLocationPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
val coarseLocationPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
return fineLocationPermission == PackageManager.PERMISSION_GRANTED &&
coarseLocationPermission == PackageManager.PERMISSION_GRANTED
}
}
Activityのlifecycleと紐付ける
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var locationPermissionObserver: LocationPermissionObserver
private val viewModel by viewModels<MainViewModel>()
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
lifecycle.addObserver(locationPermissionObserver)
}
override fun onDestroy() {
super.onDestroy()
lifecycle.removeObserver(locationPermissionObserver)
}
}
FragmentでPermissionチェックを実施
onStart時に実施していますが、ボタンを押下した際でも、どこでも大丈夫です。
@AndroidEntryPoint
class MainFragment : Fragment() {
@Inject
lateinit var locationPermissionObserver: LocationPermissionObserver
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
locationPermissionObserver.permissionListener = object : PermissionListener {
override fun permissionGranted() {
}
override fun permissionDenied() {
}
}
}
override fun onStart() {
super.onStart()
// Permissionチェック、許可されてない場合は許可を求めるダイアログを表示
if (!locationPermissionObserver.checkPermission()) {
locationPermissionObserver.launch()
}
}
xxxPermissionObserverを色んなPermissionチェックで作成するとどこでもPermissionチェック出来るようになりますので、是非活用してみてください。