Skip to content

Commit 43fe445

Browse files
authored
Merge pull request #45 from PatilShreyas/v1.1.0
Release v1.1.0
2 parents 01e3a52 + b04fb30 commit 43fe445

File tree

30 files changed

+235
-129
lines changed

30 files changed

+235
-129
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,8 @@ jobs:
3131

3232
- name: Publish Library
3333
run: |
34-
echo "Publishing library🚀"
35-
./gradlew publish --no-daemon --no-parallel
36-
echo "Published✅"
37-
38-
echo "Releasing repository...🚀"
39-
./gradlew closeAndReleaseRepository
40-
echo "Released✅"
34+
echo "Publishing library 🚀"
35+
./gradlew publishAllPublicationsToMavenCentral --no-configuration-cache
4136
env:
4237
ORG_GRADLE_PROJECT_VERSION_NAME: ${{ github.event.inputs.versionName }}
4338
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_KEY }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/.idea/
55
.DS_Store
66
/build
7+
*/build/
78
/captures
89
.externalNativeBuild
910
.cxx

README.md

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Permission Flow for Android
22

3-
Know about real-time state of a Android app Permissions with Kotlin Flow APIs. _Made with ❤️ for
3+
Know about real-time state of a Android app Permissions with Kotlin Flow APIs. _Made with ❤️ for
44
Android Developers_.
55

66
[![Build](https://github.com/PatilShreyas/permission-flow-android/actions/workflows/build.yml/badge.svg)](https://github.com/PatilShreyas/permission-flow-android/actions/workflows/build.yml)
@@ -20,13 +20,13 @@ Android Developers_.
2020

2121
## 💡Introduction
2222

23-
In big projects, app is generally divided in several modules and in such cases, if any individual
24-
module is just a data module (_not having UI_) and need to know state of a permission, it's not
25-
that easy. This library provides a way to know state of a permission throughout the app and
26-
from any layer of the application safely.
23+
In big projects, app is generally divided in several modules and in such cases, if any individual
24+
module is just a data module (_not having UI_) and need to know state of a permission, it's not
25+
that easy. This library provides a way to know state of a permission throughout the app and
26+
from any layer of the application safely.
2727

2828
_For example, you can listen for state of contacts permission in class where you'll instantly show
29-
list of contacts when permission is granted._
29+
list of contacts when permission is granted._
3030

3131
It's a simple and easy to use library. Just Plug and Play.
3232

@@ -49,23 +49,9 @@ dependencies {
4949

5050
_You can find latest version and changelogs in the [releases](https://github.com/PatilShreyas/permission-flow-android/releases)_.
5151

52-
### 2. Initialization
52+
### 2. Observing a Permission State
5353

54-
Before using any API of the library, it needs to be initialized before.
55-
Initialize **PermissionFlow** as follows (For example, in `Application` class):
56-
57-
```kotlin
58-
class MyApplication: Application() {
59-
override fun onCreate() {
60-
super.onCreate()
61-
PermissionFlow.init(this)
62-
}
63-
}
64-
```
65-
66-
### 3. Observing a Permission State
67-
68-
#### 3.1 Observing Permission with `StateFlow`
54+
#### 2.1 Observing Permission with `StateFlow`
6955
A permission state can be subscribed by retrieving `StateFlow<PermissionState>` or `StateFlow<MultiplePermissionState>` as follows:
7056

7157
```kotlin
@@ -101,7 +87,7 @@ suspend fun observeMultiplePermissions() {
10187
}
10288
```
10389

104-
#### 3.2 Observing permissions in Jetpack Compose
90+
#### 2.2 Observing permissions in Jetpack Compose
10591

10692
State of a permission and state of multiple permissions can also be observed in Jetpack Compose application as follows:
10793

@@ -119,29 +105,29 @@ fun ExampleSinglePermission() {
119105
@Composable
120106
fun ExampleMultiplePermission() {
121107
val state by rememberMultiplePermissionState(
122-
Manifest.permission.CAMERA
108+
Manifest.permission.CAMERA,
123109
Manifest.permission.ACCESS_FINE_LOCATION,
124110
Manifest.permission.READ_CONTACTS
125111
)
126-
112+
127113
if (state.allGranted) {
128114
// Render something
129115
}
130-
116+
131117
val grantedPermissions = state.grantedPermissions
132118
// Do something with `grantedPermissions`
133-
119+
134120
val deniedPermissions = state.deniedPermissions
135121
// Do something with `deniedPermissions`
136122
}
137123
```
138124

139-
### 4. Requesting permission with PermissionFlow
125+
### 3. Requesting permission with PermissionFlow
140126

141-
It's necessary to use utilities provided by this library to request permissions so that whenever permission state
127+
It's necessary to use utilities provided by this library to request permissions so that whenever permission state
142128
changes, this library takes care of notifying respective flows.
143129

144-
#### 4.1 Request permission from Activity / Fragment
130+
#### 3.1 Request permission from Activity / Fragment
145131

146132
Use [`registerForPermissionFlowRequestsResult()`](https://patilshreyas.github.io/permission-flow-android/docs/permission-flow/dev.shreyaspatil.permissionFlow.utils/register-for-permission-flow-requests-result.html) method to get `ActivityResultLauncher`
147133
and use `launch()` method to request for permission.
@@ -157,7 +143,7 @@ class ContactsActivity : AppCompatActivity() {
157143
}
158144
```
159145

160-
#### 4.2 Request permission in Jetpack Compose
146+
#### 3.2 Request permission in Jetpack Compose
161147

162148
Use [`rememberPermissionFlowRequestLauncher()`](https://patilshreyas.github.io/permission-flow-android/docs/permission-flow-compose/dev.shreyaspatil.permissionflow.compose/remember-permission-flow-request-launcher.html) method to get `ManagedActivityResultLauncher`
163149
and use `launch()` method to request for permission.
@@ -166,17 +152,17 @@ and use `launch()` method to request for permission.
166152
@Composable
167153
fun Example() {
168154
val permissionLauncher = rememberPermissionFlowRequestLauncher()
169-
155+
170156
Button(onClick = { permissionLauncher.launch(android.Manifest.permission.CAMERA, ...) }) {
171157
Text("Request Permissions")
172-
}
158+
}
173159
}
174160
```
175161

176-
### 5. Manually notifying permission state changes ⚠️
162+
### 4. Manually notifying permission state changes ⚠️
177163

178-
If you're not using `ActivityResultLauncher` APIs provided by this library then
179-
you will ***not receive permission state change updates***. But there's a provision by which
164+
If you're not using `ActivityResultLauncher` APIs provided by this library then
165+
you will ***not receive permission state change updates***. But there's a provision by which
180166
you can help this library to know about permission state changes.
181167

182168
Use [`PermissionFlow#notifyPermissionsChanged()`](https://patilshreyas.github.io/permission-flow-android/docs/permission-flow/dev.shreyaspatil.permissionFlow/-permission-flow/notify-permissions-changed.html) to notify the permission state changes
@@ -187,14 +173,14 @@ For example:
187173
```kotlin
188174
class MyActivity: AppCompatActivity() {
189175
private val permissionFlow = PermissionFlow.getInstance()
190-
176+
191177
private val permissionLauncher = registerForActivityResult(RequestPermission()) { isGranted ->
192178
permissionFlow.notifyPermissionsChanged(android.Manifest.permission.READ_CONTACTS)
193179
}
194180
}
195181
```
196182

197-
### 6. Manually Start / Stop Listening ⚠️
183+
### 5. Manually Start / Stop Listening ⚠️
198184

199185
This library starts processing things lazily whenever `getPermissionState()` or `getMultiplePermissionState()` is called
200186
for the first time. But this can be controlled with these methods:
@@ -205,12 +191,48 @@ fun doSomething() {
205191
// This means the state of permission retrieved with [getMultiplePermissionState] method will not
206192
// be updated after stopping listening.
207193
permissionFlow.stopListening()
208-
194+
209195
// Starts listening the changes of state of permissions after stopping listening
210196
permissionFlow.startListening()
211197
}
212198
```
213199

200+
### 6. What about Initialization?
201+
202+
This library automatically gets initialized with the App Startup library.
203+
If you want to provide own coroutine dispatcher
204+
205+
#### 6.1 Initialize **PermissionFlow** as follows (For example, in `Application` class)
206+
207+
```kotlin
208+
class MyApplication: Application() {
209+
override fun onCreate() {
210+
super.onCreate()
211+
val permissionDispatcher = Executors.newFixedThreadPool(3).asCoroutineDispatcher()
212+
PermissionFlow.init(this, permissionDispatcher)
213+
}
214+
}
215+
```
216+
217+
#### 6.2 Disable PermissionFlowInitializer in AndroidManifest.xml
218+
219+
Disable auto initialization of library with default configuration using this:
220+
221+
```xml
222+
<provider
223+
android:name="androidx.startup.InitializationProvider"
224+
android:authorities="${applicationId}.androidx-startup"
225+
android:exported="false"
226+
tools:node="merge">
227+
228+
<meta-data
229+
android:name="dev.shreyaspatil.permissionFlow.initializer.PermissionFlowInitializer"
230+
android:value="androidx.startup"
231+
tools:node="remove" />
232+
</provider>
233+
```
234+
235+
214236
## 📄 API Documentation
215237

216238
[Visit the API documentation](https://patilshreyas.github.io/permission-flow-android/docs/) of this library to get more information in detail. This documentation is generated using [Dokka](https://github.com/Kotlin/dokka).
@@ -221,11 +243,11 @@ fun doSomething() {
221243

222244
---
223245

224-
## 🙋‍♂️ Contribute
246+
## 🙋‍♂️ Contribute
225247

226248
Read [contribution guidelines](CONTRIBUTING.md) for more information regarding contribution.
227249

228-
## 💬 Discuss?
250+
## 💬 Discuss?
229251

230252
Have any questions, doubts or want to present your opinions, views? You're always welcome. You can [start discussions](https://github.com/PatilShreyas/permission-flow-android/discussions).
231253

app/build.gradle

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

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

99
defaultConfig {
1010
applicationId "dev.shreyaspatil.permissionFlow.example"
1111
minSdk 21
12-
targetSdk 32
12+
targetSdk 33
1313
versionCode 1
1414
versionName "1.0"
1515

@@ -36,14 +36,15 @@ android {
3636
}
3737

3838
composeOptions {
39-
kotlinCompilerExtensionVersion composeVersion
39+
kotlinCompilerExtensionVersion composeCompilerVersion
4040
}
4141

4242
packagingOptions {
4343
resources {
4444
excludes += '/META-INF/{AL2.0,LGPL2.1}'
4545
}
4646
}
47+
namespace 'dev.shreyaspatil.permissionFlow.example'
4748
}
4849

4950
dependencies {
@@ -52,9 +53,9 @@ dependencies {
5253
implementation(project(":permission-flow-compose"))
5354

5455
// Android
55-
implementation 'androidx.core:core-ktx:1.8.0'
56-
implementation 'androidx.fragment:fragment-ktx:1.4.1'
57-
implementation 'androidx.appcompat:appcompat:1.4.2'
56+
implementation 'androidx.core:core-ktx:1.10.0'
57+
implementation 'androidx.fragment:fragment-ktx:1.5.6'
58+
implementation 'androidx.appcompat:appcompat:1.6.1'
5859
implementation 'com.google.android.material:material:1.6.1'
5960
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
6061

@@ -66,7 +67,7 @@ dependencies {
6667
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
6768

6869
// Lifecycle
69-
def lifecycleVersion = "2.5.0-rc02"
70+
def lifecycleVersion = '2.6.1'
7071
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
7172
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
7273

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools"
4-
package="dev.shreyaspatil.permissionFlow.example">
3+
xmlns:tools="http://schemas.android.com/tools">
54

65
<uses-permission android:name="android.permission.READ_CONTACTS" />
76
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -10,7 +9,6 @@
109
<uses-permission android:name="android.permission.CAMERA" />
1110

1211
<application
13-
android:name="dev.shreyaspatil.permissionFlow.example.ExampleApplication"
1412
android:allowBackup="true"
1513
android:dataExtractionRules="@xml/data_extraction_rules"
1614
android:fullBackupContent="@xml/backup_rules"

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import kotlinx.coroutines.withContext
3232
class AndroidDefaultContactRepository(
3333
private val contentResolver: ContentResolver,
3434
private val permissionFlow: PermissionFlow = PermissionFlow.getInstance(),
35-
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
35+
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
3636
) : ContactRepository {
3737

3838
override val allContacts: Flow<List<Contact>> = permissionFlow
@@ -53,7 +53,7 @@ class AndroidDefaultContactRepository(
5353
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
5454
ContactsContract.CommonDataKinds.Phone.NUMBER,
5555
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
56-
ContactsContract.CommonDataKinds.Phone.PHOTO_URI
56+
ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
5757
)
5858

5959
val order = "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID} ASC"
@@ -63,18 +63,18 @@ class AndroidDefaultContactRepository(
6363
projection,
6464
null,
6565
null,
66-
order
66+
order,
6767
)
6868
if (cursor != null) {
6969
while (cursor.moveToNext()) {
7070
val contactId = cursor.getStringOrNull(
71-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)
71+
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID),
7272
)
7373
val name = cursor.getStringOrNull(
74-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
74+
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME),
7575
)
7676
val number = cursor.getStringOrNull(
77-
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
77+
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER),
7878
)
7979

8080
if (contactId != null && name != null && number != null) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ private val permissions = arrayOf(
4949
android.Manifest.permission.READ_EXTERNAL_STORAGE,
5050
android.Manifest.permission.READ_CALL_LOG,
5151
android.Manifest.permission.READ_CONTACTS,
52-
android.Manifest.permission.READ_PHONE_STATE
52+
android.Manifest.permission.READ_PHONE_STATE,
5353
)
5454

5555
@Composable
@@ -63,7 +63,7 @@ fun MainScreen() {
6363
.fillMaxSize()
6464
.padding(16.dp),
6565
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically),
66-
horizontalAlignment = Alignment.CenterHorizontally
66+
horizontalAlignment = Alignment.CenterHorizontally,
6767
) {
6868
Button(onClick = { permissionLauncher.launch(permissions) }) {
6969
Text("Request Permissions")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import kotlinx.coroutines.launch
3333

3434
class ContactsViewModel(
3535
private val repository: ContactRepository,
36-
private val permissionFlow: PermissionFlow = PermissionFlow.getInstance()
36+
private val permissionFlow: PermissionFlow = PermissionFlow.getInstance(),
3737
) : ViewModel() {
3838
private val _states = Channel<ContactsUiState>(capacity = BUFFERED)
3939
val state: Flow<ContactsUiState> = _states.receiveAsFlow()

app/src/main/java/dev/shreyaspatil/permissionFlow/example/ui/multipermission/MultiPermissionActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class MultiPermissionActivity : AppCompatActivity() {
4343
android.Manifest.permission.READ_EXTERNAL_STORAGE,
4444
android.Manifest.permission.READ_CALL_LOG,
4545
android.Manifest.permission.READ_CONTACTS,
46-
android.Manifest.permission.READ_PHONE_STATE
46+
android.Manifest.permission.READ_PHONE_STATE,
4747
)
4848

4949
override fun onCreate(savedInstanceState: Bundle?) {

0 commit comments

Comments
 (0)