request file permissions when necessary

fixes #8 by making it irrelevant
This commit is contained in:
qimiko committed 2024-01-28 00:20:18 -07:00
1 parent 9dc501c9ab
commit 19bd549b1f
3 files changed
+114 -63

No files matched your search

@@ -108,20 +108,6 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
setupRedirection(gdPackageInfo) setupRedirection(gdPackageInfo)
// request read and write permissions
val hasStoragePerms = (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) and
(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
if (!hasStoragePerms) {
requestPermissions(
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
0
)
}
Cocos2dxHelper.init(this, this) Cocos2dxHelper.init(this, this)
GeodeUtils.setContext(this) GeodeUtils.setContext(this)
@@ -1,5 +1,6 @@
package com.geode.launcher.utils package com.geode.launcher.utils
import android.Manifest
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
@@ -7,13 +8,16 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.util.Log import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.geode.launcher.R
import com.geode.launcher.activityresult.GeodeOpenFileActivityResult import com.geode.launcher.activityresult.GeodeOpenFileActivityResult
import com.geode.launcher.activityresult.GeodeOpenFilesActivityResult import com.geode.launcher.activityresult.GeodeOpenFilesActivityResult
import com.geode.launcher.activityresult.GeodeSaveFileActivityResult import com.geode.launcher.activityresult.GeodeSaveFileActivityResult
@@ -29,6 +33,10 @@ object GeodeUtils {
private lateinit var openFilesResultLauncher: ActivityResultLauncher<GeodeOpenFilesActivityResult.OpenFileParams> private lateinit var openFilesResultLauncher: ActivityResultLauncher<GeodeOpenFilesActivityResult.OpenFileParams>
private lateinit var saveFileResultLauncher: ActivityResultLauncher<GeodeSaveFileActivityResult.SaveFileParams> private lateinit var saveFileResultLauncher: ActivityResultLauncher<GeodeSaveFileActivityResult.SaveFileParams>
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String> private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
private lateinit var internalRequestPermissionsLauncher: ActivityResultLauncher<Array<String>>
private var afterRequestPermissions: (() -> Unit)? = null
private var afterRequestPermissionsFailure: (() -> Unit)? = null
fun setContext(activity: AppCompatActivity) { fun setContext(activity: AppCompatActivity) {
this.activity = WeakReference(activity) this.activity = WeakReference(activity)
@@ -79,6 +87,18 @@ object GeodeUtils {
requestPermissionLauncher = activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> requestPermissionLauncher = activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
permissionCallback(isGranted) permissionCallback(isGranted)
} }
internalRequestPermissionsLauncher = activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
val isGranted = permissions.values.all { it }
if (isGranted) {
afterRequestPermissions?.invoke()
} else {
Toast.makeText(activity, activity.getString(R.string.missing_permissions), Toast.LENGTH_SHORT)
.show()
afterRequestPermissionsFailure?.invoke()
}
}
} }
@JvmStatic @JvmStatic
@@ -152,73 +172,117 @@ object GeodeUtils {
private external fun failedCallback() private external fun failedCallback()
private fun checkForFilePermissions(onSuccess: () -> Unit, onFailure: () -> Unit) {
val permissions = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
listOf(
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO
)
} else {
listOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
val context = activity.get()!!
val needsPermissions = permissions.filter {
ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED
}
if (needsPermissions.isNotEmpty()) {
internalRequestPermissionsLauncher.launch(needsPermissions.toTypedArray())
afterRequestPermissions = onSuccess
} else {
onSuccess()
}
}
@JvmStatic @JvmStatic
fun selectFile(path: String): Boolean { fun selectFile(path: String): Boolean {
activity.get()?.run { var uri: Uri?
var uri: Uri? DocumentFile.fromFile(File(path)).also {
DocumentFile.fromFile(File(path)).also { uri = it.uri
uri = it.uri }
}
try { return try {
openFileResultLauncher.launch(GeodeOpenFileActivityResult.OpenFileParams(arrayOf("*/*"), uri)) checkForFilePermissions(
return true onSuccess = {
} catch (e: ActivityNotFoundException) { openFileResultLauncher.launch(GeodeOpenFileActivityResult.OpenFileParams(arrayOf("*/*"), uri))
return false },
} onFailure = { failedCallback() }
)
true
} catch (e: ActivityNotFoundException) {
false
} }
return false
} }
@JvmStatic @JvmStatic
fun selectFiles(path: String): Boolean { fun selectFiles(path: String): Boolean {
activity.get()?.run { var uri: Uri?
var uri: Uri? DocumentFile.fromFile(File(path)).also {
DocumentFile.fromFile(File(path)).also { uri = it.uri
uri = it.uri }
}
try { return try {
openFilesResultLauncher.launch(GeodeOpenFilesActivityResult.OpenFileParams(arrayOf("*/*"), uri)) checkForFilePermissions(
return true onSuccess = {
} catch (e: ActivityNotFoundException) { openFilesResultLauncher.launch(GeodeOpenFilesActivityResult.OpenFileParams(arrayOf("*/*"), uri))
return false },
} onFailure = { failedCallback() }
)
true
} catch (e: ActivityNotFoundException) {
false
} }
return false
} }
@JvmStatic @JvmStatic
fun selectFolder(path: String): Boolean { fun selectFolder(path: String): Boolean {
activity.get()?.run { var uri: Uri?
var uri: Uri? DocumentFile.fromFile(File(path)).also {
DocumentFile.fromFile(File(path)).also { uri = it.uri
uri = it.uri
}
try {
openDirectoryResultLauncher.launch(uri)
return true
} catch (e: ActivityNotFoundException) {
return false
}
} }
return false
return try {
checkForFilePermissions(
onSuccess = {
openDirectoryResultLauncher.launch(uri)
},
onFailure = { failedCallback() }
)
true
} catch (e: ActivityNotFoundException) {
false
}
} }
@JvmStatic @JvmStatic
fun createFile(path: String): Boolean { fun createFile(path: String): Boolean {
activity.get()?.run { var uri: Uri?
var uri: Uri? DocumentFile.fromFile(File(path)).also {
DocumentFile.fromFile(File(path)).also { uri = it.uri
uri = it.uri }
}
return try {
try { checkForFilePermissions(
saveFileResultLauncher.launch(GeodeSaveFileActivityResult.SaveFileParams(null, uri)) onSuccess = {
return true saveFileResultLauncher.launch(GeodeSaveFileActivityResult.SaveFileParams(null, uri))
} catch (e: ActivityNotFoundException) { },
return false onFailure = { failedCallback() }
} )
true
} catch (e: ActivityNotFoundException) {
false
} }
return false
} }
@JvmStatic @JvmStatic
+1
View File
@@ -53,6 +53,7 @@
<string name="load_failed_generic_error_description">Uncaught error during game load: `%1$s`.\nCheck application logs for more details.</string> <string name="load_failed_generic_error_description">Uncaught error during game load: `%1$s`.\nCheck application logs for more details.</string>
<string name="message_box_cancel">Cancel</string> <string name="message_box_cancel">Cancel</string>
<string name="message_box_accept">OK</string> <string name="message_box_accept">OK</string>
<string name="missing_permissions">Missing required permissions for this action!</string>
<!-- SettingsActivity strings --> <!-- SettingsActivity strings -->
<string name="title_activity_settings">Settings</string> <string name="title_activity_settings">Settings</string>