Skip to content

Commit a69b603

Browse files
authored
Merge pull request #79 from PatilShreyas/update-tooling
Update tooling, libraries
2 parents d91d11f + 8aefe38 commit a69b603

36 files changed

+474
-482
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ jobs:
99
steps:
1010
- uses: actions/checkout@v1
1111

12-
- name: Set up JDK 11
13-
uses: actions/setup-java@v1
12+
- name: Set up JDK 17
13+
uses: actions/setup-java@v3
1414
with:
15-
java-version: 11
15+
java-version: 17
16+
distribution: temurin
17+
cache: gradle
1618

1719
- name: Grant Permission to Execute
1820
run: chmod +x gradlew

.github/workflows/release.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ jobs:
1515
- name: Checkout repository
1616
uses: actions/checkout@v2
1717

18-
- name: Set up JDK 11
19-
uses: actions/setup-java@v2
18+
- name: Set up JDK 17
19+
uses: actions/setup-java@v3
2020
with:
21-
java-version: '11'
22-
distribution: 'adopt'
21+
java-version: 17
22+
distribution: temurin
23+
cache: gradle
2324

2425
- name: Grant Permission to Execute Gradle
2526
run: chmod +x gradlew

app/build.gradle

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ plugins {
44
}
55

66
android {
7-
compileSdk 33
7+
compileSdk 34
88

99
defaultConfig {
1010
applicationId "dev.shreyaspatil.permissionFlow.example"
1111
minSdk 21
12-
targetSdk 33
1312
versionCode 1
1413
versionName "1.0"
1514

@@ -53,28 +52,29 @@ dependencies {
5352
implementation(project(":permission-flow-compose"))
5453

5554
// Android
56-
implementation 'androidx.core:core-ktx:1.10.0'
57-
implementation 'androidx.fragment:fragment-ktx:1.5.6'
55+
implementation 'androidx.core:core-ktx:1.12.0'
56+
implementation 'androidx.fragment:fragment-ktx:1.6.2'
5857
implementation 'androidx.appcompat:appcompat:1.6.1'
5958
implementation 'com.google.android.material:material:1.6.1'
6059
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
6160

6261
// Jetpack Compose
62+
implementation platform("androidx.compose:compose-bom:$composeBomVersion")
6363
implementation "androidx.activity:activity-compose:$activityVersion"
64-
implementation "androidx.compose.material:material:$composeVersion"
65-
implementation "androidx.compose.runtime:runtime:$composeVersion"
66-
implementation "androidx.compose.animation:animation:$composeVersion"
67-
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
64+
implementation "androidx.compose.material:material"
65+
implementation "androidx.compose.runtime:runtime"
66+
implementation "androidx.compose.animation:animation"
67+
implementation "androidx.compose.ui:ui-tooling"
6868

6969
// Lifecycle
70-
def lifecycleVersion = '2.6.1'
70+
def lifecycleVersion = '2.7.0'
7171
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
7272
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
7373

7474

7575
// Coroutines
76-
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
77-
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
76+
implementation('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0')
77+
implementation('org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0')
7878

7979
// Testing
8080
testImplementation 'junit:junit:4.13.2'

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
99
<uses-permission android:name="android.permission.CAMERA" />
1010

11+
<uses-feature
12+
android:name="android.hardware.camera"
13+
android:required="false" />
14+
1115
<application
1216
android:allowBackup="true"
1317
android:dataExtractionRules="@xml/data_extraction_rules"
@@ -27,10 +31,10 @@
2731
<category android:name="android.intent.category.LAUNCHER" />
2832
</intent-filter>
2933
</activity>
30-
<activity android:name=".ui.composePermission.ComposePermissionActivity"/>
31-
<activity android:name=".ui.multipermission.MultiPermissionActivity"/>
32-
<activity android:name=".ui.contacts.ContactsActivity"/>
33-
<activity android:name=".ui.fragment.ExampleFragmentActivity"/>
34+
<activity android:name=".ui.composePermission.ComposePermissionActivity" />
35+
<activity android:name=".ui.multipermission.MultiPermissionActivity" />
36+
<activity android:name=".ui.contacts.ContactsActivity" />
37+
<activity android:name=".ui.fragment.ExampleFragmentActivity" />
3438
</application>
3539

3640
</manifest>

app/src/main/java/dev/shreyaspatil/permissionFlow/example/data/impl/AndroidDefaultContactRepository.kt

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,56 +35,64 @@ class AndroidDefaultContactRepository(
3535
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
3636
) : ContactRepository {
3737

38-
override val allContacts: Flow<List<Contact>> = permissionFlow
39-
.getPermissionState(Manifest.permission.READ_CONTACTS)
40-
.transform { state ->
38+
override val allContacts: Flow<List<Contact>> =
39+
permissionFlow.getPermissionState(Manifest.permission.READ_CONTACTS).transform { state ->
4140
if (state.isGranted) {
4241
emit(getContacts())
4342
} else {
4443
emit(emptyList())
4544
}
4645
}
4746

48-
private suspend fun getContacts(): List<Contact> = withContext(ioDispatcher) {
49-
buildList {
50-
var cursor: Cursor? = null
51-
try {
52-
val projection = arrayOf(
53-
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
54-
ContactsContract.CommonDataKinds.Phone.NUMBER,
55-
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
56-
ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
57-
)
47+
private suspend fun getContacts(): List<Contact> =
48+
withContext(ioDispatcher) {
49+
buildList {
50+
var cursor: Cursor? = null
51+
try {
52+
val projection =
53+
arrayOf(
54+
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
55+
ContactsContract.CommonDataKinds.Phone.NUMBER,
56+
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
57+
ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
58+
)
5859

59-
val order = "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} ASC"
60+
val order = "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} ASC"
6061

61-
cursor = contentResolver.query(
62-
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
63-
projection,
64-
null,
65-
null,
66-
order,
67-
)
68-
if (cursor != null) {
69-
while (cursor.moveToNext()) {
70-
val contactId = cursor.getStringOrNull(
71-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID),
72-
)
73-
val name = cursor.getStringOrNull(
74-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME),
75-
)
76-
val number = cursor.getStringOrNull(
77-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER),
62+
cursor =
63+
contentResolver.query(
64+
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
65+
projection,
66+
null,
67+
null,
68+
order,
7869
)
70+
if (cursor != null) {
71+
while (cursor.moveToNext()) {
72+
val contactId =
73+
cursor.getStringOrNull(
74+
cursor.getColumnIndex(
75+
ContactsContract.CommonDataKinds.Phone.CONTACT_ID),
76+
)
77+
val name =
78+
cursor.getStringOrNull(
79+
cursor.getColumnIndex(
80+
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME),
81+
)
82+
val number =
83+
cursor.getStringOrNull(
84+
cursor.getColumnIndex(
85+
ContactsContract.CommonDataKinds.Phone.NUMBER),
86+
)
7987

80-
if (contactId != null && name != null && number != null) {
81-
add(Contact(contactId, name, number))
88+
if (contactId != null && name != null && number != null) {
89+
add(Contact(contactId, name, number))
90+
}
8291
}
8392
}
93+
} finally {
94+
cursor?.close()
8495
}
85-
} finally {
86-
cursor?.close()
8796
}
8897
}
89-
}
9098
}

app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/composePermission/ComposePermissionActivity.kt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ class ComposePermissionActivity : ComponentActivity() {
4444
}
4545
}
4646

47-
private val permissions = arrayOf(
48-
android.Manifest.permission.CAMERA,
49-
android.Manifest.permission.READ_EXTERNAL_STORAGE,
50-
android.Manifest.permission.READ_CALL_LOG,
51-
android.Manifest.permission.READ_CONTACTS,
52-
android.Manifest.permission.READ_PHONE_STATE,
53-
)
47+
private val permissions =
48+
arrayOf(
49+
android.Manifest.permission.CAMERA,
50+
android.Manifest.permission.READ_EXTERNAL_STORAGE,
51+
android.Manifest.permission.READ_CALL_LOG,
52+
android.Manifest.permission.READ_CONTACTS,
53+
android.Manifest.permission.READ_PHONE_STATE,
54+
)
5455

5556
@Composable
5657
fun MainScreen() {
@@ -59,15 +60,11 @@ fun MainScreen() {
5960
// or use `rememberPermissionState()` to get the state of a single permission
6061

6162
Column(
62-
Modifier
63-
.fillMaxSize()
64-
.padding(16.dp),
63+
modifier = Modifier.fillMaxSize().padding(16.dp),
6564
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
6665
horizontalAlignment = Alignment.CenterHorizontally,
6766
) {
68-
Button(onClick = { permissionLauncher.launch(permissions) }) {
69-
Text("Request Permissions")
70-
}
67+
Button(onClick = { permissionLauncher.launch(permissions) }) { Text("Request Permissions") }
7168

7269
Column(modifier = Modifier.background(Color.Green).padding(16.dp)) {
7370
Text(text = "Granted Permissions:")

app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/contacts/ContactsActivity.kt

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ import kotlinx.coroutines.flow.onEach
3131
class ContactsActivity : AppCompatActivity() {
3232

3333
private lateinit var binding: ActivityContactsBinding
34-
private val viewModel by viewModels<ContactsViewModel> {
35-
ContactsViewModel.FactoryProvider(contentResolver).get()
36-
}
34+
private val viewModel by
35+
viewModels<ContactsViewModel> { ContactsViewModel.FactoryProvider(contentResolver).get() }
3736

3837
private val permissionLauncher = registerForPermissionFlowRequestsResult()
3938

@@ -44,26 +43,25 @@ class ContactsActivity : AppCompatActivity() {
4443
observeStates()
4544
}
4645

47-
private fun render(state: ContactsUiState) {
46+
private fun render(state: ContactsUiEvents) {
4847
when (state) {
49-
ContactsUiState.ContactPermissionGranted -> {
48+
ContactsUiEvents.ContactPermissionGranted -> {
5049
binding.permissionStatusText.apply {
5150
text = "Contacts Permission Granted!"
5251
setOnClickListener(null)
5352
}
5453
}
55-
ContactsUiState.ContactPermissionNotGranted -> {
54+
ContactsUiEvents.ContactPermissionNotGranted -> {
5655
binding.permissionStatusText.apply {
5756
text = "Click here to ask for contacts permission"
5857
setOnClickListener { askContactsPermission() }
5958
}
6059
}
61-
is ContactsUiState.ContactsAvailable -> {
62-
binding.contactsDataText.text = state.contacts.joinToString("\n") {
63-
"${it.id}. ${it.name} (${it.number})"
64-
}
60+
is ContactsUiEvents.ContactsAvailable -> {
61+
binding.contactsDataText.text =
62+
state.contacts.joinToString("\n") { "${it.id}. ${it.name} (${it.number})" }
6563
}
66-
is ContactsUiState.Failure -> {
64+
is ContactsUiEvents.Failure -> {
6765
Toast.makeText(this, state.error, Toast.LENGTH_SHORT).show()
6866
}
6967
}
@@ -74,9 +72,6 @@ class ContactsActivity : AppCompatActivity() {
7472
}
7573

7674
private fun observeStates() {
77-
viewModel.state
78-
.flowWithLifecycle(lifecycle)
79-
.onEach { render(it) }
80-
.launchIn(lifecycleScope)
75+
viewModel.state.flowWithLifecycle(lifecycle).onEach { render(it) }.launchIn(lifecycleScope)
8176
}
8277
}

app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/contacts/ContactsUiState.kt renamed to app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/contacts/ContactsUiEvents.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ package dev.shreyaspatil.permissionFlow.example.ui.contacts
1717

1818
import dev.shreyaspatil.permissionFlow.example.data.model.Contact
1919

20-
sealed class ContactsUiState {
21-
object ContactPermissionNotGranted : ContactsUiState()
22-
object ContactPermissionGranted : ContactsUiState()
23-
data class ContactsAvailable(val contacts: List<Contact>) : ContactsUiState()
24-
data class Failure(val error: String) : ContactsUiState()
20+
sealed class ContactsUiEvents {
21+
object ContactPermissionNotGranted : ContactsUiEvents()
22+
23+
object ContactPermissionGranted : ContactsUiEvents()
24+
25+
data class ContactsAvailable(val contacts: List<Contact>) : ContactsUiEvents()
26+
27+
data class Failure(val error: String) : ContactsUiEvents()
2528
}

app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/contacts/ContactsViewModel.kt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class ContactsViewModel(
3535
private val repository: ContactRepository,
3636
private val permissionFlow: PermissionFlow = PermissionFlow.getInstance(),
3737
) : ViewModel() {
38-
private val _states = Channel<ContactsUiState>(capacity = BUFFERED)
39-
val state: Flow<ContactsUiState> = _states.receiveAsFlow()
38+
private val uiEvents = Channel<ContactsUiEvents>(capacity = BUFFERED)
39+
val state: Flow<ContactsUiEvents> = uiEvents.receiveAsFlow()
4040

4141
init {
4242
observeContacts()
@@ -46,32 +46,33 @@ class ContactsViewModel(
4646
private fun observeContacts() {
4747
viewModelScope.launch {
4848
repository.allContacts
49-
.catch { setNextState(ContactsUiState.Failure(it.message ?: "Error occurred")) }
50-
.collect { contacts -> setNextState(ContactsUiState.ContactsAvailable(contacts)) }
49+
.catch { setNextState(ContactsUiEvents.Failure(it.message ?: "Error occurred")) }
50+
.collect { contacts -> setNextState(ContactsUiEvents.ContactsAvailable(contacts)) }
5151
}
5252
}
5353

5454
private fun observeContactsPermission() {
5555
viewModelScope.launch {
5656
permissionFlow.getPermissionState(Manifest.permission.READ_CONTACTS).collect { state ->
5757
if (state.isGranted) {
58-
setNextState(ContactsUiState.ContactPermissionGranted)
58+
setNextState(ContactsUiEvents.ContactPermissionGranted)
5959
} else {
60-
setNextState(ContactsUiState.ContactPermissionNotGranted)
60+
setNextState(ContactsUiEvents.ContactPermissionNotGranted)
6161
}
6262
}
6363
}
6464
}
6565

66-
private fun setNextState(nextState: ContactsUiState) {
67-
_states.trySend(nextState)
66+
private fun setNextState(nextState: ContactsUiEvents) {
67+
uiEvents.trySend(nextState)
6868
}
6969

7070
class FactoryProvider(private val contentResolver: ContentResolver) {
7171
fun get(): ViewModelProvider.Factory {
72-
val initializer = ViewModelInitializer(ContactsViewModel::class.java) {
73-
ContactsViewModel(AndroidDefaultContactRepository(contentResolver))
74-
}
72+
val initializer =
73+
ViewModelInitializer(ContactsViewModel::class.java) {
74+
ContactsViewModel(AndroidDefaultContactRepository(contentResolver))
75+
}
7576
return ViewModelProvider.Factory.from(initializer)
7677
}
7778
}

0 commit comments

Comments
 (0)