Skip to content

Commit

Permalink
Merge pull request #51 from sieunju/features/compose_permissions
Browse files Browse the repository at this point in the history
Features/compose permissions
  • Loading branch information
sieunju authored Apr 6, 2024
2 parents e3575e7 + ada5e6e commit 3262633
Show file tree
Hide file tree
Showing 31 changed files with 584 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ dependencies {
implementation(project(":features:rv_diff_util_2"))
implementation(project(":features:base_mvvm_lifecycle"))
implementation(project(":features:base_mvvm_bottom_sheet"))
implementation(project(":features:compose_permissions_result"))

/**
* Network
Expand Down
3 changes: 2 additions & 1 deletion buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ object Javax {
object Hilt {
const val android = "com.google.dagger:hilt-android:${Versions.hilt}"
const val compiler = "com.google.dagger:hilt-compiler:${Versions.hilt}"
const val compose = "androidx.hilt:hilt-navigation-compose:1.0.0"
}

object Rx {
Expand All @@ -60,7 +61,6 @@ object Retrofit {
object Glide {
const val base = "com.github.bumptech.glide:glide:4.16.0"
const val okhttp = "com.github.bumptech.glide:okhttp3-integration:4.16.0"
// const val compiler = "com.github.bumptech.glide:compiler:4.15.1"
const val compiler = "com.github.bumptech.glide:ksp:4.16.0"
const val compose = "com.github.bumptech.glide:compose:1.0.0-beta01"
}
Expand Down Expand Up @@ -89,6 +89,7 @@ object Compose {
const val tracing = "androidx.compose.runtime:runtime-tracing:1.0.0-beta01"
const val viewModel = "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
const val constraint = "androidx.constraintlayout:constraintlayout-compose:1.0.1"
const val runtime = "androidx.compose.runtime:runtime"
}

object UnitTest {
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ dependencies {
implementation(Compose.material)
implementation(Compose.preview)
implementation(Compose.ui)
implementation(Compose.runtime)

/**
* Unit Test
Expand Down
26 changes: 26 additions & 0 deletions core/src/main/java/com/hmju/core/compose/ComposeLifecycleState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.hmju.core.compose

import androidx.lifecycle.Lifecycle

/**
* Description : 필요한 Lifecycle 만 중복 없이 처리할수 있도록 정의한 클래스
*
* Created by juhongmin on 4/5/24
*/
enum class ComposeLifecycleState {
UN_KNOWN,
ON_CREATE,
ON_RESUME,
ON_STOP;

companion object {
fun Lifecycle.Event.from(): ComposeLifecycleState {
return when (this) {
Lifecycle.Event.ON_CREATE -> ON_CREATE
Lifecycle.Event.ON_RESUME -> ON_RESUME
Lifecycle.Event.ON_STOP -> ON_STOP
else -> UN_KNOWN
}
}
}
}
37 changes: 37 additions & 0 deletions core/src/main/java/com/hmju/core/compose/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.hmju.core.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.hmju.core.compose.ComposeLifecycleState.Companion.from


/**
* Compose 전용 Lifecycle Update 처리하는 함수
* @param lifecycleOwner Android LifecycleOwner
*/
@Composable
fun rememberLifecycleUpdatedState(
lifecycleOwner: LifecycleOwner
): MutableState<ComposeLifecycleState> {
val currentState = remember(lifecycleOwner) { mutableStateOf(ComposeLifecycleState.UN_KNOWN) }
DisposableEffect(Unit) {
val observer = LifecycleEventObserver { _, event ->
val newState = event.from()
if (currentState.value != newState &&
newState != ComposeLifecycleState.UN_KNOWN
) {
currentState.value = newState
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
return currentState
}
14 changes: 14 additions & 0 deletions core/src/main/java/com/hmju/core/permission/PermissionProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hmju.core.permission

/**
* Description : Permission Provider
*
* Created by juhongmin on 4/5/24
*/
interface PermissionProvider {

fun isGrated(permission: String): Boolean
fun isAllGrated(list: List<String>): Boolean
fun isAllGrated(map: Map<String,Boolean>) : Boolean
fun moveToSetting()
}
22 changes: 22 additions & 0 deletions core/src/main/java/com/hmju/core/permission/di/PermissionModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.hmju.core.permission.di

import com.hmju.core.permission.PermissionProvider
import com.hmju.core.permission.impl.PermissionProviderImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

/**
* Description :
*
* Created by juhongmin on 4/5/24
*/
@InstallIn(SingletonComponent::class)
@Module
internal abstract class PermissionModule {
@Binds
abstract fun bindPermissionProvider(
impl: PermissionProviderImpl
): PermissionProvider
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.hmju.core.permission.impl

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import androidx.core.content.ContextCompat
import com.hmju.core.permission.PermissionProvider
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

/**
* Description :
*
* Created by juhongmin on 4/5/24
*/
internal class PermissionProviderImpl @Inject constructor(
@ApplicationContext val context: Context
) : PermissionProvider {
override fun isGrated(permission: String): Boolean {
return ContextCompat.checkSelfPermission(
context,
permission
) == PackageManager.PERMISSION_GRANTED
}

override fun isAllGrated(list: List<String>): Boolean {
var isAllGrated = true
for (permission in list) {
if (!isGrated(permission)) {
isAllGrated = false
break
}
}
return isAllGrated
}

override fun isAllGrated(map: Map<String, Boolean>): Boolean {
var isAllGrated = true
for ((_, value) in map) {
if (!value) {
isAllGrated = false
break
}
}
return isAllGrated
}

override fun moveToSetting() {
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.parse("package:${context.packageName}")
).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addCategory(Intent.CATEGORY_DEFAULT)
context.startActivity(this)
}
}
}
1 change: 1 addition & 0 deletions features/compose_permissions_result/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
58 changes: 58 additions & 0 deletions features/compose_permissions_result/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
id("dagger.hilt.android.plugin")
kotlin("kapt")
}

android {
namespace = "com.hmju.compose_permissions_result"
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = Compose.compile
}
}

dependencies {
implementation(project(":core"))
implementation(project(":features:compose_permissions_result_bridge"))

/**
* Android X
*/
implementation(AndroidX.appCompat)

/**
* Hilt
*/
implementation(Hilt.android)
kapt(Hilt.compiler)
implementation(Hilt.compose)

/**
* Compose
*/
implementation(platform(Compose.base))
implementation(Compose.material)
implementation(Compose.ui)
implementation(Compose.preview)
implementation(Compose.viewModel)
implementation(Compose.constraint)
implementation(Compose.tracing)
implementation(Compose.activity)
implementation(Glide.compose)
// implementation("com.google.accompanist:accompanist-permissions:0.23.1")

/**
* Timber
*/
implementation(Log.timber)

testImplementation(UnitTest.junit)
androidTestImplementation(platform(Compose.base))
debugImplementation(UnitTest.Compose.tooling)
androidTestImplementation(UnitTest.Compose.junit)
androidTestImplementation(UnitTest.Compose.manifest)
}
Empty file.
21 changes: 21 additions & 0 deletions features/compose_permissions_result/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.hmju.compose_permissions_result

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.hmju.compose_permissions_result.test", appContext.packageName)
}
}
13 changes: 13 additions & 0 deletions features/compose_permissions_result/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>

<application>
<activity
android:name=".ComposePermissionsResultActivity"
android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.hmju.compose_permissions_result

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import com.hmju.compose_permissions_result.screen.PermissionScreen
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ComposePermissionsResultActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { PermissionScreen() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.hmju.compose_permissions_result.di

import android.content.Context
import com.hmju.compose_permissions_result.impl.ComposePermissionsResultBridgeImpl
import com.hmju.compose_permissions_result_bridge.ComposePermissionsResultBridge
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent

/**
* Description :
*
* Created by juhongmin on 4/3/24
*/
@InstallIn(SingletonComponent::class)
@Module
class FeatureModule {
@Provides
fun provideBridge(
@ApplicationContext context: Context
): ComposePermissionsResultBridge {
return ComposePermissionsResultBridgeImpl(context)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.hmju.compose_permissions_result.impl

import android.content.Context
import android.content.Intent
import com.hmju.compose_permissions_result.ComposePermissionsResultActivity
import com.hmju.compose_permissions_result_bridge.ComposePermissionsResultBridge

/**
* Description :
*
* Created by juhongmin on 4/3/24
*/
internal class ComposePermissionsResultBridgeImpl(
private val context: Context
) : ComposePermissionsResultBridge {
override fun moveToPage() {
Intent(context, ComposePermissionsResultActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(this)
}
}
}
Loading

0 comments on commit 3262633

Please sign in to comment.