Skip to content

Instantly share code, notes, and snippets.

@waqasakram117
Created March 24, 2020 07:41
Show Gist options
  • Select an option

  • Save waqasakram117/4256c0e1228a0196a3d09d4302195543 to your computer and use it in GitHub Desktop.

Select an option

Save waqasakram117/4256c0e1228a0196a3d09d4302195543 to your computer and use it in GitHub Desktop.
package app.strikeready.common
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.speech.tts.TextToSpeech
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.*
import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.Future
import java.util.concurrent.TimeUnit
@SuppressLint("Registered")
open class ExperimentalPermissionActivity :AppCompatActivity(){
private val ACT_CHECK_TTS_DATA: Int = 2001
private val TAG = "Base Activity"
private val InitTTS = "initTestTospeech"
private val allPermissionRequestCode by lazy { 1000 }
private val executor by lazy { Executors.newSingleThreadScheduledExecutor()}
protected var lastTask: Future<*>? = null
private var totalRequestPermissions :Int = 0
private var grandedResults :Int = 0
private var deinedResults :Int = 0
private var list:LinkedList<Permission> = LinkedList()
protected var textToSpeech: TextToSpeech? = null
private var permissionGranted: (permission: String) -> Unit = {}
private var permissionDenied: (permission: String) -> Unit = {}
private var permissionBlocked: (permission:String) -> Unit = {}
private var permissionPermanentBlocked: (permission: String)-> Unit = {}
private var allPermissionsAreBlocked: () -> Unit = {}
private var allPermissionsAreGranted: () -> Unit ={}
fun requestAllPermissions(vararg permissionList : Permission,
permissionBlocked:(String)->Unit = {},
permissionGranted: (String) -> Unit = {},
permissionDenied: (String) -> Unit = {},
permissionPermanentBlocked: (String) -> Unit = {},
allPermissionsAreGranted : () -> Unit = {},
allPermissionsAreBlocked : () -> Unit ={}
){
this.permissionBlocked = permissionBlocked
this.permissionGranted = permissionGranted
this.permissionDenied = permissionDenied
this.permissionPermanentBlocked ={}
this.allPermissionsAreBlocked = allPermissionsAreBlocked
this.allPermissionsAreGranted = allPermissionsAreGranted
this.permissionPermanentBlocked = permissionPermanentBlocked
grandedResults = 0
deinedResults = 0
totalRequestPermissions = permissionList.size
list.addAll(permissionList)
permissionChecker()
}
private fun permissionChecker(){
if (list.isNotEmpty()){
list.pop()?.let {
checkForSinglePermission(it)
}
}
}
private fun checkForSinglePermission(permission: Permission) {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
permission.manifestPermission)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
permission.manifestPermission)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
val alertBuilder = AlertDialog.Builder(this)
alertBuilder.setCancelable(true)
alertBuilder.setTitle(permission.rationalTitle)
alertBuilder.setMessage(permission.rationalDescription)
alertBuilder.setPositiveButton(android.R.string.yes) { dialog, which ->
ActivityCompat.requestPermissions(
this@ExperimentalPermissionActivity,
arrayOf(permission.manifestPermission),
allPermissionRequestCode
)
}
val alert = alertBuilder.create()
alert.show()
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
arrayOf(permission.manifestPermission),
allPermissionRequestCode)
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted
permissionGranted.invoke(permission.manifestPermission)
grandedResults++
showLogMsg( "${permission.manifestPermission} is already granted with result $grandedResults")
permissionChecker()
checkTotalNumbersOfResults()
}
}
override fun onRequestPermissionsResult(reqCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(reqCode, permissions, grantResults)
val currentPermission = permissions[0]
when {
PermissionChecker.checkSelfPermission(this , currentPermission) == PERMISSION_DENIED_APP_OP -> {
permissionPermanentBlocked(currentPermission)
deinedResults++
}
PermissionChecker.checkSelfPermission(this , currentPermission) == PERMISSION_GRANTED -> {
permissionGranted(currentPermission)
grandedResults++
showLogMsg("$currentPermission is granted with result $grandedResults")
}
PermissionChecker.checkSelfPermission(this , currentPermission) == PERMISSION_DENIED -> {
var permanent = ActivityCompat.shouldShowRequestPermissionRationale(this,
currentPermission)
if (permanent.not()){
permissionPermanentBlocked(currentPermission)
deinedResults++
showLogMsg("$currentPermission is permanent blocked ${permanent.not()} and falg is $deinedResults")
permissionChecker()
}else{
permissionBlocked.invoke(currentPermission)
deinedResults++
showLogMsg("$currentPermission is blocked with flag $deinedResults")
}
}
}
checkTotalNumbersOfResults()
permissionChecker()
}
private fun checkTotalNumbersOfResults(){
if (totalRequestPermissions != 0 && deinedResults == totalRequestPermissions){
allPermissionsAreBlocked.invoke()
}else if (totalRequestPermissions != 0 && grandedResults == totalRequestPermissions){
allPermissionsAreGranted.invoke()
}
}
override fun onDestroy() {
permissionBlocked = {}
permissionGranted = {}
permissionDenied ={}
permissionPermanentBlocked ={}
allPermissionsAreBlocked = {}
allPermissionsAreGranted ={}
executor.shutdown()
super.onDestroy()
}
override fun onPause() {
textToSpeech?.stop()
textToSpeech?.shutdown()
textToSpeech = null
super.onPause()
}
private fun registerTTS(){
val ttsIntent = Intent()
ttsIntent.action = TextToSpeech.Engine.ACTION_CHECK_TTS_DATA
startActivityForResult(ttsIntent, ACT_CHECK_TTS_DATA)
}
override fun onPostResume() {
super.onPostResume()
if (textToSpeech== null){
// registerTTS()
}
}
override fun onStart() {
super.onStart()
submit(Runnable {
registerTTS()
})
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ACT_CHECK_TTS_DATA) {
if (resultCode ==
TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// Data exists, so we instantiate the TTS engine
textToSpeech = TextToSpeech(this){
if (it != TextToSpeech.ERROR){
textToSpeech?.language = Locale.UK
}
}
} else {
// Data is missing, so we start the TTS installation
// process
val installIntent = Intent()
installIntent.action = (TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA)
startActivity(installIntent);
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putBoolean(
InitTTS , true)
super.onSaveInstanceState(outState)
}
protected open fun submit(task: Runnable?) {
if (!executor.isShutdown) {
lastTask = executor.submit(task)
}
}
protected open fun schedule(task: Runnable?, delay: Long, unit: TimeUnit?) {
if (!executor.isShutdown()) {
lastTask = executor.schedule(task, delay, unit)
}
}
}
data class Permission(val manifestPermission :String,
val rationalTitle :String,
val rationalDescription:String)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment