diff --git a/app/build.gradle b/app/build.gradle
index a81bfe3..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 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support.constraint:constraint-layout: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..01d1dbf 100644
--- a/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt
+++ b/app/src/main/kotlin/com/livetyping/activitybinder/ImageBinderActivity.kt
@@ -47,7 +47,10 @@ class ImageBinderActivity : AppCompatActivity() {
}
default_photo.setOnClickListener {
- permissionBinder.activePermission(Manifest.permission.CAMERA, getString(R.string.need_camera_permission)) {
+ permissionBinder.activePermission(
+ Manifest.permission.CAMERA,
+ getString(R.string.need_camera_permission)
+ ) {
if (it) {
val request = PhotoRequestDefaultPath()
requestAndBindImage(request)
@@ -56,17 +59,24 @@ class ImageBinderActivity : AppCompatActivity() {
}
cahche_path_photo.setOnClickListener {
- permissionBinder.activePermission(Manifest.permission.CAMERA, getString(R.string.need_camera_permission)) {
+ permissionBinder.activePermission(
+ Manifest.permission.CAMERA,
+ getString(R.string.need_camera_permission)
+ ) {
if (it) {
- val request = PhotoRequestCachePath("cache_files")
+ val request = PhotoRequestCachePath("cache_files", maxFileSize = 1000000)
requestAndBindImage(request)
}
}
}
external_cahce_path_photo.setOnClickListener {
- val permissions = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
- permissionBinder.activePermission(permissions, getString(R.string.need_camera_and_external_storage_permission)) {
+ val permissions =
+ listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ permissionBinder.activePermission(
+ permissions,
+ getString(R.string.need_camera_and_external_storage_permission)
+ ) {
if (it.all { it.value }) {
val request = PhotoRequestExternalCachePath("external_app_cache_path")
requestAndBindImage(request)
@@ -75,8 +85,12 @@ class ImageBinderActivity : AppCompatActivity() {
}
external_files_path_photo.setOnClickListener {
- val permissions = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
- permissionBinder.activePermission(permissions, getString(R.string.need_camera_and_external_storage_permission)) {
+ val permissions =
+ listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ permissionBinder.activePermission(
+ permissions,
+ getString(R.string.need_camera_and_external_storage_permission)
+ ) {
if (it.all { it.value }) {
val request = PhotoRequestExternalFilesPath("external_app_files_path")
requestAndBindImage(request)
@@ -85,8 +99,12 @@ class ImageBinderActivity : AppCompatActivity() {
}
external_path_photo.setOnClickListener {
- val permissions = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
- permissionBinder.activePermission(permissions, getString(R.string.need_camera_and_external_storage_permission)) {
+ val permissions =
+ listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ permissionBinder.activePermission(
+ permissions,
+ getString(R.string.need_camera_and_external_storage_permission)
+ ) {
if (it.all { it.value }) {
val request = PhotoRequestExternalPath("external_files")
requestAndBindImage(request)
@@ -95,8 +113,12 @@ class ImageBinderActivity : AppCompatActivity() {
}
files_path_photo.setOnClickListener {
- val permissions = listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
- permissionBinder.activePermission(permissions, getString(R.string.need_camera_and_external_storage_permission)) {
+ val permissions =
+ listOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ permissionBinder.activePermission(
+ permissions,
+ getString(R.string.need_camera_and_external_storage_permission)
+ ) {
if (it.all { it.value }) {
val request = PhotoRequestFilesPath("images")
requestAndBindImage(request)
@@ -120,13 +142,17 @@ 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) {
+ 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_new_binder.xml b/app/src/main/res/layout/activity_new_binder.xml
index 9fc212b..db011dd 100644
--- a/app/src/main/res/layout/activity_new_binder.xml
+++ b/app/src/main/res/layout/activity_new_binder.xml
@@ -18,9 +18,9 @@
@@ -45,7 +45,7 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="single_gallery"
- app:layout_constraintEnd_toStartOf="@+id/view2"
+ app:layout_constraintEnd_toEndOf="@+id/view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/multiple_gallery" />
@@ -57,7 +57,7 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="single_gallery_chooser"
- app:layout_constraintEnd_toStartOf="@+id/view2"
+ app:layout_constraintEnd_toEndOf="@+id/view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/single_gallery" />
@@ -69,7 +69,7 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="default_photo"
- app:layout_constraintEnd_toStartOf="@+id/view2"
+ app:layout_constraintEnd_toEndOf="@+id/view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/single_request_chooser" />
@@ -81,7 +81,7 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="cahche_path_photo"
- app:layout_constraintEnd_toStartOf="@+id/view2"
+ app:layout_constraintEnd_toEndOf="@+id/view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/default_photo" />
@@ -93,8 +93,8 @@
android:layout_marginEnd="8dp"
android:text="external_cahce_path_photo"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toEndOf="@+id/view2"
- app:layout_constraintTop_toTopOf="@+id/multiple_gallery" />
+ app:layout_constraintStart_toStartOf="@+id/view2"
+ app:layout_constraintTop_toBottomOf="@+id/cahche_path_photo" />
-
+
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">
-
+ android:layout_margin="16dp"
+ android:text="@string/single_passive_permission_button_title"
+ app:layout_constraintBottom_toTopOf="@id/single_active"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_chainStyle="packed" />
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_chainStyle="packed" />
+ android:layout_margin="16dp"
+ android:text="@string/single_active_permission_button_title"
+ app:layout_constraintBottom_toTopOf="@id/single_global"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/single_passive"
+ app:layout_constraintVertical_chainStyle="packed" />
+ android:layout_margin="16dp"
+ android:text="@string/multiply_active_permissions_button_title"
+ app:layout_constraintBottom_toTopOf="@id/multiply_global"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/multiply_passive"
+ app:layout_constraintVertical_chainStyle="packed" />
+ android:layout_margin="16dp"
+ android:text="@string/single_global_permission_button_title"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/single_active"
+ app:layout_constraintVertical_chainStyle="packed" />
+ android:layout_margin="16dp"
+ android:text="@string/multiply_global_permission_button_title"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/multiply_active"
+ app:layout_constraintVertical_chainStyle="packed" />
diff --git a/app/src/main/res/layout/activity_social.xml b/app/src/main/res/layout/activity_social.xml
index 000d553..dd3b85f 100644
--- a/app/src/main/res/layout/activity_social.xml
+++ b/app/src/main/res/layout/activity_social.xml
@@ -28,22 +28,9 @@
android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold"
- app:layout_constraintEnd_toStartOf="@+id/login_instagram"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/login_vk"
- app:layout_constraintTop_toTopOf="@+id/login_vk" />
-
-
Need permission to camera
Need permission for camera and external storage
+ single passive
+ multiply passive
+ single active
+ multiply active
+ single global
+ multiply global
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 5885930..e74f243 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -8,4 +8,9 @@
- @color/colorAccent
+
+
diff --git a/app/src/test/java/com/livetyping/activitybinder/ExampleUnitTest.kt b/app/src/test/java/com/livetyping/activitybinder/ExampleUnitTest.kt
deleted file mode 100644
index ecb5a25..0000000
--- a/app/src/test/java/com/livetyping/activitybinder/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.activitybinder
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
diff --git a/build.gradle b/build.gradle
index e9e93d4..f7216b6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,17 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.11'
+ ext.kotlin_version = '1.3.72'
+ ext.appcompat = '1.1.0'
+ ext.kotlin_coroutines_version = '1.2.2'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.3.0'
+ classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
- classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
+ classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta09'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -22,12 +24,6 @@ allprojects {
repositories {
google()
jcenter()
- maven { url 'https://jitpack.io' } //TODO не забыть добавить в описание,что эти репы добавляются в allprojects для инстраграмма
- }
- configurations.all {
- resolutionStrategy {
- force 'com.android.support:support-v4:28.0.0'
- }
}
}
diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/core/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/core/src/androidTest/java/com/livetyping/core/ExampleInstrumentedTest.java b/core/src/androidTest/java/com/livetyping/core/ExampleInstrumentedTest.java
deleted file mode 100644
index 95a7f53..0000000
--- a/core/src/androidTest/java/com/livetyping/core/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.core;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.core.test", appContext.getPackageName());
- }
-}
diff --git a/core/src/main/kotlin/com/livetyping/core/Binder.kt b/core/src/main/kotlin/com/livetyping/core/Binder.kt
index 6af1d7f..6207871 100644
--- a/core/src/main/kotlin/com/livetyping/core/Binder.kt
+++ b/core/src/main/kotlin/com/livetyping/core/Binder.kt
@@ -1,22 +1,22 @@
package com.livetyping.core
-import android.app.Activity
+import androidx.appcompat.app.AppCompatActivity
import java.lang.ref.WeakReference
import java.util.*
abstract class Binder {
- private var attachedObjRef: WeakReference? = null
- private val weakHashMap = WeakHashMap()
+ private var attachedObjRef: WeakReference? = null
+ private val weakHashMap = WeakHashMap()
- open fun attach(obj: Activity) {
+ open fun attach(obj: AppCompatActivity) {
val weakReference = WeakReference(obj)
weakHashMap[obj] = weakReference
attachedObjRef = weakReference
}
- open fun detach(obj: Activity) {
+ open fun detach(obj: AppCompatActivity) {
if (weakHashMap.remove(obj) == null) {
return
}
@@ -26,7 +26,7 @@ abstract class Binder {
} else null
}
- fun getAttachedObject(): Activity? {
+ fun getAttachedObject(): AppCompatActivity? {
return attachedObjRef?.get()
}
}
diff --git a/core/src/test/java/com/livetyping/core/ExampleUnitTest.java b/core/src/test/java/com/livetyping/core/ExampleUnitTest.java
deleted file mode 100644
index fa72cd8..0000000
--- a/core/src/test/java/com/livetyping/core/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.core;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index edd7cd9..b6a84ec 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,10 +6,19 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx1536m
-android.useAndroidX=true
-android.enableJetifier=true
+org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
+org.gradle.parallel=true
+org.gradle.configureondemand=true
+kapt.incremental.apt=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index bbd41b2..e7cc0e1 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Jan 17 10:56:01 OMST 2019
+#Thu Aug 22 20:12:56 GMT+06:00 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/images/build.gradle b/images/build.gradle
index 2c04d55..f648c89 100644
--- a/images/build.gradle
+++ b/images/build.gradle
@@ -3,6 +3,7 @@ apply from: "$rootDir//kotlin_android_library.gradle"
dependencies {
implementation project(":core")
implementation project(':permission')
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support:exifinterface:28.0.0'
+
+ implementation "com.google.android.material:material:$versions.material"
+ implementation "androidx.exifinterface:exifinterface:$versions.exifinterface"
}
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/ImagesBinder.kt b/images/src/main/kotlin/com/livetyping/images/ImagesBinder.kt
index 0b59c63..c8f3c54 100644
--- a/images/src/main/kotlin/com/livetyping/images/ImagesBinder.kt
+++ b/images/src/main/kotlin/com/livetyping/images/ImagesBinder.kt
@@ -3,6 +3,7 @@ package com.livetyping.images
import android.app.Activity
import android.content.Intent
import androidx.annotation.XmlRes
+import androidx.appcompat.app.AppCompatActivity
import com.livetyping.core.Binder
import com.livetyping.images.photo.PhotoRequest
@@ -44,7 +45,7 @@ class ImagesBinder(private val providerAuthority: String,
}
}
- override fun attach(obj: Activity) {
+ override fun attach(obj: AppCompatActivity) {
super.attach(obj)
waitedContextRequests.isNotEmpty().let { notEmpty ->
if (notEmpty) {
diff --git a/images/src/main/kotlin/com/livetyping/images/gallery/GalleryMultipleRequest.kt b/images/src/main/kotlin/com/livetyping/images/gallery/GalleryMultipleRequest.kt
index 27be250..dfb9157 100644
--- a/images/src/main/kotlin/com/livetyping/images/gallery/GalleryMultipleRequest.kt
+++ b/images/src/main/kotlin/com/livetyping/images/gallery/GalleryMultipleRequest.kt
@@ -5,8 +5,8 @@ import android.content.Intent
import java.io.File
-class GalleryMultipleRequest(chooserText: String? = null)
- : GalleryRequest>(chooserText) {
+class GalleryMultipleRequest(chooserText: String? = null) :
+ GalleryRequest>(chooserText) {
override val requestCode: Int
get() = 2233
@@ -27,12 +27,17 @@ class GalleryMultipleRequest(chooserText: String? = null)
if (itemCount > 0) {
val list = ArrayList(itemCount)
(0 until itemCount)
- .mapTo(list) { saveToProjectFiles(attachedObject, clipData.getItemAt(it).uri) }
+ .mapTo(list) {
+ saveToProjectFiles(
+ attachedObject,
+ clipData.getItemAt(it).uri
+ )
+ }
resultFunction(list)
}
} else {
val list = ArrayList(1)
- list.add(saveToProjectFiles(attachedObject, it?.data))
+ list.add(saveToProjectFiles(attachedObject, it.data!!))
resultFunction(list)
}
}
diff --git a/images/src/main/kotlin/com/livetyping/images/gallery/GalleryRequest.kt b/images/src/main/kotlin/com/livetyping/images/gallery/GalleryRequest.kt
index 5474668..d75523c 100644
--- a/images/src/main/kotlin/com/livetyping/images/gallery/GalleryRequest.kt
+++ b/images/src/main/kotlin/com/livetyping/images/gallery/GalleryRequest.kt
@@ -23,8 +23,8 @@ abstract class GalleryRequest(chooserText: String? = null)
val tempFile = File.createTempFile(uri.lastPathSegment.toString(), ".jpg", storageDir)
val out = FileOutputStream(tempFile)
val openInputStream = contentResolver.openInputStream(uri)
- val angle = getRotationAngle(openInputStream)
- openInputStream?.close()
+ val angle = getRotationAngle(openInputStream!!)
+ openInputStream.close()
val orientationMatrix = Matrix()
orientationMatrix.postRotate(angle.toFloat())
val picture = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, orientationMatrix, false)
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/kotlin/com/livetyping/images/photo/PhotoRequest.kt b/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequest.kt
index 983a2b6..789077c 100644
--- a/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequest.kt
+++ b/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequest.kt
@@ -3,20 +3,20 @@ package com.livetyping.images.photo
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
+import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.net.Uri
import android.provider.MediaStore
import androidx.core.content.FileProvider
import com.livetyping.images.ImageRequest
import com.livetyping.images.photo.filecreator.FileCreator
-import java.io.File
-import java.io.FileOutputStream
-import java.io.IOException
+import java.io.*
abstract class PhotoRequest(
- chooserText: String? = null,
- private val fileCreator: FileCreator
+ chooserText: String? = null,
+ private val fileCreator: FileCreator,
+ private val maxSize: Int? = null
) : ImageRequest(chooserText) {
internal lateinit var mCurrentPhotoPath: Uri
@@ -36,9 +36,11 @@ abstract class PhotoRequest(
}
imageFile?.let {
it.deleteOnExit()
- mCurrentPhotoPath = FileProvider.getUriForFile(attachedObject,
- providerAuthority,
- it)
+ mCurrentPhotoPath = FileProvider.getUriForFile(
+ attachedObject,
+ providerAuthority,
+ it
+ )
intent.putExtra(MediaStore.EXTRA_OUTPUT, mCurrentPhotoPath)
startIntentConsideringChooserText(intent, attachedObject)
}
@@ -51,22 +53,50 @@ abstract class PhotoRequest(
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, mCurrentPhotoPath)
val rotationInputStream = contentResolver.openInputStream(mCurrentPhotoPath)
//TODO check for null
- val angle = getRotationAngle(rotationInputStream)
- rotationInputStream?.close()
+ val angle = getRotationAngle(rotationInputStream!!)
+ rotationInputStream.close()
val imageFile = fileCreator.getImageFile(attachedObject, paths!!)
- if (angle == 0) {
- resultFunction.invoke(imageFile)
- } else {
- imageFile.delete()
- imageFile.createNewFile()
- val out = FileOutputStream(imageFile)
- val orientationMatrix = Matrix()
- orientationMatrix.postRotate(angle.toFloat())
- val picture = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, orientationMatrix, false)
- picture.compress(Bitmap.CompressFormat.JPEG, 100, out)
- picture.recycle()
- out.close()
- resultFunction.invoke(imageFile)
+ val quality = if (maxSize != null) calculateQuality(imageFile, maxSize) else 100
+ imageFile.delete()
+ imageFile.createNewFile()
+ val out = FileOutputStream(imageFile)
+ val orientationMatrix = Matrix()
+ orientationMatrix.postRotate(angle.toFloat())
+ val picture = Bitmap.createBitmap(
+ bitmap,
+ 0,
+ 0,
+ bitmap.width,
+ bitmap.height,
+ orientationMatrix,
+ false
+ )
+ picture.compress(Bitmap.CompressFormat.JPEG, quality, out)
+ picture.recycle()
+ out.close()
+ resultFunction.invoke(imageFile)
+ }
+
+ private fun calculateQuality(file: File, maxSize: Int): Int {
+ var compressQuality = 100
+ if (file.length() > maxSize) {
+ var streamLength = maxSize
+ val bmpStream = ByteArrayOutputStream()
+ while (streamLength >= maxSize) {
+ bmpStream.use {
+ it.flush()
+ it.reset()
+ }
+ compressQuality -= 8
+ val bitmap =
+ BitmapFactory.decodeFile(file.absolutePath, BitmapFactory.Options())
+ bitmap.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream)
+ streamLength = bmpStream.toByteArray().size
+ }
+ return compressQuality
}
+ return compressQuality
}
}
+
+
diff --git a/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequests.kt b/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequests.kt
index d93bf0f..494b73b 100644
--- a/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequests.kt
+++ b/images/src/main/kotlin/com/livetyping/images/photo/PhotoRequests.kt
@@ -7,55 +7,56 @@ import com.livetyping.images.photo.filecreator.*
* crete file in data/data/{applicationId}/files
*/
class PhotoRequestDefaultPath(
- chooser: String? = null
+ chooser: String? = null
) : PhotoRequest(chooser, DefaultFileCreator())
/**
* crete file in data/data/{applicationId}/cache/additionalPath
*/
class PhotoRequestCachePath(
- attrName: String,
- additionalPath: String? = null,
- fileName: String = "file_in_cache_dir",
- chooser: String? = null
-) : PhotoRequest(chooser, CachePathCreator(attrName, additionalPath, fileName))
+ attrName: String,
+ additionalPath: String? = null,
+ fileName: String = "file_in_cache_dir",
+ chooser: String? = null,
+ maxFileSize: Int? = null
+) : PhotoRequest(chooser, CachePathCreator(attrName, additionalPath, fileName), maxFileSize)
/**
* crete file in /storage/emulated/0/Android/data/{applicationId}/cache/additionalPath
*/
class PhotoRequestExternalCachePath(
- attrName: String,
- additionalPath: String? = null,
- fileName: String = "file_in_external_cache_dir",
- chooser: String? = null
+ attrName: String,
+ additionalPath: String? = null,
+ fileName: String = "file_in_external_cache_dir",
+ chooser: String? = null
) : PhotoRequest(chooser, ExternalCachePathCreator(attrName, additionalPath, fileName))
/**
* crete file in storage/emulated/0/Android/{applicationId}/files/additionalPath
*/
class PhotoRequestExternalFilesPath(
- attrName: String,
- additionalPath: String? = null,
- fileName: String = "file_in_external_files_dir",
- chooser: String? = null
+ attrName: String,
+ additionalPath: String? = null,
+ fileName: String = "file_in_external_files_dir",
+ chooser: String? = null
) : PhotoRequest(chooser, ExternalFilesPathCreator(attrName, additionalPath, fileName))
/**
* crete file in storage/emulated/0/files/additionalPath
*/
class PhotoRequestExternalPath(
- attrName: String,
- additionalPath: String? = null,
- fileName: String = "file_in_external_dir",
- chooser: String? = null
+ attrName: String,
+ additionalPath: String? = null,
+ fileName: String = "file_in_external_dir",
+ chooser: String? = null
) : PhotoRequest(chooser, ExternalPathCreator(attrName, additionalPath, fileName))
/**
* crete file in data/data/{applicationId}/files/additionalPath
*/
class PhotoRequestFilesPath(
- attrName: String,
- additionalPath: String? = null,
- fileName: String = "file_in_app_files_dir",
- chooser: String? = null
+ attrName: String,
+ additionalPath: String? = null,
+ fileName: String = "file_in_app_files_dir",
+ chooser: String? = null
) : PhotoRequest(chooser, FilesPathCreator(attrName, additionalPath, fileName))
diff --git a/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalCachePathCreator.kt b/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalCachePathCreator.kt
index 1dc5b42..1f27ddc 100644
--- a/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalCachePathCreator.kt
+++ b/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalCachePathCreator.kt
@@ -14,5 +14,5 @@ internal class ExternalCachePathCreator(
override val pathAttr: String
get() = "external-cache-path"
- override fun getRootPath(context: Context) = context.externalCacheDir.path
+ override fun getRootPath(context: Context) = context.externalCacheDir!!.path
}
diff --git a/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalFilesPathCreator.kt b/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalFilesPathCreator.kt
index 67d2c10..b28fe45 100644
--- a/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalFilesPathCreator.kt
+++ b/images/src/main/kotlin/com/livetyping/images/photo/filecreator/ExternalFilesPathCreator.kt
@@ -14,5 +14,5 @@ internal class ExternalFilesPathCreator(
override val pathAttr: String
get() = "external-files-path"
- override fun getRootPath(context: Context) = context.getExternalFilesDir(null).path
+ override fun getRootPath(context: Context) = context.getExternalFilesDir(null)!!.path
}
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 @@
-
-
-
-
-
-
diff --git a/kotlin_android_library.gradle b/kotlin_android_library.gradle
index e46691b..2ddbded 100644
--- a/kotlin_android_library.gradle
+++ b/kotlin_android_library.gradle
@@ -1,19 +1,22 @@
apply plugin: 'com.github.dcendents.android-maven'
group = 'com.github.LiveTyping.activity-binder'
+
+apply from: "$rootDir/versions.gradle"
+
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
-android {
- compileSdkVersion 28
+android {
+ compileSdkVersion 29
defaultConfig {
minSdkVersion 19
- targetSdkVersion 28
+ targetSdkVersion 29
versionCode 1
versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -28,10 +31,9 @@ android {
test.java.srcDirs += 'src/test/kotlin'
androidTest.java.srcDirs += 'src/androidTest/kotlin'
}
-
}
dependencies {
- compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-// implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation "androidx.appcompat:appcompat:$appcompat"
}
diff --git a/permission/build.gradle b/permission/build.gradle
index 939f409..ca8f4d2 100644
--- a/permission/build.gradle
+++ b/permission/build.gradle
@@ -2,5 +2,6 @@ apply from: "$rootDir//kotlin_android_library.gradle"
dependencies {
implementation project(":core")
- implementation 'com.android.support:appcompat-v7:27.1.1'
-}
\ No newline at end of file
+
+ implementation "com.google.android.material:material:$versions.material"
+}
diff --git a/permission/proguard-rules.pro b/permission/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/permission/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/permission/src/androidTest/java/com/livetyping/permission/ExampleInstrumentedTest.java b/permission/src/androidTest/java/com/livetyping/permission/ExampleInstrumentedTest.java
deleted file mode 100644
index a203dbe..0000000
--- a/permission/src/androidTest/java/com/livetyping/permission/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.permission;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.permission.test", appContext.getPackageName());
- }
-}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt
index 519d173..8ff2c7a 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/ActivePermissionRequest.kt
@@ -3,67 +3,79 @@ package com.livetyping.permission
import android.app.Activity
import android.content.Intent
import android.net.Uri
-import android.provider.Settings
+import android.provider.Settings.*
+import androidx.annotation.StyleRes
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
-
internal class ActivePermissionRequest(
- resultListener: (HashMap) -> Unit,
- private val settingsButtonText: String,
- private val rationaleText: String
+ private val rationaleText: String,
+ private val settingsButtonText: String,
+ resultListener: (Map) -> Unit
) : PermissionRequest(resultListener) {
private var rationaleShowed = false
- override fun onPermissionsNeedDenied(activity: Activity) {
- val permissionsWithoutRationale = getPermissionsWithoutRationale(activity).toList()
- if (permissionsWithoutRationale.isEmpty()) {
- showRequestPermissionDialog(activity)
+ override fun onPermissionsDenied(activity: Activity, @StyleRes themeResId: Int) {
+ if (hasDeniedByUserPermissions(activity)) {
+ showRequestPermissionDialog(activity, themeResId)
rationaleShowed = true
} else {
- val deniedPermissions = getDeniedPermissions(activity)
- ActivityCompat.requestPermissions(activity, deniedPermissions.toTypedArray(), requestCode)
+ val deniedPermissions = getDeniedPermissions(activity).toTypedArray()
+ ActivityCompat.requestPermissions(activity, deniedPermissions, requestCode)
}
}
- override fun afterRequest(activity: Activity) {
- if (areAllPermissionGranted(activity)) {
+ private fun showRequestPermissionDialog(activity: Activity, @StyleRes themeResId: Int) {
+ AlertDialog.Builder(activity, themeResId)
+ .setMessage(rationaleText)
+ .setPositiveButton(android.R.string.ok) { _, _ -> requestPermission(activity) }
+ .show()
+ }
+
+ override fun afterRequest(activity: Activity, @StyleRes themeResId: Int) {
+ val isAllPermissionsGrantedOrRationalShowed =
+ rationaleShowed || areAllPermissionsGranted(activity)
+ if (isAllPermissionsGrantedOrRationalShowed) {
invokeResult(activity)
} else {
- if (!rationaleShowed) {
- showOpenSettingsDialog(activity)
+ if (!rationaleShowed && getPermissionsWithoutRationale(activity).isNotEmpty()) {
+ showOpenSettingsDialog(activity, themeResId)
} else {
invokeResult(activity)
}
}
}
- override fun afterSettingsActivityResult(requestCode: Int, data: Intent?, activity: Activity) {
+ override fun afterSettingsActivityResult(
+ activity: Activity,
+ @StyleRes themeResId: Int
+ ) {
invokeResult(activity)
}
- private fun showRequestPermissionDialog(activity: Activity) {
- AlertDialog.Builder(activity)
- .setMessage(rationaleText)
- .setPositiveButton(android.R.string.ok) { _, _ ->
- ActivityCompat.requestPermissions(activity, permissions.toTypedArray(), requestCode)
- }
- .show()
+ private fun requestPermission(activity: Activity) {
+ ActivityCompat.requestPermissions(
+ activity,
+ permissions.toTypedArray(),
+ requestCode
+ )
}
- private fun showOpenSettingsDialog(activity: Activity) {
- AlertDialog.Builder(activity)
- .setMessage(rationaleText)
- .setPositiveButton(settingsButtonText) { _, _ -> openAppSettings(activity) }
- .setNegativeButton(android.R.string.cancel) { _, _ -> invokeResult(activity) }
- .setOnCancelListener { invokeResult(activity) }
- .show()
+ private fun showOpenSettingsDialog(activity: Activity, @StyleRes themeResId: Int) {
+ AlertDialog.Builder(activity, themeResId)
+ .setMessage(rationaleText)
+ .setPositiveButton(settingsButtonText) { _, _ -> openAppSettings(activity) }
+ .setNegativeButton(android.R.string.cancel) { _, _ -> invokeResult(activity) }
+ .setOnCancelListener { invokeResult(activity) }
+ .show()
}
private fun openAppSettings(activity: Activity) {
- val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
- Uri.parse("package:${activity.packageName}"))
+ val intent = Intent(
+ ACTION_APPLICATION_DETAILS_SETTINGS,
+ Uri.parse("package:${activity.packageName}")
+ )
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
activity.startActivityForResult(intent, requestCode)
}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/GlobalPermissionRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/GlobalPermissionRequest.kt
index 5b0330b..ab72af9 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/GlobalPermissionRequest.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/GlobalPermissionRequest.kt
@@ -2,12 +2,12 @@ package com.livetyping.permission
import android.app.Activity
import android.content.Intent
+import androidx.annotation.StyleRes
import androidx.core.app.ActivityCompat
-
internal class GlobalPermissionRequest(
- private val preSettingsClass: Class,
- resultListener: (HashMap) -> Unit
+ private val preSettingsClass: Class,
+ resultListener: (Map) -> Unit
) : PermissionRequest(resultListener) {
companion object {
@@ -15,26 +15,33 @@ internal class GlobalPermissionRequest(
internal const val PERMISSION_KEY = "PermissionRepository.PermissionKey"
}
-
- override fun onPermissionsNeedDenied(activity: Activity) {
- ActivityCompat.requestPermissions(activity, permissions.toList().toTypedArray(), requestCode)
+ override fun onPermissionsDenied(activity: Activity, @StyleRes themeResId: Int) {
+ val permissions = permissions.toTypedArray()
+ ActivityCompat.requestPermissions(activity, permissions, requestCode)
}
-
- override fun afterRequest(activity: Activity) {
- if (areAllPermissionGranted(activity)) {
+ override fun afterRequest(activity: Activity, @StyleRes themeResId: Int) {
+ if (areAllPermissionsGranted(activity)) {
invokeResult(activity)
} else {
- val intent = Intent(activity, preSettingsClass)
- with(intent) {
- putExtra(PERMISSION_KEY, permissions.toTypedArray())
- putExtra(PERMISSION_REQUEST_CODE_KEY, requestCode)
- }
- activity.startActivityForResult(intent, requestCode)
+ onNotAllPermissionsGranted(activity)
+ }
+ }
+
+ private fun onNotAllPermissionsGranted(activity: Activity) {
+ val intent = Intent(activity, preSettingsClass)
+ val permissions = permissions.toTypedArray()
+ with(intent) {
+ putExtra(PERMISSION_KEY, permissions)
+ putExtra(PERMISSION_REQUEST_CODE_KEY, requestCode)
}
+ activity.startActivityForResult(intent, requestCode)
}
- override fun afterSettingsActivityResult(requestCode: Int, data: Intent?, activity: Activity) {
- bunchNeedPermissions(activity)
+ override fun afterSettingsActivityResult(
+ activity: Activity,
+ @StyleRes themeResId: Int
+ ) {
+ bunchPermissions(activity, themeResId)
}
}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionRequest.kt
index b13b29f..6d6330c 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionRequest.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/PassivePermissionRequest.kt
@@ -2,27 +2,32 @@ package com.livetyping.permission
import android.app.Activity
import android.content.Intent
+import androidx.annotation.StyleRes
import androidx.core.app.ActivityCompat
-
internal class PassivePermissionRequest(
- resultListener: (permissionMap: HashMap) -> Unit
+ resultListener: (permissionMap: Map) -> Unit
) : PermissionRequest(resultListener) {
- override fun onPermissionsNeedDenied(activity: Activity) {
- val permissionsWithoutRationale = getPermissionsWithoutRationale(activity)
- if (permissionsWithoutRationale.isNotEmpty()) {
- ActivityCompat.requestPermissions(activity, permissionsWithoutRationale.toTypedArray(), requestCode)
+ override fun onPermissionsDenied(activity: Activity, @StyleRes themeResId: Int) {
+ val permissionsWithoutRationale = getFirstTimeRequestedPermissions(activity)
+ val hasFirstTimeRequestedPermissions = permissionsWithoutRationale.isNotEmpty()
+ if (hasFirstTimeRequestedPermissions) {
+ val permissions = permissionsWithoutRationale.toTypedArray()
+ ActivityCompat.requestPermissions(activity, permissions, requestCode)
} else {
invokeResult(activity)
}
}
- override fun afterRequest(activity: Activity) {
+ override fun afterRequest(activity: Activity, @StyleRes themeResId: Int) {
invokeResult(activity)
}
- override fun afterSettingsActivityResult(requestCode: Int, data: Intent?, activity: Activity) {
+ override fun afterSettingsActivityResult(
+ activity: Activity,
+ @StyleRes themeResId: Int
+ ) {
//nothing for this request
}
}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/PermissionBinder.kt b/permission/src/main/kotlin/com/livetyping/permission/PermissionBinder.kt
index 88e8672..a99ddc5 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/PermissionBinder.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/PermissionBinder.kt
@@ -2,90 +2,145 @@ package com.livetyping.permission
import android.app.Activity
import android.content.Intent
+import androidx.annotation.StyleRes
import com.livetyping.core.Binder
-
+import com.livetyping.permission.PermissionRequestCodes.MULTIPLE_PERMISSIONS_CODE
class PermissionBinder : Binder() {
+
private val requests: MutableMap = mutableMapOf()
- private val permissionCodes: PermissionRequestCodes = PermissionRequestCodes()
- private lateinit var resultListener: (HashMap) -> Unit
- fun passivePermission(permission: String, singleResultListener: (Boolean) -> Unit) {
- resultListener = {
- singleResultListener(it[permission]!!)
+ fun passivePermission(
+ permission: String,
+ singleResultListener: (Boolean) -> Unit
+ ) {
+ val permissionRequest = PassivePermissionRequest { permissionsResults ->
+ val isGranted = permissionsResults.getValue(permission)
+ singleResultListener(isGranted)
}
- needPermissions(listOf(permission), PassivePermissionRequest(resultListener))
+ needPermissions(listOf(permission), permissionRequest)
}
- fun passivePermission(permissions: Iterable, resultListener: (HashMap) -> Unit) {
- needPermissions(permissions, PassivePermissionRequest(resultListener))
+ @Deprecated(
+ "This is old version of the method. Use passivePermissions instead",
+ ReplaceWith("passivePermissions(permissions, resultListener)")
+ )
+ fun passivePermission(
+ permissions: Iterable,
+ resultListener: (Map) -> Unit
+ ) = passivePermissions(permissions, resultListener)
+
+ fun passivePermissions(
+ permissions: Iterable,
+ resultListener: (Map) -> Unit
+ ) {
+ val permissionRequest = PassivePermissionRequest(resultListener)
+ needPermissions(permissions, permissionRequest)
}
fun activePermission(
- permission: String,
- rationaleText: String,
- settingsButtonText: String = "settings",
- singleResultListener: (Boolean) -> Unit
+ permission: String,
+ rationaleText: String,
+ @StyleRes themeResId: Int = 0,
+ settingsButtonText: String = "settings",
+ singleResultListener: (Boolean) -> Unit
) {
- resultListener = {
- singleResultListener(it[permission]!!)
+ val permissionRequest = ActivePermissionRequest(rationaleText, settingsButtonText) { permissionsResults ->
+ val isGranted = permissionsResults.getValue(permission)
+ singleResultListener(isGranted)
}
- needPermissions(listOf(permission), ActivePermissionRequest(resultListener, settingsButtonText, rationaleText))
+ needPermissions(listOf(permission), permissionRequest, themeResId)
}
+ @Deprecated(
+ "This is old version of the method. Use activePermissions instead",
+ ReplaceWith("activePermissions(permissions, rationaleText, themeResId, settingsButtonText, resultListener)")
+ )
fun activePermission(
- permissions: Iterable,
- rationaleText: String,
- settingsButtonText: String = "settings",
- resultListener: (HashMap) -> Unit
+ permissions: Iterable,
+ rationaleText: String,
+ @StyleRes themeResId: Int = 0,
+ settingsButtonText: String = "settings",
+ resultListener: (Map) -> Unit
+ ) = activePermissions(permissions, rationaleText, themeResId, settingsButtonText, resultListener)
+
+ fun activePermissions(
+ permissions: Iterable,
+ rationaleText: String,
+ @StyleRes themeResId: Int = 0,
+ settingsButtonText: String = "settings",
+ resultListener: (Map) -> Unit
) {
- needPermissions(permissions, ActivePermissionRequest(resultListener, settingsButtonText, rationaleText))
+ val permissionRequest = ActivePermissionRequest(rationaleText, settingsButtonText, resultListener)
+ needPermissions(permissions, permissionRequest, themeResId)
}
fun globalPermission(
- permission: String,
- preSettingsClass: Class,
- singleResultListener: (Boolean) -> Unit
+ permission: String,
+ preSettingsClass: Class,
+ @StyleRes themeResId: Int = 0,
+ singleResultListener: (Boolean) -> Unit
) {
- resultListener = {
- singleResultListener(it[permission]!!)
+ val permissionRequest = GlobalPermissionRequest(preSettingsClass) { permissionsResults ->
+ val isGranted = permissionsResults.getValue(permission)
+ singleResultListener(isGranted)
}
- needPermissions(listOf(permission), GlobalPermissionRequest(preSettingsClass, resultListener))
+ needPermissions(listOf(permission), permissionRequest, themeResId)
}
+ @Deprecated(
+ "This is old version of the method. Use globalPermissions instead",
+ ReplaceWith("globalPermissions(permissions, preSettingsClass, themeResId, resultListener)")
+ )
fun globalPermission(
- permissions: Iterable,
- preSettingsClass: Class,
- resultListener: (HashMap) -> Unit
+ permissions: Iterable,
+ preSettingsClass: Class,
+ @StyleRes themeResId: Int = 0,
+ resultListener: (Map) -> Unit
+ ) = globalPermissions(permissions, preSettingsClass, themeResId, resultListener)
+
+ fun globalPermissions(
+ permissions: Iterable,
+ preSettingsClass: Class,
+ @StyleRes themeResId: Int = 0,
+ resultListener: (Map) -> Unit
) {
- needPermissions(permissions, GlobalPermissionRequest(preSettingsClass, resultListener))
+ val permissionRequest = GlobalPermissionRequest(preSettingsClass, resultListener)
+ needPermissions(permissions, permissionRequest, themeResId)
}
- fun onRequestPermissionResult(code: Int, grantResults: IntArray) {
+ fun onRequestPermissionResult(code: Int, @StyleRes themeResId: Int = 0) {
val requester = requests[code]
- getAttachedObject()
- ?: throw IllegalStateException("PermissionRepository. Haven't attached activity")
- requester?.afterRequest(getAttachedObject()!!)
+ val attachedObject = getAttachedObject()
+ ?: throw IllegalStateException("PermissionRepository. Haven't attached activity")
+ requester?.afterRequest(attachedObject, themeResId)
+ requests.remove(code)
}
- fun onActivityResult(requestCode: Int, data: Intent?, activity: Activity) {
- requests[requestCode]?.afterSettingsActivityResult(requestCode, data, activity)
+ fun onActivityResult(
+ requestCode: Int,
+ activity: Activity,
+ @StyleRes themeResId: Int = 0
+ ) {
+ requests[requestCode]?.afterSettingsActivityResult(activity, themeResId)
}
-
- private fun needPermissions(permissions: Iterable, request: PermissionRequest) {
- getAttachedObject()
- ?: throw IllegalStateException("PermissionRepository. Haven't attached activity")
+ private fun needPermissions(
+ permissions: Iterable,
+ request: PermissionRequest,
+ @StyleRes themeResId: Int = 0
+ ) {
+ val attachedObject = getAttachedObject()
+ ?: throw IllegalStateException("PermissionRepository. Haven't attached activity")
val requestCode = calculateRequestCode(permissions)
requests[requestCode] = request
- request.needPermissions(requestCode, permissions, getAttachedObject()!!)
+ request.needPermissions(requestCode, permissions, attachedObject, themeResId)
}
- private fun calculateRequestCode(permissions: Iterable): Int {
- return if (permissions.toList().size == 1) {
- permissionCodes.getCode(permissions.iterator().next())
+ private fun calculateRequestCode(permissions: Iterable) =
+ if (permissions.count() == 1) {
+ PermissionRequestCodes.getCode(permissions.first())
} else {
- PermissionRequestCodes.MULTIPLE_PERMISSIONS_CODE
+ MULTIPLE_PERMISSIONS_CODE
}
- }
}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/PermissionRequest.kt b/permission/src/main/kotlin/com/livetyping/permission/PermissionRequest.kt
index 39dca39..ceb3cc1 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/PermissionRequest.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/PermissionRequest.kt
@@ -2,83 +2,95 @@ package com.livetyping.permission
import android.app.Activity
import android.content.Intent
+import androidx.annotation.StyleRes
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.PERMISSION_DENIED
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
-internal abstract class PermissionRequest(protected val resultListener: (HashMap) -> Unit) {
- protected val permissionHashMap = HashMap()
- protected var requestCode = 0
+internal abstract class PermissionRequest(
+ private val resultListener: (Map) -> Unit
+) {
+
+ private val permissionMap = mutableMapOf()
protected lateinit var permissions: MutableList
+ protected var requestCode = 0
- internal fun needPermissions(requestCode: Int, permissions: Iterable, activity: Activity) {
+ internal fun needPermissions(
+ requestCode: Int,
+ permissions: Iterable,
+ activity: Activity,
+ @StyleRes themeResId: Int
+ ) {
this.requestCode = requestCode
this.permissions = permissions.toMutableList()
initPermissionHashMap()
- bunchNeedPermissions(activity)
+ bunchPermissions(activity, themeResId)
}
private fun initPermissionHashMap() {
- permissionHashMap.clear()
- permissions.forEach {
- permissionHashMap[it] = false
+ permissionMap.clear()
+ permissions.forEach { permission ->
+ permissionMap[permission] = false
}
}
- fun bunchNeedPermissions(activity: Activity) {
- if (areAllPermissionGranted(activity)) {
+ fun bunchPermissions(activity: Activity, @StyleRes themeResId: Int) {
+ if (areAllPermissionsGranted(activity)) {
syncPermissionsGrantedResult(activity)
- resultListener.invoke(permissionHashMap)
+ resultListener.invoke(permissionMap)
} else {
- onPermissionsNeedDenied(activity)
+ onPermissionsDenied(activity, themeResId)
}
}
- internal abstract fun onPermissionsNeedDenied(activity: Activity)
-
- internal abstract fun afterSettingsActivityResult(requestCode: Int, data: Intent?, activity: Activity)
-
- internal abstract fun afterRequest(activity: Activity)
-
@PermissionChecker.PermissionResult
- private fun isPermissionGranted(permission: String, activity: Activity): Boolean {
- return ContextCompat.checkSelfPermission(activity, permission) == PERMISSION_GRANTED
+ protected fun areAllPermissionsGranted(activity: Activity) = permissions.all { permission ->
+ isPermissionGranted(activity, permission)
}
@PermissionChecker.PermissionResult
- protected fun isPermissionDenied(permission: String, activity: Activity): Boolean {
- return ContextCompat.checkSelfPermission(activity, permission) == PERMISSION_DENIED
- }
+ private fun isPermissionGranted(activity: Activity, permission: String) =
+ ContextCompat.checkSelfPermission(activity, permission) == PERMISSION_GRANTED
- protected fun getPermissionsWithoutRationale(activity: Activity): List {
- return permissions.filter {
- !ActivityCompat.shouldShowRequestPermissionRationale(activity, it)
+ private fun syncPermissionsGrantedResult(activity: Activity) {
+ for ((permission) in permissionMap) {
+ permissionMap[permission] = isPermissionGranted(activity, permission)
}
}
- protected fun getDeniedPermissions(activity: Activity): List {
- return permissions.filter { isPermissionDenied(it, activity) }
- }
+ internal abstract fun onPermissionsDenied(activity: Activity, @StyleRes themeResId: Int)
+ internal abstract fun afterSettingsActivityResult(
+ activity: Activity,
+ @StyleRes themeResId: Int
+ )
- protected fun syncPermissionsGrantedResult(activity: Activity) {
- for ((permission) in permissionHashMap) {
- permissionHashMap[permission] = isPermissionGranted(permission, activity)
- }
+ internal abstract fun afterRequest(activity: Activity, @StyleRes themeResId: Int)
+
+ protected fun hasDeniedByUserPermissions(activity: Activity) = permissions.any {
+ ActivityCompat.shouldShowRequestPermissionRationale(activity, it)
+ }
+
+ protected fun getFirstTimeRequestedPermissions(activity: Activity) = permissions.filter {
+ ActivityCompat.shouldShowRequestPermissionRationale(activity, it).not()
}
+ protected fun getDeniedPermissions(activity: Activity) = permissions.filter { isPermissionDenied(it, activity) }
+
+ @PermissionChecker.PermissionResult
+ protected fun isPermissionDenied(permission: String, activity: Activity) =
+ ContextCompat.checkSelfPermission(activity, permission) == PERMISSION_DENIED
+
protected fun invokeResult(activity: Activity) {
syncPermissionsGrantedResult(activity)
- resultListener.invoke(permissionHashMap)
+ resultListener.invoke(permissionMap)
}
- @PermissionChecker.PermissionResult
- protected fun areAllPermissionGranted(activity: Activity): Boolean {
- permissions.forEach {
- if (!isPermissionGranted(it, activity)) return@areAllPermissionGranted false
+ protected fun getPermissionsWithoutRationale(activity: Activity): List {
+ return permissions.filter {
+ !ActivityCompat.shouldShowRequestPermissionRationale(activity, it)
}
- return true
}
}
diff --git a/permission/src/main/kotlin/com/livetyping/permission/PermissionRequestCodes.kt b/permission/src/main/kotlin/com/livetyping/permission/PermissionRequestCodes.kt
index 29bd7af..3dd3628 100644
--- a/permission/src/main/kotlin/com/livetyping/permission/PermissionRequestCodes.kt
+++ b/permission/src/main/kotlin/com/livetyping/permission/PermissionRequestCodes.kt
@@ -1,44 +1,43 @@
package com.livetyping.permission
-import android.Manifest
+import android.Manifest.permission.*
+import android.annotation.SuppressLint
+import android.annotation.TargetApi
+import android.os.Build.VERSION_CODES.KITKAT_WATCH
+internal object PermissionRequestCodes {
-internal class PermissionRequestCodes {
- companion object {
- const val MULTIPLE_PERMISSIONS_CODE = 116
- }
+ const val MULTIPLE_PERMISSIONS_CODE = 100
- fun getCode(permission: String): Int {
- val permissionCode = when (permission) {
- Manifest.permission.CAMERA -> 101
- Manifest.permission.READ_CALENDAR -> 102
- Manifest.permission.WRITE_CALENDAR -> 103
- Manifest.permission.READ_CONTACTS -> 104
- Manifest.permission.WRITE_CONTACTS -> 105
- Manifest.permission.GET_ACCOUNTS -> 106
- Manifest.permission.ACCESS_FINE_LOCATION -> 107
- Manifest.permission.ACCESS_COARSE_LOCATION -> 108
- Manifest.permission.RECORD_AUDIO -> 109
- Manifest.permission.READ_PHONE_STATE -> 110
- Manifest.permission.CALL_PHONE -> 111
- Manifest.permission.READ_CALL_LOG -> 112
- Manifest.permission.WRITE_CALL_LOG -> 113
- Manifest.permission.ADD_VOICEMAIL -> 114
- Manifest.permission.USE_SIP -> 115
- Manifest.permission.PROCESS_OUTGOING_CALLS -> 116
- Manifest.permission.BODY_SENSORS -> 117
- Manifest.permission.SEND_SMS -> 118
- Manifest.permission.RECEIVE_SMS -> 119
- Manifest.permission.READ_SMS -> 120
- Manifest.permission.RECEIVE_WAP_PUSH -> 121
- Manifest.permission.RECEIVE_MMS -> 112
- Manifest.permission.READ_EXTERNAL_STORAGE -> 113
- Manifest.permission.WRITE_EXTERNAL_STORAGE -> 115
- else -> {
- throw IllegalArgumentException("PermissionRequestCodes, undefined permission")
- }
+ @SuppressLint("InlinedApi")
+ fun getCode(permission: String) =
+ when (permission) {
+ READ_CALENDAR -> 101
+ WRITE_CALENDAR -> 102
+ READ_CALL_LOG -> 103
+ WRITE_CALL_LOG -> 104
+ PROCESS_OUTGOING_CALLS -> 105
+ CAMERA -> 106
+ READ_CONTACTS -> 107
+ WRITE_CONTACTS -> 108
+ GET_ACCOUNTS -> 109
+ ACCESS_FINE_LOCATION -> 110
+ ACCESS_COARSE_LOCATION -> 111
+ RECORD_AUDIO -> 112
+ READ_PHONE_STATE -> 113
+ READ_PHONE_NUMBERS -> 114
+ CALL_PHONE -> 115
+ ANSWER_PHONE_CALLS -> 116
+ ADD_VOICEMAIL -> 117
+ USE_SIP -> 118
+ BODY_SENSORS -> 119
+ SEND_SMS -> 120
+ RECEIVE_SMS -> 121
+ READ_SMS -> 122
+ RECEIVE_WAP_PUSH -> 123
+ RECEIVE_MMS -> 124
+ READ_EXTERNAL_STORAGE -> 125
+ WRITE_EXTERNAL_STORAGE -> 126
+ else -> throw IllegalArgumentException("PermissionRequestCodes, undefined permission")
}
- if (permissionCode == MULTIPLE_PERMISSIONS_CODE) throw IllegalStateException("Please, choose another request code!")
- return permissionCode
- }
}
diff --git a/settings.gradle b/settings.gradle
index e44f669..1170d88 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -4,7 +4,6 @@ include ':app', ':core'
include ':social:logincore',
':social:vk',
':social:facebook',
- ':social:instagram',
':social:google'
include ':permission'
diff --git a/social/facebook/build.gradle b/social/facebook/build.gradle
index ac117dd..b832dc8 100644
--- a/social/facebook/build.gradle
+++ b/social/facebook/build.gradle
@@ -1,14 +1,6 @@
apply from: "$rootDir//kotlin_android_library.gradle"
apply from: "$rootDir//social/social_login_item.gradle"
-android {
- buildscript {
- repositories {
- jcenter()
- }
- }
-}
-
dependencies {
- implementation("com.facebook.android:facebook-login:4.36.0")
-}
\ No newline at end of file
+ implementation "com.facebook.android:facebook-login:$versions.facebook"
+}
diff --git a/social/facebook/proguard-rules.pro b/social/facebook/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/social/facebook/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/social/facebook/src/androidTest/java/com/livetyping/facebook/ExampleInstrumentedTest.java b/social/facebook/src/androidTest/java/com/livetyping/facebook/ExampleInstrumentedTest.java
deleted file mode 100644
index c26789a..0000000
--- a/social/facebook/src/androidTest/java/com/livetyping/facebook/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.facebook;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.facebook.test", appContext.getPackageName());
- }
-}
diff --git a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookInitializer.kt b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookInitializer.kt
index df110ec..be6ffbd 100644
--- a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookInitializer.kt
+++ b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookInitializer.kt
@@ -3,11 +3,9 @@ package com.livetyping.facebook
import android.app.Application
import com.livetyping.logincore.SocialInitializer
-
class FacebookInitializer : SocialInitializer {
override fun init(app: Application) {
- // pass
+ // No initialization need
}
-
-}
\ No newline at end of file
+}
diff --git a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginError.kt b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginError.kt
deleted file mode 100644
index 447f38c..0000000
--- a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginError.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.livetyping.facebook
-
-import com.facebook.FacebookException
-import com.livetyping.logincore.SocialLoginError
-
-
-class FacebookLoginError(private val exception: FacebookException) : SocialLoginError {
-
- override fun error() = exception.message.orEmpty()
-}
\ No newline at end of file
diff --git a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginResult.kt b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginResult.kt
index dce5957..a97f717 100644
--- a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginResult.kt
+++ b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookLoginResult.kt
@@ -3,12 +3,12 @@ package com.livetyping.facebook
import com.facebook.login.LoginResult
import com.livetyping.logincore.SocialLoginResult
-
-class FacebookLoginResult(val accessToken: String, applicationId: String, userId: String)
- : SocialLoginResult {
-
-}
-
-internal fun LoginResult.toFacebookLoginResult(): FacebookLoginResult {
- return FacebookLoginResult(accessToken.token, accessToken.applicationId, accessToken.userId)
+data class FacebookLoginResult(
+ val accessToken: String,
+ val applicationId: String,
+ val userId: String
+) : SocialLoginResult
+
+internal fun LoginResult.toFacebookLoginResult() = with(accessToken) {
+ FacebookLoginResult(token, applicationId, userId)
}
diff --git a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookNetwork.kt b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookNetwork.kt
index b295a83..23b78de 100644
--- a/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookNetwork.kt
+++ b/social/facebook/src/main/kotlin/com/livetyping/facebook/FacebookNetwork.kt
@@ -7,37 +7,54 @@ import com.facebook.FacebookCallback
import com.facebook.FacebookException
import com.facebook.login.LoginManager
import com.facebook.login.LoginResult
-import com.livetyping.logincore.SocialLoginError
import com.livetyping.logincore.SocialNetwork
-
class FacebookNetwork : SocialNetwork {
+ companion object {
+ private const val PUBLIC_PROFILE_PERMISSION = "public_profile"
+ private const val EMAIL_PERMISSION = "email"
+ }
+
private val callbackManager = CallbackManager.Factory.create()
override fun login(activity: Activity) {
- LoginManager.getInstance().logInWithReadPermissions(activity,
- arrayListOf("public_profile", "email"))
+ LoginManager.getInstance().logInWithReadPermissions(
+ activity,
+ listOf(PUBLIC_PROFILE_PERMISSION, EMAIL_PERMISSION)
+ )
}
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?,
- successBlock: (result: FacebookLoginResult) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)?) {
- LoginManager.getInstance()
- .registerCallback(callbackManager, object : FacebookCallback {
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ onSuccess: (result: FacebookLoginResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) {
+ LoginManager.getInstance().registerCallback(
+ callbackManager,
+ facebookCallback(onSuccess, onFail)
+ )
+ callbackManager.onActivityResult(requestCode, resultCode, data)
+ }
- override fun onSuccess(result: LoginResult) {
- successBlock.invoke(result.toFacebookLoginResult())
- }
+ private fun facebookCallback(
+ onSuccess: (result: FacebookLoginResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) = object : FacebookCallback {
- override fun onCancel() {
- LoginManager.getInstance().unregisterCallback(callbackManager)
- }
+ override fun onSuccess(loginResult: LoginResult) {
+ val result = loginResult.toFacebookLoginResult()
+ onSuccess.invoke(result)
+ }
- override fun onError(error: FacebookException) {
- errorBlock?.invoke(FacebookLoginError(error))
- }
- })
- callbackManager.onActivityResult(requestCode, resultCode, data)
+ override fun onCancel() {
+ LoginManager.getInstance().unregisterCallback(callbackManager)
+ }
+
+ override fun onError(exception: FacebookException) {
+ onFail.invoke(exception)
+ }
}
}
diff --git a/social/facebook/src/test/java/com/livetyping/facebook/ExampleUnitTest.java b/social/facebook/src/test/java/com/livetyping/facebook/ExampleUnitTest.java
deleted file mode 100644
index 400bd4b..0000000
--- a/social/facebook/src/test/java/com/livetyping/facebook/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.facebook;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/social/google/build.gradle b/social/google/build.gradle
index 9bbe2e9..dc073bd 100644
--- a/social/google/build.gradle
+++ b/social/google/build.gradle
@@ -1,14 +1,6 @@
apply from: "$rootDir//kotlin_android_library.gradle"
apply from: "$rootDir//social/social_login_item.gradle"
-android {
- buildscript {
- repositories {
- jcenter()
- }
- }
-}
-
dependencies {
- implementation "com.google.android.gms:play-services-auth:16.0.1"
-}
\ No newline at end of file
+ implementation "com.google.android.gms:play-services-auth:$versions.auth"
+}
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleAccountNetwork.kt b/social/google/src/main/java/com/livetyping/google/GoogleAccountNetwork.kt
index 545e03b..b719baf 100644
--- a/social/google/src/main/java/com/livetyping/google/GoogleAccountNetwork.kt
+++ b/social/google/src/main/java/com/livetyping/google/GoogleAccountNetwork.kt
@@ -1,50 +1,48 @@
package com.livetyping.google
import android.app.Activity
-import android.content.Context
import android.content.Intent
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
-import com.livetyping.logincore.SocialLoginError
import com.livetyping.logincore.SocialNetwork
-class GoogleAccountNetwork(androidClientId: String) : SocialNetwork {
-
+class GoogleAccountNetwork(androidClientId: String) : SocialNetwork {
companion object {
private const val GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE = 231
}
- private var context: Context? = null
-
private val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
- .requestServerAuthCode(androidClientId)
- .requestId()
- .requestIdToken(androidClientId)
- .requestEmail()
- .build()
+ .requestServerAuthCode(androidClientId)
+ .requestId()
+ .requestIdToken(androidClientId)
+ .requestEmail()
+ .build()
override fun login(activity: Activity) {
- context = activity
val signInClient = GoogleSignIn.getClient(activity, signInOptions)
- activity.startActivityForResult(signInClient.signInIntent, GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE)
+ activity.startActivityForResult(
+ signInClient.signInIntent,
+ GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE
+ )
}
- override fun onActivityResult(requestCode: Int,
- resultCode: Int, data: Intent?,
- successBlock: (result: GoogleLoginResult) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)?) {
- if (requestCode == GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE) {
- val task = GoogleSignIn.getSignedInAccountFromIntent(data)
- try {
- val account = task.getResult(ApiException::class.java)
- successBlock(account!!.toSocialResult())
- } catch (e: ApiException) {
- errorBlock?.invoke(GoogleLoginError(e))
- } finally {
- context = null
- }
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ onSuccess: (result: GoogleAccountResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) {
+ if (requestCode != GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE) return
+ val task = GoogleSignIn.getSignedInAccountFromIntent(data)
+ try {
+ val account = task.getResult(ApiException::class.java)!!
+ val result = GoogleAccountResult(account)
+ onSuccess(result)
+ } catch (exception: Exception) {
+ onFail.invoke(exception)
}
}
}
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleAccountResult.kt b/social/google/src/main/java/com/livetyping/google/GoogleAccountResult.kt
index 88c9d5c..8f5ceb0 100644
--- a/social/google/src/main/java/com/livetyping/google/GoogleAccountResult.kt
+++ b/social/google/src/main/java/com/livetyping/google/GoogleAccountResult.kt
@@ -3,9 +3,6 @@ package com.livetyping.google
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.livetyping.logincore.SocialLoginResult
-
-class GoogleLoginResult(val account: GoogleSignInAccount) : SocialLoginResult
-
-internal fun GoogleSignInAccount.toSocialResult(): GoogleLoginResult {
- return GoogleLoginResult(this)
-}
+data class GoogleAccountResult(
+ val googleAccount: GoogleSignInAccount
+) : SocialLoginResult
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleInitializer.kt b/social/google/src/main/java/com/livetyping/google/GoogleInitializer.kt
index 7832359..31fed7e 100644
--- a/social/google/src/main/java/com/livetyping/google/GoogleInitializer.kt
+++ b/social/google/src/main/java/com/livetyping/google/GoogleInitializer.kt
@@ -6,6 +6,6 @@ import com.livetyping.logincore.SocialInitializer
class GoogleInitializer : SocialInitializer {
override fun init(app: Application) {
- // pass (google does not require static initialization)
+ // No initialization need
}
-}
\ No newline at end of file
+}
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleLoginError.kt b/social/google/src/main/java/com/livetyping/google/GoogleLoginError.kt
deleted file mode 100644
index f311593..0000000
--- a/social/google/src/main/java/com/livetyping/google/GoogleLoginError.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.livetyping.google
-
-import com.google.android.gms.common.api.ApiException
-import com.livetyping.logincore.SocialLoginError
-
-class GoogleLoginError(private val apiException: ApiException) : SocialLoginError {
-
- override fun error() = apiException.message.orEmpty()
-}
\ No newline at end of file
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleTokenLoader.kt b/social/google/src/main/java/com/livetyping/google/GoogleTokenLoader.kt
deleted file mode 100644
index 747760d..0000000
--- a/social/google/src/main/java/com/livetyping/google/GoogleTokenLoader.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.livetyping.google
-
-import android.content.Context
-import android.os.AsyncTask
-import androidx.loader.content.AsyncTaskLoader
-import com.google.android.gms.auth.GoogleAuthUtil
-import com.google.android.gms.auth.api.signin.GoogleSignInAccount
-
-
-internal class GoogleTokenLoader(context: Context,
- private val googleSignInAccount: GoogleSignInAccount) : AsyncTaskLoader(context) {
-
- override fun loadInBackground(): String? {
- val scopes = "oauth2:profile email"
- return GoogleAuthUtil.getToken(context, googleSignInAccount.account, scopes)
- }
-}
-
-internal class GoogleTokenAsyncTask() : AsyncTask() {
-
- override fun doInBackground(vararg p0: GoogleSignInAccount?): String {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
-
-}
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleTokenNetwork.kt b/social/google/src/main/java/com/livetyping/google/GoogleTokenNetwork.kt
index 10759dd..0e9b9a8 100644
--- a/social/google/src/main/java/com/livetyping/google/GoogleTokenNetwork.kt
+++ b/social/google/src/main/java/com/livetyping/google/GoogleTokenNetwork.kt
@@ -10,60 +10,79 @@ import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
-import com.livetyping.logincore.SocialLoginError
+import com.google.android.gms.tasks.Task
import com.livetyping.logincore.SocialNetwork
+import com.google.android.gms.auth.api.signin.GoogleSignInOptions.DEFAULT_SIGN_IN as DEFAULT_SIGN_IN
-
-class GoogleTokenNetwork(androidClientId: String) :
- SocialNetwork {
+class GoogleTokenNetwork(androidClientId: String) : SocialNetwork {
companion object {
private const val GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE = 231
+ private const val HANDLER_THREAD_NAME = "GoogleTokenNetworkHandlerThread"
+ private const val SCOPES = "oauth2:profile email"
}
- private var handlerThread = HandlerThread("GoogleTokenNetwork")
- private lateinit var handler: Handler
- private var context: Context? = null
- private lateinit var account: GoogleSignInAccount
+ private var handler: Handler? = null
+ private var handlerThread: HandlerThread? = null
+
+ private lateinit var googleAccount: GoogleSignInAccount
private lateinit var successBlock: (result: GoogleTokenResult) -> Unit
- private val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
- .requestServerAuthCode(androidClientId)
- .requestId()
- .requestIdToken(androidClientId)
- .requestEmail()
- .build()
+ private var context: Context? = null
+
+ private val signInOptions = GoogleSignInOptions.Builder(DEFAULT_SIGN_IN)
+ .requestServerAuthCode(androidClientId)
+ .requestId()
+ .requestIdToken(androidClientId)
+ .requestEmail()
+ .build()
override fun login(activity: Activity) {
- context = activity
val signInClient = GoogleSignIn.getClient(activity, signInOptions)
- activity.startActivityForResult(signInClient.signInIntent, GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE)
+ context = activity.applicationContext
+ activity.startActivityForResult(
+ signInClient.signInIntent,
+ GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE
+ )
}
- override fun onActivityResult(requestCode: Int,
- resultCode: Int, data: Intent?,
- successBlock: (result: GoogleTokenResult) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)?) {
- this.successBlock = successBlock
- if (requestCode == GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE) {
- val task = GoogleSignIn.getSignedInAccountFromIntent(data)
- try {
- account = task.getResult(ApiException::class.java)!!
- handlerThread.start()
- handler = Handler(handlerThread.looper)
- handler.post(loadToken)
- } catch (e: ApiException) {
- errorBlock?.invoke(GoogleLoginError(e))
- context = null
- }
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ onSuccess: (result: GoogleTokenResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) {
+ if (requestCode != GOOGLE_SIGN_IN_ACTIVITY_REQUEST_CODE) return
+ this.successBlock = onSuccess
+ val task = GoogleSignIn.getSignedInAccountFromIntent(data)
+ try {
+ getToken(task)
+ } catch (exception: Exception) {
+ onFail.invoke(exception)
+ handler = null
+ handlerThread = null
+ context = null
}
}
+ private fun getToken(task: Task) {
+ checkNotNull(context) { "Context is null!" }
+ googleAccount = task.getResult(ApiException::class.java)!!
+ handlerThread = HandlerThread(HANDLER_THREAD_NAME)
+ handlerThread!!.start()
+ handler = Handler(handlerThread!!.looper)
+ handler!!.post(loadToken)
+ }
+
private val loadToken: () -> Unit = {
- val scopes = "oauth2:profile email"
- val token = GoogleAuthUtil.getToken(context, account.account, scopes)
- successBlock.invoke(GoogleTokenResult(token))
- handler.removeMessages(0)
+ val account = googleAccount.account
+ val token = GoogleAuthUtil.getToken(context, account, SCOPES)
+ val result = GoogleTokenResult(token)
+ successBlock.invoke(result)
+ handler!!.removeMessages(0)
+ handler = null
+ handlerThread = null
context = null
}
}
diff --git a/social/google/src/main/java/com/livetyping/google/GoogleTokenResult.kt b/social/google/src/main/java/com/livetyping/google/GoogleTokenResult.kt
index 44a6a3c..f9c8675 100644
--- a/social/google/src/main/java/com/livetyping/google/GoogleTokenResult.kt
+++ b/social/google/src/main/java/com/livetyping/google/GoogleTokenResult.kt
@@ -2,6 +2,6 @@ package com.livetyping.google
import com.livetyping.logincore.SocialLoginResult
-
-class GoogleTokenResult(val accessToken: String) : SocialLoginResult {
-}
+data class GoogleTokenResult(
+ val accessToken: String
+) : SocialLoginResult
diff --git a/social/instagram/.gitignore b/social/instagram/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/social/instagram/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/social/instagram/build.gradle b/social/instagram/build.gradle
deleted file mode 100644
index bb9d1f3..0000000
--- a/social/instagram/build.gradle
+++ /dev/null
@@ -1,10 +0,0 @@
-apply from: "$rootDir//kotlin_android_library.gradle"
-apply from: "$rootDir//social/social_login_item.gradle"
-
-repositories {
- maven { url 'https://jitpack.io' }
-}
-
-dependencies {
- implementation("com.github.nikolajakshic:instagramauth:1.1.1")
-}
diff --git a/social/instagram/proguard-rules.pro b/social/instagram/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/social/instagram/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/social/instagram/src/androidTest/java/com/livetyping/instagram/ExampleInstrumentedTest.java b/social/instagram/src/androidTest/java/com/livetyping/instagram/ExampleInstrumentedTest.java
deleted file mode 100644
index ad6c043..0000000
--- a/social/instagram/src/androidTest/java/com/livetyping/instagram/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.instagram;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.instagram.test", appContext.getPackageName());
- }
-}
diff --git a/social/instagram/src/main/AndroidManifest.xml b/social/instagram/src/main/AndroidManifest.xml
deleted file mode 100644
index 18a229d..0000000
--- a/social/instagram/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramInitializer.kt b/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramInitializer.kt
deleted file mode 100644
index 3f06922..0000000
--- a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramInitializer.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.livetyping.instagram
-
-import android.app.Application
-import com.livetyping.logincore.SocialInitializer
-import com.nikola.jakshic.instagramauth.InstagramAuth
-
-
-class InstagramInitializer : SocialInitializer {
-
- override fun init(app: Application) {
- InstagramAuth.initialize(app)
- }
-}
\ No newline at end of file
diff --git a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginError.kt b/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginError.kt
deleted file mode 100644
index 7164462..0000000
--- a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginError.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.livetyping.instagram
-
-import com.livetyping.logincore.SocialLoginError
-
-
-class InstagramLoginError(private val exception: Exception) : SocialLoginError {
-
- override fun error() = exception.toString()
-
-}
\ No newline at end of file
diff --git a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginResult.kt b/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginResult.kt
deleted file mode 100644
index e5bfc14..0000000
--- a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramLoginResult.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.livetyping.instagram
-
-import com.livetyping.logincore.SocialLoginResult
-
-
-class InstagramLoginResult(val accessToken: String) : SocialLoginResult {
-}
diff --git a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramNetwork.kt b/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramNetwork.kt
deleted file mode 100644
index 80f8643..0000000
--- a/social/instagram/src/main/kotlin/com/livetyping/instagram/InstagramNetwork.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.livetyping.instagram
-
-import android.app.Activity
-import android.content.Intent
-import com.livetyping.logincore.SocialLoginError
-import com.livetyping.logincore.SocialNetwork
-import com.nikola.jakshic.instagramauth.AuthManager
-import com.nikola.jakshic.instagramauth.InstagramAuthException
-
-
-class InstagramNetwork : SocialNetwork {
-
- private var successBlock: ((token: InstagramLoginResult) -> Unit)? = null
- private var errorBlock: ((error: SocialLoginError) -> Unit)? = null
-
- override fun login(activity: Activity) {
- AuthManager.getInstance().login(activity, object : AuthManager.LoginCallback {
- override fun onError(e: InstagramAuthException) {
- errorBlock?.apply { invoke(InstagramLoginError(e)) }
- }
-
- override fun onSuccess() {
- successBlock?.apply {
- invoke(InstagramLoginResult(AuthManager.getInstance().getToken().orEmpty()))
- }
- }
-
- })
- }
-
- override fun onActivityResult(requestCode: Int,
- resultCode: Int,
- data: Intent?,
- successBlock: (token: InstagramLoginResult) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)?) {
- this.successBlock = successBlock
- this.errorBlock = errorBlock
- AuthManager.getInstance().onActivityResult(requestCode, resultCode, data);
- }
-
-}
diff --git a/social/instagram/src/main/res/values/strings.xml b/social/instagram/src/main/res/values/strings.xml
deleted file mode 100644
index ff2005d..0000000
--- a/social/instagram/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- instagram
-
diff --git a/social/instagram/src/test/java/com/livetyping/instagram/ExampleUnitTest.java b/social/instagram/src/test/java/com/livetyping/instagram/ExampleUnitTest.java
deleted file mode 100644
index f094b01..0000000
--- a/social/instagram/src/test/java/com/livetyping/instagram/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.instagram;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/social/logincore/build.gradle b/social/logincore/build.gradle
index 4288908..2305ad2 100644
--- a/social/logincore/build.gradle
+++ b/social/logincore/build.gradle
@@ -2,5 +2,4 @@ apply from: "$rootDir//kotlin_android_library.gradle"
dependencies {
implementation project(":core")
-
}
diff --git a/social/logincore/proguard-rules.pro b/social/logincore/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/social/logincore/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/social/logincore/src/androidTest/java/com/livetyping/logincore/ExampleInstrumentedTest.java b/social/logincore/src/androidTest/java/com/livetyping/logincore/ExampleInstrumentedTest.java
deleted file mode 100644
index 9364491..0000000
--- a/social/logincore/src/androidTest/java/com/livetyping/logincore/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.logincore;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.logincore.test", appContext.getPackageName());
- }
-}
diff --git a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialInitializer.kt b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialInitializer.kt
index a63c227..fd76d27 100644
--- a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialInitializer.kt
+++ b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialInitializer.kt
@@ -2,8 +2,7 @@ package com.livetyping.logincore
import android.app.Application
-
interface SocialInitializer {
fun init(app: Application)
-}
\ No newline at end of file
+}
diff --git a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginBinder.kt b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginBinder.kt
index 8dd20fd..a81d2b3 100644
--- a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginBinder.kt
+++ b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginBinder.kt
@@ -4,31 +4,39 @@ import android.app.Application
import android.content.Intent
import com.livetyping.core.Binder
-
class SocialLoginBinder : Binder() {
- private var route: SocialNetwork? = null
- private var tokenBlock: ((result: SocialLoginResult) -> Unit)? = null
- private var errorBlock: ((error: SocialLoginError) -> Unit)? = null
+ private var socialNetwork: SocialNetwork? = null
+ private var onSuccess: ((result: SocialLoginResult) -> Unit)? = null
+ private var onFail: ((error: Exception) -> Unit)? = null
fun initializeNetworks(app: Application, initializers: Collection) {
initializers.forEach { it.init(app) }
}
- fun loginWith(route: SocialNetwork,
- errorBlock: ((error: SocialLoginError) -> Unit)? = null,
- successBlock: (result: T) -> Unit) {
+ @Suppress("UNCHECKED_CAST")
+ fun loginWith(
+ socialNetwork: SocialNetwork,
+ onSuccess: (result: T) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) {
getAttachedObject()?.let {
- this.route = route
- this.tokenBlock = successBlock as ((SocialLoginResult) -> Unit)?
- this.errorBlock = errorBlock
- route.login(it)
+ this.socialNetwork = socialNetwork
+ this.onSuccess = onSuccess as (SocialLoginResult) -> Unit
+ this.onFail = onFail
+ socialNetwork.login(it)
}
}
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- route?.onActivityResult(requestCode, resultCode, data,
- { tokenBlock?.invoke(it) }, // success
- { errorBlock?.invoke(it) }) // error
+ onSuccess ?: return
+ onFail ?: return
+ socialNetwork?.onActivityResult(
+ requestCode,
+ resultCode,
+ data,
+ onSuccess!!,
+ onFail!!
+ )
}
}
diff --git a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginError.kt b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginError.kt
deleted file mode 100644
index d3033d3..0000000
--- a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginError.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.livetyping.logincore
-
-
-interface SocialLoginError {
- fun error(): String
-}
\ No newline at end of file
diff --git a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginResult.kt b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginResult.kt
index a82cf98..bb18f7a 100644
--- a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginResult.kt
+++ b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialLoginResult.kt
@@ -1,5 +1,3 @@
package com.livetyping.logincore
-
-interface SocialLoginResult {
-}
+interface SocialLoginResult
diff --git a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialNetwork.kt b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialNetwork.kt
index eee94a1..329af2f 100644
--- a/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialNetwork.kt
+++ b/social/logincore/src/main/kotlin/com/livetyping/logincore/SocialNetwork.kt
@@ -3,12 +3,15 @@ package com.livetyping.logincore
import android.app.Activity
import android.content.Intent
-
interface SocialNetwork {
fun login(activity: Activity)
- fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?,
- successBlock: (result: T) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)? = null)
+ fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ onSuccess: (result: T) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ )
}
diff --git a/social/logincore/src/test/java/com/livetyping/logincore/ExampleUnitTest.java b/social/logincore/src/test/java/com/livetyping/logincore/ExampleUnitTest.java
deleted file mode 100644
index da0a093..0000000
--- a/social/logincore/src/test/java/com/livetyping/logincore/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.logincore;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/social/social_login_item.gradle b/social/social_login_item.gradle
index c66c961..a787040 100644
--- a/social/social_login_item.gradle
+++ b/social/social_login_item.gradle
@@ -1,10 +1,8 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
+
dependencies {
implementation project(":social:logincore")
implementation project(":core")
- compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
-
-
diff --git a/social/vk/build.gradle b/social/vk/build.gradle
index 12c89de..e78b060 100644
--- a/social/vk/build.gradle
+++ b/social/vk/build.gradle
@@ -1,14 +1,6 @@
apply from: "$rootDir//kotlin_android_library.gradle"
apply from: "$rootDir//social/social_login_item.gradle"
-android {
- buildscript {
- repositories {
- mavenCentral()
- }
- }
-}
dependencies {
- implementation 'com.vk:androidsdk:1.6.9'
+ implementation "com.vk:androidsdk:$versions.vk"
}
-
diff --git a/social/vk/proguard-rules.pro b/social/vk/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/social/vk/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/social/vk/src/androidTest/java/com/livetyping/vk/ExampleInstrumentedTest.java b/social/vk/src/androidTest/java/com/livetyping/vk/ExampleInstrumentedTest.java
deleted file mode 100644
index c136cb5..0000000
--- a/social/vk/src/androidTest/java/com/livetyping/vk/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.livetyping.vk;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.livetyping.vk.test", appContext.getPackageName());
- }
-}
diff --git a/social/vk/src/main/kotlin/com/livetyping/vk/VkInitializer.kt b/social/vk/src/main/kotlin/com/livetyping/vk/VkInitializer.kt
index c71caf7..4ae82a6 100644
--- a/social/vk/src/main/kotlin/com/livetyping/vk/VkInitializer.kt
+++ b/social/vk/src/main/kotlin/com/livetyping/vk/VkInitializer.kt
@@ -2,12 +2,11 @@ package com.livetyping.vk
import android.app.Application
import com.livetyping.logincore.SocialInitializer
-import com.vk.sdk.VKSdk
-
+import com.vk.api.sdk.VK
class VkInitializer : SocialInitializer {
override fun init(app: Application) {
- VKSdk.initialize(app)
+ VK.initialize(app)
}
-}
\ No newline at end of file
+}
diff --git a/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginError.kt b/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginError.kt
deleted file mode 100644
index a1923cf..0000000
--- a/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginError.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.livetyping.vk
-
-import com.livetyping.logincore.SocialLoginError
-import com.vk.sdk.api.VKError
-
-
-class VkLoginError(private val error: VKError) : SocialLoginError {
-
- override fun error() = error.errorMessage
-}
\ No newline at end of file
diff --git a/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginResult.kt b/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginResult.kt
index 4837514..c4cb32b 100644
--- a/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginResult.kt
+++ b/social/vk/src/main/kotlin/com/livetyping/vk/VkLoginResult.kt
@@ -1,11 +1,11 @@
package com.livetyping.vk
import com.livetyping.logincore.SocialLoginResult
-import com.vk.sdk.VKAccessToken
+import com.vk.api.sdk.auth.VKAccessToken
+data class VkLoginResult(
+ val accessToken: String,
+ val email: String?
+) : SocialLoginResult
-class VkLoginResult(val accessToken: String, val email: String) : SocialLoginResult {
-
-}
-
-internal fun VKAccessToken.toVkLoginResult(): VkLoginResult = VkLoginResult(accessToken, email)
+internal fun VKAccessToken.toVkLoginResult() = VkLoginResult(accessToken, email)
diff --git a/social/vk/src/main/kotlin/com/livetyping/vk/VkNetwork.kt b/social/vk/src/main/kotlin/com/livetyping/vk/VkNetwork.kt
index fd7c3b8..e00770a 100644
--- a/social/vk/src/main/kotlin/com/livetyping/vk/VkNetwork.kt
+++ b/social/vk/src/main/kotlin/com/livetyping/vk/VkNetwork.kt
@@ -2,34 +2,52 @@ package com.livetyping.vk
import android.app.Activity
import android.content.Intent
-import com.livetyping.logincore.SocialLoginError
import com.livetyping.logincore.SocialNetwork
-import com.vk.sdk.VKAccessToken
-import com.vk.sdk.VKCallback
-import com.vk.sdk.VKScope
-import com.vk.sdk.VKSdk
-import com.vk.sdk.api.VKError
-
+import com.vk.api.sdk.VK
+import com.vk.api.sdk.auth.*
+import com.vk.api.sdk.auth.VKAuthCallback.Companion.AUTH_CANCELED
+import com.vk.api.sdk.auth.VKScope.*
class VkNetwork : SocialNetwork {
+ companion object {
+ private const val VK_AUTH_CANCELLED = "VK SDK: authorization canceled"
+ private const val VK_UNKNOWN_ERROR = "VK SDK: Unknown error"
+ }
+
override fun login(activity: Activity) {
- VKSdk.login(activity, VKScope.EMAIL)
+ VK.login(activity, listOf(EMAIL))
+ }
+
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?,
+ onSuccess: (result: VkLoginResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) {
+ VK.onActivityResult(
+ requestCode,
+ resultCode,
+ data,
+ vkAuthCallback(onSuccess, onFail)
+ )
}
- override fun onActivityResult(requestCode: Int,
- resultCode: Int, data: Intent?,
- successBlock: (result: VkLoginResult) -> Unit,
- errorBlock: ((error: SocialLoginError) -> Unit)?) {
- if (!VKSdk.onActivityResult(requestCode, resultCode, data, object : VKCallback {
- override fun onResult(vkAccessToken: VKAccessToken) {
- successBlock.invoke(vkAccessToken.toVkLoginResult())
- }
-
- override fun onError(error: VKError) {
- errorBlock?.invoke(VkLoginError(error))
- }
- })) {
+ private fun vkAuthCallback(
+ onSuccess: (result: VkLoginResult) -> Unit,
+ onFail: (exception: Exception) -> Unit
+ ) = object : VKAuthCallback {
+
+ override fun onLogin(token: VKAccessToken) {
+ val result = token.toVkLoginResult()
+ onSuccess.invoke(result)
+ }
+
+ override fun onLoginFailed(errorCode: Int) {
+ val errorMessage = if (errorCode == AUTH_CANCELED) VK_AUTH_CANCELLED else VK_UNKNOWN_ERROR
+ val exception = Exception(errorMessage)
+ onFail.invoke(exception)
}
}
}
diff --git a/social/vk/src/test/java/com/livetyping/vk/ExampleUnitTest.java b/social/vk/src/test/java/com/livetyping/vk/ExampleUnitTest.java
deleted file mode 100644
index 2c38525..0000000
--- a/social/vk/src/test/java/com/livetyping/vk/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.livetyping.vk;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/versions.gradle b/versions.gradle
new file mode 100644
index 0000000..8fcd08b
--- /dev/null
+++ b/versions.gradle
@@ -0,0 +1,16 @@
+ext.versions = [
+
+ // AndroidX
+ material : '1.2.0-beta01',
+ constraint_layout: '2.0.0-beta7',
+ exifinterface : '1.1.0-beta01',
+
+ // Google services
+ auth : '17.0.0',
+
+ // Facebook
+ facebook : '5.4.0',
+
+ // VK
+ vk : '2.1.1'
+]