From 7b0f5f39aba23e6fe45dca4d8ae3e62b746724e1 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Sat, 26 Oct 2019 17:16:29 +0300 Subject: [PATCH 01/10] Fix show of settings popup of first permission dismiss --- app/build.gradle | 4 ++-- .../com/livetyping/permission/ActivePermissionRequest.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a81bfe3..ee84010 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,8 +39,8 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.android.support:appcompat-v7:28.0.0' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1' implementation "com.google.android.gms:play-services-auth:16.0.1" diff --git a/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt index 519d173..0c8bf41 100644 --- a/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt +++ b/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt @@ -31,7 +31,7 @@ internal class ActivePermissionRequest( if (areAllPermissionGranted(activity)) { invokeResult(activity) } else { - if (!rationaleShowed) { + if (!rationaleShowed && getPermissionsWithoutRationale(activity).isNotEmpty()) { showOpenSettingsDialog(activity) } else { invokeResult(activity) From eca878749c493817afde559b21475c1f478b4b92 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Sat, 18 Jan 2020 17:02:03 +0300 Subject: [PATCH 02/10] Remove default FileProvider from images module --- images/src/main/AndroidManifest.xml | 16 +--------------- .../livetyping/images/photo/DefaultProvider.kt | 6 ------ images/src/main/res/xml/default_file_paths.xml | 8 -------- 3 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 images/src/main/kotlin/com/livetyping/images/photo/DefaultProvider.kt delete mode 100644 images/src/main/res/xml/default_file_paths.xml diff --git a/images/src/main/AndroidManifest.xml b/images/src/main/AndroidManifest.xml index 2d097be..feebc64 100644 --- a/images/src/main/AndroidManifest.xml +++ b/images/src/main/AndroidManifest.xml @@ -1,15 +1 @@ - - - - - - - - + diff --git a/images/src/main/kotlin/com/livetyping/images/photo/DefaultProvider.kt b/images/src/main/kotlin/com/livetyping/images/photo/DefaultProvider.kt deleted file mode 100644 index 879b316..0000000 --- a/images/src/main/kotlin/com/livetyping/images/photo/DefaultProvider.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.livetyping.images.photo - -import androidx.core.content.FileProvider - - -class DefaultProvider : FileProvider() diff --git a/images/src/main/res/xml/default_file_paths.xml b/images/src/main/res/xml/default_file_paths.xml deleted file mode 100644 index 97cfd6b..0000000 --- a/images/src/main/res/xml/default_file_paths.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - From 4ec21857859d298dc3b3a7e17e684e615d70228d Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Sun, 19 Jan 2020 22:03:19 +0300 Subject: [PATCH 03/10] Add BinderRequest and single passive permission request --- .../BinderExampleApplication.kt | 5 +++ .../PermissionExampleActivity.kt | 18 +++++--- .../com/livetyping/core/BinderRequest.kt | 23 ++++++++++ .../kotlin/com/livetyping/core/NewBinder.kt | 42 ++++++++++++++++++ .../PassivePermissionBinderRequest.kt | 43 +++++++++++++++++++ 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 core/src/main/kotlin/com/livetyping/core/BinderRequest.kt create mode 100644 core/src/main/kotlin/com/livetyping/core/NewBinder.kt create mode 100644 permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt b/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt index c2f2377..9d0a798 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt @@ -1,6 +1,7 @@ package com.livetyping.activitybinder import android.app.Application +import com.livetyping.core.NewBinder import com.livetyping.facebook.FacebookInitializer import com.livetyping.images.ImagesBinder import com.livetyping.instagram.InstagramInitializer @@ -22,6 +23,10 @@ class BinderExampleApplication : Application() { ImagesBinder(applicationContext.packageName + ".provider", R.xml.file_path) } + val newBinder:NewBinder by lazy { + NewBinder() + } + override fun onCreate() { super.onCreate() socialLoginBinder.initializeNetworks(this, diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt index 9325d92..b59d560 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt @@ -3,8 +3,10 @@ package com.livetyping.activitybinder import android.Manifest import android.content.Intent import android.os.Bundle -import android.util.Log +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity +import com.livetyping.core.NewBinder +import com.livetyping.permission.PassivePermissionBinderRequest import com.livetyping.permission.PermissionBinder import kotlinx.android.synthetic.main.activity_permissions.* @@ -16,11 +18,13 @@ class PermissionExampleActivity : AppCompatActivity() { } private lateinit var permissionBinder: PermissionBinder + private lateinit var newBinder: NewBinder override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_permissions) permissionBinder = (application as BinderExampleApplication).permissionBinder + newBinder = (application as BinderExampleApplication).newBinder handleButtonSinglePermissions() handleButtonMultiplyPermissions() } @@ -56,9 +60,9 @@ class PermissionExampleActivity : AppCompatActivity() { private fun handleButtonSinglePermissions() { single_passive.setOnClickListener { - permissionBinder.passivePermission(Manifest.permission.READ_EXTERNAL_STORAGE) { + newBinder.request(PassivePermissionBinderRequest(Manifest.permission.READ_EXTERNAL_STORAGE) { handleOutputResults(it, TAG_SINGLE) - } + }) } val rationaleText = getString(R.string.active_permission_rationale_text) @@ -84,28 +88,32 @@ class PermissionExampleActivity : AppCompatActivity() { override fun onStart() { super.onStart() permissionBinder.attach(this) + newBinder.attach(this) } override fun onStop() { permissionBinder.detach(this) + newBinder.detach(this) super.onStop() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) permissionBinder.onActivityResult(requestCode, data, this) + newBinder.onActivityResult(requestCode, resultCode, data) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) permissionBinder.onRequestPermissionResult(requestCode, grantResults) + newBinder.onRequestPermissionsResult(requestCode, permissions, grantResults) } private fun granted(tag: String, permission: String = "") { - Log.i(tag, "$permission was granted") + Toast.makeText(this, "$permission was granted", Toast.LENGTH_SHORT).show() } private fun denied(tag: String, permission: String = "") { - Log.i(tag, "$permission was denied") + Toast.makeText(this, "$permission was denied", Toast.LENGTH_SHORT).show() } } diff --git a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt new file mode 100644 index 0000000..5ffe014 --- /dev/null +++ b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt @@ -0,0 +1,23 @@ +package com.livetyping.core + +import android.app.Activity +import android.content.Intent + + +abstract class BinderRequest { + + var requestCode: Int = 0 + + internal fun onActivityResult(resultCode: Int, data: Intent?) { + //for override + } + + open fun onRequestPermissionsResult( + permissions: Array, + grantResults: IntArray + ) { + //for override + } + + abstract fun request(activity: Activity) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt new file mode 100644 index 0000000..d76e509 --- /dev/null +++ b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt @@ -0,0 +1,42 @@ +package com.livetyping.core + +import android.content.Intent +import kotlin.random.Random + + +class NewBinder : Binder() { + + private val activityResultRequests by lazy { + mutableMapOf>() + } + private val permissionResultRequests by lazy { + mutableMapOf>() + } + + fun request(request: BinderRequest<*>) { + request.requestCode = generateRequestCode() + activityResultRequests[request.requestCode] = request + permissionResultRequests[request.requestCode] = request + getAttachedObject()?.let { request.request(it) } + } + + fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + activityResultRequests[requestCode]?.onActivityResult(resultCode, data) + } + + fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + permissionResultRequests[requestCode]?.onRequestPermissionsResult(permissions, grantResults) + } + + + //TODO need generator for request codes + private val random = Random(100) + + private fun generateRequestCode(): Int { + return random.nextInt(100) + 100 + } +} \ No newline at end of file diff --git a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt new file mode 100644 index 0000000..107a5b2 --- /dev/null +++ b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt @@ -0,0 +1,43 @@ +package com.livetyping.permission + +import android.app.Activity +import android.content.pm.PackageManager +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import androidx.core.content.PermissionChecker +import com.livetyping.core.BinderRequest + + +class PassivePermissionBinderRequest( + private val permission: String, + private val block: (granted: Boolean) -> Unit +) : + BinderRequest() { + + override fun request(activity: Activity) { + if (isPermissionGranted(permission, activity)) { + block(true) + } else { + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) { + block(false) + } else ActivityCompat.requestPermissions(activity, arrayOf(permission), requestCode) + } + } + + override fun onRequestPermissionsResult( + permissions: Array, + grantResults: IntArray + ) { + if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + block(true) + } else block(false) + } + + @PermissionChecker.PermissionResult + private fun isPermissionGranted(permission: String, activity: Activity): Boolean { + return ContextCompat.checkSelfPermission( + activity, + permission + ) == PermissionChecker.PERMISSION_GRANTED + } +} \ No newline at end of file From 1843125c5603271286d0cc72b2695437052c94d1 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Mon, 20 Jan 2020 22:43:03 +0300 Subject: [PATCH 04/10] Work on access rights --- .../com/livetyping/core/BinderRequest.kt | 21 +++++++++++++++++-- .../kotlin/com/livetyping/core/NewBinder.kt | 18 +++++++--------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt index 5ffe014..06d4def 100644 --- a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt +++ b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt @@ -6,7 +6,24 @@ import android.content.Intent abstract class BinderRequest { - var requestCode: Int = 0 + protected var requestCode: Int = 0 + + internal fun setRequestCode(requestCode: Int) { + this.requestCode = requestCode + } + + internal fun internalActivityResult(resultCode: Int, data: Intent?) { + onActivityResult(resultCode, data) + } + + internal fun internalPermissionResult( + permissions: Array, + grantResults: IntArray + ) { + onRequestPermissionsResult(permissions, grantResults) + } + + internal fun internalRequest(activity: Activity) = request(activity) internal fun onActivityResult(resultCode: Int, data: Intent?) { //for override @@ -19,5 +36,5 @@ abstract class BinderRequest { //for override } - abstract fun request(activity: Activity) + protected abstract fun request(activity: Activity) } \ No newline at end of file diff --git a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt index d76e509..e947df5 100644 --- a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt +++ b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt @@ -6,22 +6,20 @@ import kotlin.random.Random class NewBinder : Binder() { - private val activityResultRequests by lazy { - mutableMapOf>() - } - private val permissionResultRequests by lazy { + + private val requests by lazy { mutableMapOf>() } fun request(request: BinderRequest<*>) { - request.requestCode = generateRequestCode() - activityResultRequests[request.requestCode] = request - permissionResultRequests[request.requestCode] = request - getAttachedObject()?.let { request.request(it) } + val generateRequestCode = generateRequestCode() + request.setRequestCode(generateRequestCode) + requests[generateRequestCode] = request + getAttachedObject()?.let { request.internalRequest(it) } } fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - activityResultRequests[requestCode]?.onActivityResult(resultCode, data) + requests[requestCode]?.onActivityResult(resultCode, data) } fun onRequestPermissionsResult( @@ -29,7 +27,7 @@ class NewBinder : Binder() { permissions: Array, grantResults: IntArray ) { - permissionResultRequests[requestCode]?.onRequestPermissionsResult(permissions, grantResults) + requests[requestCode]?.onRequestPermissionsResult(permissions, grantResults) } From 8a6d3da8ab4f1d77c1670ec40c153213decfed26 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Mon, 20 Jan 2020 22:50:23 +0300 Subject: [PATCH 05/10] Rework request method with generic --- .../activitybinder/PermissionExampleActivity.kt | 8 ++++++-- core/src/main/kotlin/com/livetyping/core/BinderRequest.kt | 5 +++++ core/src/main/kotlin/com/livetyping/core/NewBinder.kt | 6 +++--- .../permission/PassivePermissionBinderRequest.kt | 3 +-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt index b59d560..60c8879 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt @@ -60,9 +60,13 @@ class PermissionExampleActivity : AppCompatActivity() { private fun handleButtonSinglePermissions() { single_passive.setOnClickListener { - newBinder.request(PassivePermissionBinderRequest(Manifest.permission.READ_EXTERNAL_STORAGE) { + newBinder.request( + PassivePermissionBinderRequest( + Manifest.permission.READ_EXTERNAL_STORAGE + ) + ) { handleOutputResults(it, TAG_SINGLE) - }) + } } val rationaleText = getString(R.string.active_permission_rationale_text) diff --git a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt index 06d4def..de70f03 100644 --- a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt +++ b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt @@ -7,11 +7,16 @@ import android.content.Intent abstract class BinderRequest { protected var requestCode: Int = 0 + protected lateinit var block: (result: T) -> Unit internal fun setRequestCode(requestCode: Int) { this.requestCode = requestCode } + internal fun setBlock(block: (result: T) -> Unit) { + this.block = block + } + internal fun internalActivityResult(resultCode: Int, data: Intent?) { onActivityResult(resultCode, data) } diff --git a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt index e947df5..c24df67 100644 --- a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt +++ b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt @@ -5,15 +5,15 @@ import kotlin.random.Random class NewBinder : Binder() { - - + private val requests by lazy { mutableMapOf>() } - fun request(request: BinderRequest<*>) { + fun request(request: BinderRequest, resultBlock: (result: T) -> Unit) { val generateRequestCode = generateRequestCode() request.setRequestCode(generateRequestCode) + request.setBlock(resultBlock) requests[generateRequestCode] = request getAttachedObject()?.let { request.internalRequest(it) } } diff --git a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt index 107a5b2..58b4b74 100644 --- a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt +++ b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt @@ -9,8 +9,7 @@ import com.livetyping.core.BinderRequest class PassivePermissionBinderRequest( - private val permission: String, - private val block: (granted: Boolean) -> Unit + private val permission: String ) : BinderRequest() { From c137412acb568b6afd7b96e874998734eb933a42 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Mon, 20 Jan 2020 22:54:18 +0300 Subject: [PATCH 06/10] Change access rights for BinderRequest methods --- core/src/main/kotlin/com/livetyping/core/BinderRequest.kt | 4 ++-- core/src/main/kotlin/com/livetyping/core/NewBinder.kt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt index de70f03..ac22d24 100644 --- a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt +++ b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt @@ -30,11 +30,11 @@ abstract class BinderRequest { internal fun internalRequest(activity: Activity) = request(activity) - internal fun onActivityResult(resultCode: Int, data: Intent?) { + protected open fun onActivityResult(resultCode: Int, data: Intent?) { //for override } - open fun onRequestPermissionsResult( + protected open fun onRequestPermissionsResult( permissions: Array, grantResults: IntArray ) { diff --git a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt index c24df67..380a807 100644 --- a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt +++ b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt @@ -5,7 +5,7 @@ import kotlin.random.Random class NewBinder : Binder() { - + private val requests by lazy { mutableMapOf>() } @@ -19,7 +19,7 @@ class NewBinder : Binder() { } fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - requests[requestCode]?.onActivityResult(resultCode, data) + requests[requestCode]?.internalActivityResult(resultCode, data) } fun onRequestPermissionsResult( @@ -27,7 +27,7 @@ class NewBinder : Binder() { permissions: Array, grantResults: IntArray ) { - requests[requestCode]?.onRequestPermissionsResult(permissions, grantResults) + requests[requestCode]?.internalPermissionResult(permissions, grantResults) } From 70ef2ab48ef3d0208faa85ef818e11bed1a0a3ec Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Tue, 21 Jan 2020 22:52:38 +0300 Subject: [PATCH 07/10] Add active request permission --- .../PermissionExampleActivity.kt | 18 ++-- .../com/livetyping/core/BinderRequest.kt | 4 +- .../kotlin/com/livetyping/core/NewBinder.kt | 5 +- .../request/ActivePermissionBinderRequest.kt | 84 +++++++++++++++++++ .../MultiplyPermissionBinderRequest.kt | 5 ++ .../PassivePermissionBinderRequest.kt | 16 +--- .../request/SinglePermissionBinderRequest.kt | 18 ++++ permission/src/main/res/values/strings.xml | 2 +- 8 files changed, 129 insertions(+), 23 deletions(-) create mode 100644 permission/src/main/kotlin/com/livetyping/permission/request/ActivePermissionBinderRequest.kt create mode 100644 permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt rename permission/src/main/kotlin/com/livetyping/permission/{ => request}/PassivePermissionBinderRequest.kt (64%) create mode 100644 permission/src/main/kotlin/com/livetyping/permission/request/SinglePermissionBinderRequest.kt diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt index 60c8879..62249d3 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt @@ -6,8 +6,9 @@ import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.livetyping.core.NewBinder -import com.livetyping.permission.PassivePermissionBinderRequest import com.livetyping.permission.PermissionBinder +import com.livetyping.permission.request.ActivePermissionBinderRequest +import com.livetyping.permission.request.PassivePermissionBinderRequest import kotlinx.android.synthetic.main.activity_permissions.* @@ -61,22 +62,23 @@ class PermissionExampleActivity : AppCompatActivity() { private fun handleButtonSinglePermissions() { single_passive.setOnClickListener { newBinder.request( - PassivePermissionBinderRequest( - Manifest.permission.READ_EXTERNAL_STORAGE - ) + PassivePermissionBinderRequest(Manifest.permission.READ_EXTERNAL_STORAGE) ) { handleOutputResults(it, TAG_SINGLE) } } - val rationaleText = getString(R.string.active_permission_rationale_text) - //cab be placed in active permission method as third parameter - val settingsButtonText = getString(R.string.active_permission_rationale_button_text) single_active.setOnClickListener { - permissionBinder.activePermission(Manifest.permission.CAMERA, rationaleText) { + newBinder.request( + ActivePermissionBinderRequest( + Manifest.permission.CAMERA, + R.string.active_permission_rationale_text + ) + ) { handleOutputResults(it, TAG_SINGLE) } } + single_global.setOnClickListener { permissionBinder.globalPermission(Manifest.permission.USE_SIP, ShowGlobalExplanationActivity::class.java) { diff --git a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt index ac22d24..ab33016 100644 --- a/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt +++ b/core/src/main/kotlin/com/livetyping/core/BinderRequest.kt @@ -22,10 +22,11 @@ abstract class BinderRequest { } internal fun internalPermissionResult( + activity: Activity, permissions: Array, grantResults: IntArray ) { - onRequestPermissionsResult(permissions, grantResults) + onRequestPermissionsResult(activity, permissions, grantResults) } internal fun internalRequest(activity: Activity) = request(activity) @@ -35,6 +36,7 @@ abstract class BinderRequest { } protected open fun onRequestPermissionsResult( + activity: Activity, permissions: Array, grantResults: IntArray ) { diff --git a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt index 380a807..172921b 100644 --- a/core/src/main/kotlin/com/livetyping/core/NewBinder.kt +++ b/core/src/main/kotlin/com/livetyping/core/NewBinder.kt @@ -27,7 +27,10 @@ class NewBinder : Binder() { permissions: Array, grantResults: IntArray ) { - requests[requestCode]?.internalPermissionResult(permissions, grantResults) + getAttachedObject()?.let { + requests[requestCode]?.internalPermissionResult(it, permissions, grantResults) + } + } diff --git a/permission/src/main/kotlin/com/livetyping/permission/request/ActivePermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/ActivePermissionBinderRequest.kt new file mode 100644 index 0000000..6846eca --- /dev/null +++ b/permission/src/main/kotlin/com/livetyping/permission/request/ActivePermissionBinderRequest.kt @@ -0,0 +1,84 @@ +package com.livetyping.permission.request + +import android.app.Activity +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.provider.Settings +import androidx.annotation.StringRes +import androidx.appcompat.app.AlertDialog +import androidx.core.app.ActivityCompat +import com.livetyping.permission.R + + +class ActivePermissionBinderRequest( + private val permission: String, + @StringRes private val rationaleTextStringRes: Int, + @StringRes private val buttonOkTextStringRes: Int = android.R.string.ok, + @StringRes private val buttonSettingsStringRes: Int = R.string.permission_settings_default_button_text +) : + SinglePermissionBinderRequest() { + + private var rationaleShowed = false + + override fun request(activity: Activity) { + if (isPermissionGranted(permission, activity)) { + block(true) + } else { + if (shouldShowRationale(activity)) { + rationaleShowed = true + showRationaleDialog(activity, buttonOkTextStringRes) { requestPermission(activity) } + } else { + requestPermission(activity) + } + } + } + + override fun onRequestPermissionsResult( + activity: Activity, + permissions: Array, + grantResults: IntArray + ) { + if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + block(true) + } else { + if (rationaleShowed.not() && shouldShowRationale(activity)) { + block(false) + } else { + if (rationaleShowed) { + block(false) + } else { + showRationaleDialog(activity, buttonSettingsStringRes) { openAppSettings(activity) } + } + } + } + } + + private fun shouldShowRationale(activity: Activity): Boolean { + return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) + } + + private fun showRationaleDialog(activity: Activity, buttonResId: Int, buttonBlock: () -> Unit) { + AlertDialog.Builder(activity) + .setMessage(rationaleTextStringRes) + .setPositiveButton(buttonResId) { _, _ -> buttonBlock() } + .show() + } + + private fun requestPermission(activity: Activity) { + ActivityCompat.requestPermissions( + activity, + arrayOf(permission), + requestCode + ) + } + + private fun openAppSettings(activity: Activity) { + val intent = Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse("package:${activity.packageName}") + ) + intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) + activity.startActivityForResult(intent, requestCode) + } +} \ No newline at end of file diff --git a/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt new file mode 100644 index 0000000..23363a2 --- /dev/null +++ b/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt @@ -0,0 +1,5 @@ +package com.livetyping.permission.request + + +class MultiplyPermissionBinderRequest { +} \ No newline at end of file diff --git a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/PassivePermissionBinderRequest.kt similarity index 64% rename from permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt rename to permission/src/main/kotlin/com/livetyping/permission/request/PassivePermissionBinderRequest.kt index 58b4b74..d9f73ad 100644 --- a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionBinderRequest.kt +++ b/permission/src/main/kotlin/com/livetyping/permission/request/PassivePermissionBinderRequest.kt @@ -1,17 +1,14 @@ -package com.livetyping.permission +package com.livetyping.permission.request import android.app.Activity import android.content.pm.PackageManager import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat -import androidx.core.content.PermissionChecker -import com.livetyping.core.BinderRequest class PassivePermissionBinderRequest( private val permission: String ) : - BinderRequest() { + SinglePermissionBinderRequest() { override fun request(activity: Activity) { if (isPermissionGranted(permission, activity)) { @@ -24,6 +21,7 @@ class PassivePermissionBinderRequest( } override fun onRequestPermissionsResult( + activity: Activity, permissions: Array, grantResults: IntArray ) { @@ -32,11 +30,5 @@ class PassivePermissionBinderRequest( } else block(false) } - @PermissionChecker.PermissionResult - private fun isPermissionGranted(permission: String, activity: Activity): Boolean { - return ContextCompat.checkSelfPermission( - activity, - permission - ) == PermissionChecker.PERMISSION_GRANTED - } + } \ No newline at end of file diff --git a/permission/src/main/kotlin/com/livetyping/permission/request/SinglePermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/SinglePermissionBinderRequest.kt new file mode 100644 index 0000000..00bed66 --- /dev/null +++ b/permission/src/main/kotlin/com/livetyping/permission/request/SinglePermissionBinderRequest.kt @@ -0,0 +1,18 @@ +package com.livetyping.permission.request + +import android.app.Activity +import androidx.core.content.ContextCompat +import androidx.core.content.PermissionChecker +import com.livetyping.core.BinderRequest + + +abstract class SinglePermissionBinderRequest : BinderRequest() { + + @PermissionChecker.PermissionResult + protected fun isPermissionGranted(permission: String, activity: Activity): Boolean { + return ContextCompat.checkSelfPermission( + activity, + permission + ) == PermissionChecker.PERMISSION_GRANTED + } +} \ No newline at end of file diff --git a/permission/src/main/res/values/strings.xml b/permission/src/main/res/values/strings.xml index 8ed2bb5..ea6d270 100644 --- a/permission/src/main/res/values/strings.xml +++ b/permission/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - permission + settings From 9ecefe1846cdaa244f9aae763423885ab90dbc21 Mon Sep 17 00:00:00 2001 From: Dmitry Alexeeenkoff Date: Fri, 7 Feb 2020 23:32:36 +0300 Subject: [PATCH 08/10] Add general multiple request of permissions --- .../PermissionExampleActivity.kt | 15 ++++++- .../MultiplyGeneralPermissionBinderRequest.kt | 44 +++++++++++++++++++ .../MultiplyPermissionBinderRequest.kt | 5 --- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 permission/src/main/kotlin/com/livetyping/permission/request/MultiplyGeneralPermissionBinderRequest.kt delete mode 100644 permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt index 62249d3..6e16b7d 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt @@ -3,11 +3,13 @@ package com.livetyping.activitybinder import android.Manifest import android.content.Intent import android.os.Bundle +import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.livetyping.core.NewBinder import com.livetyping.permission.PermissionBinder import com.livetyping.permission.request.ActivePermissionBinderRequest +import com.livetyping.permission.request.MultiplyGeneralPermissionBinderRequest import com.livetyping.permission.request.PassivePermissionBinderRequest import kotlinx.android.synthetic.main.activity_permissions.* @@ -32,9 +34,18 @@ class PermissionExampleActivity : AppCompatActivity() { private fun handleButtonMultiplyPermissions() { multiply_passive.setOnClickListener { - permissionBinder.passivePermission(listOf(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)) { + val request = MultiplyGeneralPermissionBinderRequest( + listOf( + Manifest.permission.READ_CONTACTS, + Manifest.permission.USE_SIP + ) + ) + newBinder.request(request) { for ((permission, isGranted) in it) { - handleOutputResults(isGranted, TAG_MULTIPLY, permission) + Log.d( + "PERMISSION_BINDER: ", + "$permission is " + if (isGranted) "granted" else "denied" + ) } } } diff --git a/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyGeneralPermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyGeneralPermissionBinderRequest.kt new file mode 100644 index 0000000..5e87b21 --- /dev/null +++ b/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyGeneralPermissionBinderRequest.kt @@ -0,0 +1,44 @@ +package com.livetyping.permission.request + +import android.app.Activity +import android.content.pm.PackageManager +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import com.livetyping.core.BinderRequest + + +class MultiplyGeneralPermissionBinderRequest( + private val permissions: Iterable +) : BinderRequest>() { + + private val result = mutableMapOf() + + override fun request(activity: Activity) { + val groupedByGranted = permissions.groupBy { + ContextCompat.checkSelfPermission( + activity, + it + ) == PackageManager.PERMISSION_GRANTED + } + groupedByGranted[true]?.forEach { result[it] = true } + val denied = groupedByGranted[false] + if (denied == null) { + block(result) + } else { + denied.toTypedArray().let { + ActivityCompat.requestPermissions(activity, it, requestCode) + } + } + } + + override fun onRequestPermissionsResult( + activity: Activity, + permissions: Array, + grantResults: IntArray + ) { + permissions.forEachIndexed { index, permission -> + result[permission] = grantResults[index] == PackageManager.PERMISSION_GRANTED + } + block(result) + } +} \ No newline at end of file diff --git a/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt deleted file mode 100644 index 23363a2..0000000 --- a/permission/src/main/kotlin/com/livetyping/permission/request/MultiplyPermissionBinderRequest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.livetyping.permission.request - - -class MultiplyPermissionBinderRequest { -} \ No newline at end of file From 8990a5b8789bafb79d57cc201c5ca7e64697f179 Mon Sep 17 00:00:00 2001 From: alexeenkoff Date: Mon, 30 Mar 2020 23:44:49 +0300 Subject: [PATCH 09/10] Merge LiveTyping-develop --- app/build.gradle | 18 +-- .../activitybinder/ExampleInstrumentedTest.kt | 24 --- app/src/main/AndroidManifest.xml | 12 +- .../BinderExampleApplication.kt | 20 +-- .../activitybinder/ImageBinderActivity.kt | 4 +- .../PermissionExampleActivity.kt | 138 +++++++++------- .../activitybinder/SocialActivity.kt | 117 ++++++++++---- .../main/res/layout/activity_permissions.xml | 73 +++++---- app/src/main/res/layout/activity_social.xml | 15 +- app/src/main/res/values/strings.xml | 6 + app/src/main/res/values/styles.xml | 5 + .../activitybinder/ExampleUnitTest.kt | 17 -- build.gradle | 13 +- core/proguard-rules.pro | 21 --- .../core/ExampleInstrumentedTest.java | 26 --- .../com/livetyping/core/ExampleUnitTest.java | 17 -- gradle.properties | 15 +- gradle/wrapper/gradle-wrapper.properties | 4 +- images/build.gradle | 5 +- kotlin_android_library.gradle | 11 +- permission/build.gradle | 5 +- permission/proguard-rules.pro | 21 --- .../permission/ExampleInstrumentedTest.java | 26 --- .../permission/ActivePermissionRequest.kt | 74 +++++---- .../permission/GlobalPermissionRequest.kt | 41 +++-- .../permission/PassivePermissionRequest.kt | 21 ++- .../livetyping/permission/PermissionBinder.kt | 148 ++++++++++++------ .../permission/PermissionRequest.kt | 90 ++++++----- .../permission/PermissionRequestCodes.kt | 73 +++++---- settings.gradle | 1 - social/facebook/build.gradle | 12 +- social/facebook/proguard-rules.pro | 21 --- .../facebook/ExampleInstrumentedTest.java | 26 --- .../facebook/FacebookInitializer.kt | 6 +- .../livetyping/facebook/FacebookLoginError.kt | 10 -- .../facebook/FacebookLoginResult.kt | 16 +- .../livetyping/facebook/FacebookNetwork.kt | 57 ++++--- .../livetyping/facebook/ExampleUnitTest.java | 17 -- social/google/build.gradle | 12 +- .../livetyping/google/GoogleAccountNetwork.kt | 52 +++--- .../livetyping/google/GoogleAccountResult.kt | 9 +- .../livetyping/google/GoogleInitializer.kt | 4 +- .../com/livetyping/google/GoogleLoginError.kt | 9 -- .../livetyping/google/GoogleTokenLoader.kt | 25 --- .../livetyping/google/GoogleTokenNetwork.kt | 91 ++++++----- .../livetyping/google/GoogleTokenResult.kt | 6 +- social/instagram/.gitignore | 1 - social/instagram/build.gradle | 10 -- social/instagram/proguard-rules.pro | 21 --- .../instagram/ExampleInstrumentedTest.java | 26 --- social/instagram/src/main/AndroidManifest.xml | 1 - .../instagram/InstagramInitializer.kt | 13 -- .../instagram/InstagramLoginError.kt | 10 -- .../instagram/InstagramLoginResult.kt | 7 - .../livetyping/instagram/InstagramNetwork.kt | 41 ----- .../instagram/src/main/res/values/strings.xml | 3 - .../livetyping/instagram/ExampleUnitTest.java | 17 -- social/logincore/build.gradle | 1 - social/logincore/proguard-rules.pro | 21 --- .../logincore/ExampleInstrumentedTest.java | 26 --- .../livetyping/logincore/SocialInitializer.kt | 3 +- .../livetyping/logincore/SocialLoginBinder.kt | 36 +++-- .../livetyping/logincore/SocialLoginError.kt | 6 - .../livetyping/logincore/SocialLoginResult.kt | 4 +- .../com/livetyping/logincore/SocialNetwork.kt | 11 +- .../livetyping/logincore/ExampleUnitTest.java | 17 -- social/social_login_item.gradle | 4 +- social/vk/build.gradle | 10 +- social/vk/proguard-rules.pro | 21 --- .../vk/ExampleInstrumentedTest.java | 26 --- .../kotlin/com/livetyping/vk/VkInitializer.kt | 7 +- .../kotlin/com/livetyping/vk/VkLoginError.kt | 10 -- .../kotlin/com/livetyping/vk/VkLoginResult.kt | 12 +- .../kotlin/com/livetyping/vk/VkNetwork.kt | 60 ++++--- .../com/livetyping/vk/ExampleUnitTest.java | 17 -- versions.gradle | 16 ++ 76 files changed, 773 insertions(+), 1119 deletions(-) delete mode 100644 app/src/androidTest/java/com/livetyping/activitybinder/ExampleInstrumentedTest.kt delete mode 100644 app/src/test/java/com/livetyping/activitybinder/ExampleUnitTest.kt delete mode 100644 core/proguard-rules.pro delete mode 100644 core/src/androidTest/java/com/livetyping/core/ExampleInstrumentedTest.java delete mode 100644 core/src/test/java/com/livetyping/core/ExampleUnitTest.java delete mode 100644 permission/proguard-rules.pro delete mode 100644 permission/src/androidTest/java/com/livetyping/permission/ExampleInstrumentedTest.java delete mode 100644 social/facebook/proguard-rules.pro delete mode 100644 social/facebook/src/androidTest/java/com/livetyping/facebook/ExampleInstrumentedTest.java delete mode 100644 social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginError.kt delete mode 100644 social/facebook/src/test/java/com/livetyping/facebook/ExampleUnitTest.java delete mode 100644 social/google/src/main/java/com/livetyping/google/GoogleLoginError.kt delete mode 100644 social/google/src/main/java/com/livetyping/google/GoogleTokenLoader.kt delete mode 100644 social/instagram/.gitignore delete mode 100644 social/instagram/build.gradle delete mode 100644 social/instagram/proguard-rules.pro delete mode 100644 social/instagram/src/androidTest/java/com/livetyping/instagram/ExampleInstrumentedTest.java delete mode 100644 social/instagram/src/main/AndroidManifest.xml delete mode 100644 social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramInitializer.kt delete mode 100644 social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginError.kt delete mode 100644 social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginResult.kt delete mode 100644 social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramNetwork.kt delete mode 100644 social/instagram/src/main/res/values/strings.xml delete mode 100644 social/instagram/src/test/java/com/livetyping/instagram/ExampleUnitTest.java delete mode 100644 social/logincore/proguard-rules.pro delete mode 100644 social/logincore/src/androidTest/java/com/livetyping/logincore/ExampleInstrumentedTest.java delete mode 100644 social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginError.kt delete mode 100644 social/logincore/src/test/java/com/livetyping/logincore/ExampleUnitTest.java delete mode 100644 social/vk/proguard-rules.pro delete mode 100644 social/vk/src/androidTest/java/com/livetyping/vk/ExampleInstrumentedTest.java delete mode 100644 social/vk/src/main/kotlin/com/livetyping/vk/VkLoginError.kt delete mode 100644 social/vk/src/test/java/com/livetyping/vk/ExampleUnitTest.java create mode 100644 versions.gradle diff --git a/app/build.gradle b/app/build.gradle index ee84010..28d9968 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,8 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +apply from: "$rootDir/versions.gradle" + android { compileSdkVersion 28 defaultConfig { @@ -12,7 +14,7 @@ android { targetSdkVersion 28 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -39,19 +41,17 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1' - implementation "com.google.android.gms:play-services-auth:16.0.1" - implementation 'com.squareup.picasso:picasso:2.71828' + implementation "com.google.android.material:material:$versions.material" + implementation "androidx.constraintlayout:constraintlayout:$versions.constraint_layout" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" + implementation "com.google.android.gms:play-services-auth:$versions.auth" implementation project(':core') -// implementation 'com.github.LiveTyping.activity-binder:core:0.1.3' + implementation project(':social:logincore') implementation project(':social:vk') implementation project(':social:facebook') - implementation project(':social:instagram') implementation project(':social:google') implementation project(':permission') diff --git a/app/src/androidTest/java/com/livetyping/activitybinder/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/livetyping/activitybinder/ExampleInstrumentedTest.kt deleted file mode 100644 index e38305e..0000000 --- a/app/src/androidTest/java/com/livetyping/activitybinder/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.livetyping.activitybinder - -import android.support.test.InstrumentationRegistry -import android.support.test.runner.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getTargetContext() - assertEquals("com.livetyping.activity_binder", appContext.packageName) - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 50e8b1a..b1dfb86 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ - + @@ -46,15 +46,6 @@ android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" /> - - - - - - diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt b/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt index c2f2377..3846626 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/BinderExampleApplication.kt @@ -2,33 +2,33 @@ package com.livetyping.activitybinder import android.app.Application import com.livetyping.facebook.FacebookInitializer +import com.livetyping.google.GoogleInitializer import com.livetyping.images.ImagesBinder -import com.livetyping.instagram.InstagramInitializer import com.livetyping.logincore.SocialLoginBinder import com.livetyping.permission.PermissionBinder import com.livetyping.vk.VkInitializer class BinderExampleApplication : Application() { - val socialLoginBinder: SocialLoginBinder by lazy { + val socialLoginBinder by lazy { SocialLoginBinder() } - val permissionBinder: PermissionBinder by lazy { + val permissionBinder by lazy { PermissionBinder() } - val testImagesBinder: ImagesBinder by lazy { + val testImagesBinder by lazy { ImagesBinder(applicationContext.packageName + ".provider", R.xml.file_path) } override fun onCreate() { super.onCreate() - socialLoginBinder.initializeNetworks(this, - listOf( - VkInitializer(), - FacebookInitializer(), - InstagramInitializer() - )) + val socialsInitializers = listOf( + VkInitializer(), + FacebookInitializer(), + GoogleInitializer() + ) + socialLoginBinder.initializeNetworks(this, socialsInitializers) } } diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt index 3833039..80a933d 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt @@ -120,13 +120,13 @@ class ImageBinderActivity : AppCompatActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) imagesBinder.onActivityResult(requestCode, resultCode, data, this) - permissionBinder.onActivityResult(requestCode, data, this) + permissionBinder.onActivityResult(requestCode, this) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) imagesBinder.onRequestPermissionsResult(requestCode, permissions, grantResults) - permissionBinder.onRequestPermissionResult(requestCode, grantResults) + permissionBinder.onRequestPermissionResult(requestCode) } private fun requestAndBindImage(request: ImageRequest) { diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt index 9325d92..95e59e7 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/PermissionExampleActivity.kt @@ -1,6 +1,6 @@ package com.livetyping.activitybinder -import android.Manifest +import android.Manifest.permission.* import android.content.Intent import android.os.Bundle import android.util.Log @@ -8,8 +8,8 @@ import androidx.appcompat.app.AppCompatActivity import com.livetyping.permission.PermissionBinder import kotlinx.android.synthetic.main.activity_permissions.* - class PermissionExampleActivity : AppCompatActivity() { + companion object { private const val TAG_SINGLE = "single" private const val TAG_MULTIPLY = "multiply" @@ -25,62 +25,102 @@ class PermissionExampleActivity : AppCompatActivity() { handleButtonMultiplyPermissions() } - private fun handleButtonMultiplyPermissions() { - multiply_passive.setOnClickListener { - permissionBinder.passivePermission(listOf(Manifest.permission.READ_CONTACTS, Manifest.permission.ACCESS_FINE_LOCATION)) { - for ((permission, isGranted) in it) { - handleOutputResults(isGranted, TAG_MULTIPLY, permission) - } - } + private fun handleButtonSinglePermissions() { + setOnSinglePassivePermissionClickListener() + setOnSingleActivePermissionClickListener() + setOnSingleGlobalPermissionClickListener() + } + + private fun setOnSinglePassivePermissionClickListener() { + single_passive.setOnClickListener { + permissionBinder.passivePermission(READ_EXTERNAL_STORAGE) { isGranted -> onPermissionResult(isGranted) } } + } + + private fun onPermissionResult(isGranted: Boolean) { + handleOutputResults(isGranted, TAG_SINGLE) + } + + private fun handleOutputResults( + isGranted: Boolean, + tag: String, + permission: String = "" + ) { + if (isGranted) granted(tag, permission) else denied(tag, permission) + } + private fun granted(tag: String, permission: String = "") { + Log.i(tag, "$permission was granted") + } + + private fun denied(tag: String, permission: String = "") { + Log.i(tag, "$permission was denied") + } + + private fun setOnSingleActivePermissionClickListener() { val rationaleText = getString(R.string.active_permission_rationale_text) - //cab be placed in active permission method as third parameter - val settingsButtonText = getString(R.string.active_permission_rationale_button_text) - multiply_active.setOnClickListener { - permissionBinder.activePermission(listOf(Manifest.permission.SEND_SMS, Manifest.permission.RECORD_AUDIO), rationaleText) { - for ((permission, isGranted) in it) { - handleOutputResults(isGranted, TAG_MULTIPLY, permission) - } - } + val dialogCustomThemeResId = R.style.SingleActivePermissionDialogTheme + val settingsButtonTitle = getString(R.string.active_permission_rationale_button_text) + single_active.setOnClickListener { + permissionBinder.activePermission( + CAMERA, + rationaleText, + dialogCustomThemeResId, + settingsButtonTitle + ) { isGranted -> onPermissionResult(isGranted) } } - multiply_global.setOnClickListener { - permissionBinder.globalPermission(listOf(Manifest.permission.BODY_SENSORS, Manifest.permission.READ_CALENDAR), - ShowGlobalExplanationActivity::class.java) { - for ((permission, isGranted) in it) { - handleOutputResults(isGranted, TAG_MULTIPLY, permission) - } - } + } + + private fun setOnSingleGlobalPermissionClickListener() { + single_global.setOnClickListener { + permissionBinder.globalPermission( + USE_SIP, + ShowGlobalExplanationActivity::class.java + ) { isGranted -> onPermissionResult(isGranted) } } } - private fun handleButtonSinglePermissions() { - single_passive.setOnClickListener { - permissionBinder.passivePermission(Manifest.permission.READ_EXTERNAL_STORAGE) { - handleOutputResults(it, TAG_SINGLE) - } + private fun handleButtonMultiplyPermissions() { + setOnMultiplePassivePermissionClickListener() + setOnMultipleActivePermissionClickListener() + setOnMultipleGlobalPermissionClickListener() + } + + private fun setOnMultiplePassivePermissionClickListener() { + val passivePermissions = listOf(READ_CONTACTS, ACCESS_FINE_LOCATION) + multiply_passive.setOnClickListener { + permissionBinder.passivePermissions(passivePermissions) { results -> onPermissionsResults(results) } } + } - val rationaleText = getString(R.string.active_permission_rationale_text) - //cab be placed in active permission method as third parameter - val settingsButtonText = getString(R.string.active_permission_rationale_button_text) - single_active.setOnClickListener { - permissionBinder.activePermission(Manifest.permission.CAMERA, rationaleText) { - handleOutputResults(it, TAG_SINGLE) - } + private fun onPermissionsResults(permissionsResults: Map) { + for ((permission, isGranted) in permissionsResults) { + handleOutputResults(isGranted, TAG_MULTIPLY, permission) } - single_global.setOnClickListener { - permissionBinder.globalPermission(Manifest.permission.USE_SIP, - ShowGlobalExplanationActivity::class.java) { - handleOutputResults(it, TAG_SINGLE) - } + } + + private fun setOnMultipleActivePermissionClickListener() { + val activePermissions = listOf(RECORD_AUDIO, CAMERA) + val rationaleText = getString(R.string.active_permission_rationale_text) + multiply_active.setOnClickListener { + permissionBinder.activePermissions( + activePermissions, + rationaleText + ) { results -> onPermissionsResults(results) } } } - private fun handleOutputResults(isGranted: Boolean, tag: String, permission: String = "") { - if (isGranted) granted(tag, permission) else denied(tag, permission) + private fun setOnMultipleGlobalPermissionClickListener() { + val globalPermissions = listOf(READ_PHONE_STATE, READ_CALENDAR) + multiply_global.setOnClickListener { + permissionBinder.globalPermissions( + globalPermissions, + ShowGlobalExplanationActivity::class.java + ) { results -> onPermissionsResults(results) } + } } + override fun onStart() { super.onStart() permissionBinder.attach(this) @@ -93,19 +133,11 @@ class PermissionExampleActivity : AppCompatActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - permissionBinder.onActivityResult(requestCode, data, this) + permissionBinder.onActivityResult(requestCode, this) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) - permissionBinder.onRequestPermissionResult(requestCode, grantResults) - } - - private fun granted(tag: String, permission: String = "") { - Log.i(tag, "$permission was granted") - } - - private fun denied(tag: String, permission: String = "") { - Log.i(tag, "$permission was denied") + permissionBinder.onRequestPermissionResult(requestCode) } } diff --git a/app/src/main/kotlin/com/livetyping/activitybinder/SocialActivity.kt b/app/src/main/kotlin/com/livetyping/activitybinder/SocialActivity.kt index 687e12b..8e7069e 100644 --- a/app/src/main/kotlin/com/livetyping/activitybinder/SocialActivity.kt +++ b/app/src/main/kotlin/com/livetyping/activitybinder/SocialActivity.kt @@ -5,67 +5,121 @@ import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.auth.GoogleAuthUtil +import com.livetyping.facebook.FacebookLoginResult import com.livetyping.facebook.FacebookNetwork import com.livetyping.google.GoogleAccountNetwork +import com.livetyping.google.GoogleAccountResult import com.livetyping.google.GoogleTokenNetwork -import com.livetyping.instagram.InstagramNetwork +import com.livetyping.google.GoogleTokenResult import com.livetyping.logincore.SocialLoginBinder +import com.livetyping.logincore.SocialLoginResult +import com.livetyping.logincore.SocialNetwork +import com.livetyping.vk.VkLoginResult import com.livetyping.vk.VkNetwork import kotlinx.android.synthetic.main.activity_social.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch +import kotlinx.coroutines.* +import kotlin.coroutines.CoroutineContext +class SocialActivity : AppCompatActivity(), CoroutineScope { -class SocialActivity : AppCompatActivity() { + companion object { + private const val SCOPES = "oauth2:profile email" + private const val GOOGLE_ANDROID_CLIENT_ID = + "962786784406-vrmqfde2mtng3vei55djkqehd5me9t42.apps.googleusercontent.com" + } private lateinit var socialLoginBinder: SocialLoginBinder - private companion object { - const val GOOGLE_ANDROID_CLIENT_ID = "962786784406-vrmqfde2mtng3vei55djkqehd5me9t42.apps.googleusercontent.com" - } + private val job = SupervisorJob() + override val coroutineContext: CoroutineContext = Dispatchers.Main + job override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_social) - socialLoginBinder = (application as BinderExampleApplication).socialLoginBinder // can be injected with dagger + // can be injected with dagger + socialLoginBinder = (application as BinderExampleApplication).socialLoginBinder + + initVkLogin() + initFacebookLogin() + initGoogleAccountLogin() + initGoogleTokenLogin() + } + private fun initVkLogin() { + val socialNetwork = VkNetwork() login_vk.setOnClickListener { - socialLoginBinder.loginWith(VkNetwork()) { - Toast.makeText(this, it.accessToken, Toast.LENGTH_SHORT).show() - } + loginWith(socialNetwork, ::onSuccessVkLogin) } + } + private fun loginWith( + socialNetwork: SocialNetwork, + onSuccess: (result: T) -> Unit + ) = socialLoginBinder.loginWith(socialNetwork, onSuccess, ::onFail) + + private fun initFacebookLogin() { + val socialNetwork = FacebookNetwork() login_fb.setOnClickListener { - socialLoginBinder.loginWith(FacebookNetwork()) { - Toast.makeText(this, it.accessToken, Toast.LENGTH_SHORT).show() - } - } - login_instagram.setOnClickListener { - socialLoginBinder.loginWith(InstagramNetwork()) { - Toast.makeText(this, it.accessToken, Toast.LENGTH_SHORT).show() - } + loginWith(socialNetwork, ::onSuccessFacebookLogin) } + } + private fun initGoogleAccountLogin() { + val socialNetwork = GoogleAccountNetwork(GOOGLE_ANDROID_CLIENT_ID) login_google.setOnClickListener { - socialLoginBinder.loginWith(GoogleAccountNetwork(GOOGLE_ANDROID_CLIENT_ID)) { - GlobalScope.launch(Dispatchers.IO) { - val scopes = "oauth2:profile email" - val token = GoogleAuthUtil.getToken(this@SocialActivity, it.account.account, scopes) - GlobalScope.launch(Dispatchers.Main) { - Toast.makeText(this@SocialActivity, token.toString(), Toast.LENGTH_SHORT).show() - } - } - } + loginWith(socialNetwork, ::onSuccessGoogleAccountLogin) } + } + + private fun initGoogleTokenLogin() { + val socialNetwork = GoogleTokenNetwork(GOOGLE_ANDROID_CLIENT_ID) login_google_token.setOnClickListener { - socialLoginBinder.loginWith(GoogleTokenNetwork(GOOGLE_ANDROID_CLIENT_ID)) { - Toast.makeText(this, it.accessToken, Toast.LENGTH_SHORT).show() + loginWith(socialNetwork, ::onSuccessGoogleTokenLogin) + } + } + + private fun onSuccessVkLogin(result: VkLoginResult) { + val token = result.accessToken + val email = result.email + showToast("$email\n$token") + } + + private fun showToast(message: String) { + Toast.makeText(this@SocialActivity, message, Toast.LENGTH_SHORT).show() + } + + private fun onSuccessFacebookLogin(result: FacebookLoginResult) { + val token = result.accessToken + val appId = result.applicationId + val userId = result.userId + showToast("$userId\n$appId\n$token") + } + + private fun onSuccessGoogleAccountLogin(result: GoogleAccountResult) { + launch { + val account = result.googleAccount.account + val token = withContext(Dispatchers.IO) { + GoogleAuthUtil.getToken(this@SocialActivity, account, SCOPES) } + showToast(token) } } + private fun onSuccessGoogleTokenLogin(result: GoogleTokenResult) { + val token = result.accessToken + showToast(token) + } + + private fun onFail(exception: Exception) { + showToast(exception.localizedMessage) + } + + override fun onDestroy() { + job.cancel() + super.onDestroy() + } + override fun onStart() { super.onStart() socialLoginBinder.attach(this) @@ -79,6 +133,5 @@ class SocialActivity : AppCompatActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { socialLoginBinder.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data) - } } diff --git a/app/src/main/res/layout/activity_permissions.xml b/app/src/main/res/layout/activity_permissions.xml index cf51f25..482d219 100644 --- a/app/src/main/res/layout/activity_permissions.xml +++ b/app/src/main/res/layout/activity_permissions.xml @@ -6,73 +6,70 @@ android:layout_height="match_parent" tools:context=".PermissionExampleActivity"> -