Skip to content

Commit df2193e

Browse files
Created the new PermissionsUtils
1 parent 3d55396 commit df2193e

File tree

4 files changed

+185
-154
lines changed

4 files changed

+185
-154
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ android {
1414
applicationId = "com.d4rk.cleaner"
1515
minSdk = 26
1616
targetSdk = 34
17-
versionCode = 85
17+
versionCode = 86
1818
versionName = "2.0.0"
1919
archivesName = "${applicationId}-v${versionName}"
2020
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Lines changed: 5 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
package com.d4rk.cleaner.ui.home
22

3-
import android.Manifest
43
import android.app.Activity
5-
import android.app.AppOpsManager
64
import android.app.Application
75
import android.app.usage.StorageStatsManager
86
import android.content.Context
9-
import android.content.Intent
10-
import android.content.pm.PackageManager
11-
import android.net.Uri
12-
import android.os.Build
13-
import android.os.Environment
147
import android.os.storage.StorageManager
15-
import android.provider.Settings
168
import androidx.compose.runtime.mutableStateMapOf
179
import androidx.compose.runtime.mutableStateOf
18-
import androidx.core.app.ActivityCompat
19-
import androidx.core.content.ContextCompat
2010
import androidx.lifecycle.AndroidViewModel
2111
import androidx.lifecycle.MutableLiveData
2212
import androidx.lifecycle.viewModelScope
2313
import com.d4rk.cleaner.data.datastore.DataStore
2414
import com.d4rk.cleaner.utils.FileScanner
15+
import com.d4rk.cleaner.utils.PermissionsUtils
2516
import kotlinx.coroutines.Dispatchers
2617
import kotlinx.coroutines.flow.MutableStateFlow
2718
import kotlinx.coroutines.flow.StateFlow
@@ -123,8 +114,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
123114
* @param activity The Activity instance required to request permissions.
124115
*/
125116
fun analyze(activity: Activity) {
126-
if (!hasRequiredPermissions()) {
127-
requestPermissions(activity)
117+
if (!PermissionsUtils.hasStoragePermissions(getApplication())) {
118+
PermissionsUtils.requestStoragePermissions(activity)
128119
return
129120
}
130121

@@ -157,8 +148,8 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
157148
* @param activity The Activity instance required to request permissions.
158149
*/
159150
fun clean(activity: Activity) {
160-
if (!hasRequiredPermissions()) {
161-
requestPermissions(activity)
151+
if (!PermissionsUtils.hasStoragePermissions(getApplication())) {
152+
PermissionsUtils.requestStoragePermissions(activity)
162153
return
163154
}
164155

@@ -179,126 +170,4 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
179170
}
180171
}
181172
}
182-
183-
/**
184-
* Checks if the app has all the necessary permissions to perform scanning and cleaning.
185-
*
186-
* @return True if all required permissions are granted, false otherwise.
187-
*/
188-
private fun hasRequiredPermissions(): Boolean {
189-
val hasStoragePermissions = when {
190-
Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q ->
191-
ContextCompat.checkSelfPermission(
192-
getApplication(),
193-
Manifest.permission.WRITE_EXTERNAL_STORAGE
194-
) == PackageManager.PERMISSION_GRANTED
195-
196-
Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2 ->
197-
ContextCompat.checkSelfPermission(
198-
getApplication(),
199-
Manifest.permission.READ_EXTERNAL_STORAGE
200-
) == PackageManager.PERMISSION_GRANTED
201-
202-
else -> true
203-
}
204-
205-
val hasManageStoragePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
206-
Environment.isExternalStorageManager()
207-
} else {
208-
true
209-
}
210-
211-
val hasUsageStatsPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
212-
isAccessGranted()
213-
} else {
214-
true
215-
}
216-
217-
val hasMediaPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
218-
ContextCompat.checkSelfPermission(
219-
getApplication(),
220-
Manifest.permission.READ_MEDIA_AUDIO
221-
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
222-
getApplication(),
223-
Manifest.permission.READ_MEDIA_IMAGES
224-
) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(
225-
getApplication(),
226-
Manifest.permission.READ_MEDIA_VIDEO
227-
) == PackageManager.PERMISSION_GRANTED
228-
} else {
229-
true
230-
}
231-
232-
return hasStoragePermissions && hasManageStoragePermission &&
233-
hasUsageStatsPermission && hasMediaPermissions
234-
}
235-
236-
/**
237-
* Checks if the app has access to usage statistics.
238-
*
239-
* @return True if access is granted, false otherwise.
240-
*/
241-
private fun isAccessGranted(): Boolean = try {
242-
val packageManager = getApplication<Application>().packageManager
243-
val applicationInfo =
244-
packageManager.getApplicationInfo(getApplication<Application>().packageName, 0)
245-
val appOpsManager =
246-
getApplication<Application>().getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
247-
@Suppress("DEPRECATION") val mode: Int = appOpsManager.checkOpNoThrow(
248-
AppOpsManager.OPSTR_GET_USAGE_STATS,
249-
applicationInfo.uid,
250-
applicationInfo.packageName
251-
)
252-
mode == AppOpsManager.MODE_ALLOWED
253-
} catch (e: PackageManager.NameNotFoundException) {
254-
false
255-
}
256-
257-
/**
258-
* Requests necessary permissions for the app to function correctly.
259-
*
260-
* This function checks for and requests the following permissions:
261-
* - WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE: For accessing and managing files.
262-
* - MANAGE_EXTERNAL_STORAGE (Android R and above): For managing all files on external storage.
263-
* - PACKAGE_USAGE_STATS: For gathering app usage statistics.
264-
* - READ_MEDIA_AUDIO, READ_MEDIA_IMAGES, READ_MEDIA_VIDEO (Android Tiramisu and above):
265-
* For accessing media files.
266-
*
267-
* It utilizes ActivityCompat.requestPermissions to initiate the permission request process
268-
* and handles different Android versions to ensure compatibility.
269-
*
270-
* @param activity The Activity instance required to request permissions.
271-
*/
272-
private fun requestPermissions(activity: Activity) {
273-
val requiredPermissions = mutableListOf(
274-
Manifest.permission.WRITE_EXTERNAL_STORAGE,
275-
Manifest.permission.READ_EXTERNAL_STORAGE
276-
)
277-
278-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
279-
if (!Environment.isExternalStorageManager()) {
280-
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
281-
val uri = Uri.fromParts("package", getApplication<Application>().packageName, null)
282-
intent.data = uri
283-
activity.startActivity(intent)
284-
}
285-
286-
if (!isAccessGranted()) {
287-
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
288-
activity.startActivity(intent)
289-
}
290-
}
291-
292-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
293-
requiredPermissions.addAll(
294-
listOf(
295-
Manifest.permission.READ_MEDIA_AUDIO,
296-
Manifest.permission.READ_MEDIA_IMAGES,
297-
Manifest.permission.READ_MEDIA_VIDEO
298-
)
299-
)
300-
}
301-
302-
ActivityCompat.requestPermissions(activity, requiredPermissions.toTypedArray(), 1)
303-
}
304173
}

app/src/main/kotlin/com/d4rk/cleaner/ui/startup/StartupActivity.kt

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.compose.material3.MaterialTheme
1111
import androidx.compose.material3.Surface
1212
import androidx.compose.ui.Modifier
1313
import com.d4rk.cleaner.ui.settings.display.theme.style.AppTheme
14+
import com.d4rk.cleaner.utils.PermissionsUtils
1415
import com.google.android.ump.ConsentForm
1516
import com.google.android.ump.ConsentInformation
1617
import com.google.android.ump.ConsentRequestParameters
@@ -38,7 +39,9 @@ class StartupActivity : AppCompatActivity() {
3839
loadForm()
3940
}
4041
} , {})
41-
requestPermissions()
42+
if (!PermissionsUtils.hasNotificationPermission(this)) {
43+
PermissionsUtils.requestNotificationPermission(this)
44+
}
4245
}
4346

4447
/**
@@ -62,20 +65,4 @@ class StartupActivity : AppCompatActivity() {
6265
}
6366
} , {})
6467
}
65-
66-
/**
67-
* Handles the application's permission requirements.
68-
*
69-
* This function is responsible for checking and requesting the necessary permissions for the application. It takes into account the Android version to manage specific permission scenarios.
70-
* For Android versions Tiramisu or later, it requests the POST_NOTIFICATIONS permission.
71-
*
72-
* @see android.Manifest.permission.POST_NOTIFICATIONS
73-
* @see android.os.Build.VERSION.SDK_INT
74-
* @see android.os.Build.VERSION_CODES.TIRAMISU
75-
*/
76-
private fun requestPermissions() {
77-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
78-
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS) , 1)
79-
}
80-
}
8168
}

0 commit comments

Comments
 (0)