ActivityLauncherHelper.kt (4243B) - raw


      1 package me.rhunk.snapenhance.ui.util
      2 
      3 import android.app.Activity
      4 import android.content.Intent
      5 import androidx.activity.ComponentActivity
      6 import androidx.activity.result.ActivityResultLauncher
      7 import androidx.activity.result.contract.ActivityResultContracts
      8 import me.rhunk.snapenhance.common.logger.AbstractLogger
      9 
     10 typealias ActivityLauncherCallback = (resultCode: Int, intent: Intent?) -> Unit
     11 
     12 class ActivityLauncherHelper(
     13     val activity: ComponentActivity,
     14 ) {
     15     private var callback: ActivityLauncherCallback? = null
     16     private var permissionResultLauncher: ActivityResultLauncher<String> =
     17         activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
     18             runCatching {
     19                 callback?.let { it(if (result) Activity.RESULT_OK else Activity.RESULT_CANCELED, null) }
     20             }.onFailure {
     21                 AbstractLogger.directError("Failed to process activity result", it)
     22             }
     23             callback = null
     24         }
     25 
     26     private var activityResultLauncher: ActivityResultLauncher<Intent> =
     27         activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
     28             runCatching {
     29                 callback?.let { it(result.resultCode, result.data) }
     30             }.onFailure {
     31                 AbstractLogger.directError("Failed to process activity result", it)
     32             }
     33             callback = null
     34         }
     35 
     36     fun launch(intent: Intent, callback: ActivityLauncherCallback) {
     37         if (this.callback != null) {
     38             throw IllegalStateException("Already launching an activity")
     39         }
     40         this.callback = callback
     41         activityResultLauncher.launch(intent)
     42     }
     43 
     44     fun requestPermission(permission: String, callback: ActivityLauncherCallback) {
     45         if (this.callback != null) {
     46             throw IllegalStateException("Already launching an activity")
     47         }
     48         this.callback = callback
     49         permissionResultLauncher.launch(permission)
     50     }
     51 }
     52 
     53 fun ActivityLauncherHelper.chooseFolder(callback: (uri: String) -> Unit) {
     54     launch(
     55         Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
     56             .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
     57             .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
     58     ) { resultCode, intent ->
     59         if (resultCode != Activity.RESULT_OK) {
     60             return@launch
     61         }
     62         val uri = intent?.data ?: return@launch
     63         val value = uri.toString()
     64         this.activity.contentResolver.takePersistableUriPermission(
     65             uri,
     66             Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
     67         )
     68         callback(value)
     69     }
     70 }
     71 
     72 fun ActivityLauncherHelper.saveFile(name: String, type: String = "*/*", callback: (uri: String) -> Unit) {
     73     launch(
     74         Intent(Intent.ACTION_CREATE_DOCUMENT)
     75             .addCategory(Intent.CATEGORY_OPENABLE)
     76             .setType(type)
     77             .putExtra(Intent.EXTRA_TITLE, name)
     78             .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
     79             .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
     80     ) { resultCode, intent ->
     81         if (resultCode != Activity.RESULT_OK) {
     82             return@launch
     83         }
     84         val uri = intent?.data ?: return@launch
     85         val value = uri.toString()
     86         this.activity.contentResolver.takePersistableUriPermission(
     87             uri,
     88             Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
     89         )
     90         callback(value)
     91     }
     92 }
     93 fun ActivityLauncherHelper.openFile(type: String = "*/*", callback: (uri: String) -> Unit) {
     94     launch(
     95         Intent(Intent.ACTION_OPEN_DOCUMENT)
     96             .addCategory(Intent.CATEGORY_OPENABLE)
     97             .setType(type)
     98             .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
     99             .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    100     ) { resultCode, intent ->
    101         if (resultCode != Activity.RESULT_OK) {
    102             return@launch
    103         }
    104         val uri = intent?.data ?: return@launch
    105         val value = uri.toString()
    106         this.activity.contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    107         callback(value)
    108     }
    109 }