Merge pull request #2 from gedoor/master

merge
pull/416/head
口口吕 4 years ago committed by GitHub
commit 14de73270d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      app/build.gradle
  2. 4
      app/src/main/assets/updateLog.md
  3. 3
      app/src/main/java/io/legado/app/App.kt
  4. 6
      app/src/main/java/io/legado/app/constant/EventBus.kt
  5. 4
      app/src/main/java/io/legado/app/help/ActivityHelp.kt
  6. 3
      app/src/main/java/io/legado/app/help/AppConfig.kt
  7. 2
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  8. 12
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  9. 106
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  10. 13
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  11. 77
      app/src/main/java/io/legado/app/utils/LanguageUtils.kt
  12. 1
      app/src/main/res/layout/activity_book_source.xml
  13. 5
      app/src/main/res/layout/view_select_action_bar.xml
  14. 17
      app/src/main/res/menu/read_book.xml
  15. 8
      app/src/main/res/values/arrays.xml
  16. 3
      app/src/main/res/values/pref_key_value.xml
  17. 1
      app/src/main/res/values/strings.xml
  18. 7
      app/src/main/res/xml/pref_config_other.xml
  19. 2
      build.gradle

@ -121,15 +121,15 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
//fireBase
implementation 'com.google.firebase:firebase-analytics-ktx:17.5.0'
implementation 'com.google.firebase:firebase-crashlytics-ktx:17.2.1'
implementation 'com.google.firebase:firebase-analytics-ktx:17.6.0'
implementation 'com.google.firebase:firebase-crashlytics-ktx:17.2.2'
//androidX
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.media:media:1.2.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.google.android.material:material:1.2.1'

@ -3,6 +3,10 @@
* 关注合作公众号 **[小说拾遗]()** 获取好看的小说。
- 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2020/10/11**
* 优化书源校验
* 语言切换bug修复 by [h11128](https://github.com/h11128)
**2020/10/07**
* 更新时预下载10章
* 支持更多分组

@ -7,6 +7,7 @@ import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.provider.Settings
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDexApplication
@ -46,7 +47,7 @@ class App : MultiDexApplication() {
INSTANCE = this
androidId = Settings.System.getString(contentResolver, Settings.Secure.ANDROID_ID)
CrashHandler(this)
LanguageUtils.setConfigurationOld(this)
LanguageUtils.setConfiguration(this)
db = AppDatabase.createDatabase(INSTANCE)
packageManager.getPackageInfo(packageName, 0)?.let {
versionCode = it.versionCode

@ -20,8 +20,6 @@ object EventBus {
const val WEB_SERVICE = "webService"
const val UP_DOWNLOAD = "upDownload"
const val SAVE_CONTENT = "saveContent"
const val CHECK_INIT = "checkInit"
const val CHECK_UP_PROGRESS = "checkProgress"
const val CHECK_UP_PROGRESS_STRING = "checkProgressTxt"
const val CHECK_DONE = "checkDone"
const val CHECK_SOURCE = "checkSource"
const val CHECK_SOURCE_DONE = "checkSourceDone"
}

@ -3,6 +3,7 @@ package io.legado.app.help
import android.app.Activity
import android.app.Application
import android.os.Bundle
import io.legado.app.utils.LanguageUtils
import java.lang.ref.WeakReference
import java.util.*
@ -110,5 +111,8 @@ object ActivityHelp : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
add(activity)
if (!LanguageUtils.isSameWithSetting(activity)){
LanguageUtils.setConfiguration(activity)
}
}
}

@ -58,9 +58,6 @@ object AppConfig {
App.INSTANCE.putPrefBoolean(PreferKey.showRss, value)
}
val backgroundVerification: Boolean
get() = App.INSTANCE.getPrefBoolean(R.string.pk_background_verification, true)
val autoRefreshBook: Boolean
get() = App.INSTANCE.getPrefBoolean(R.string.pk_auto_refresh)

@ -225,7 +225,7 @@ object Restore {
if (!BuildConfig.DEBUG) {
LauncherIconHelp.changeIcon(App.INSTANCE.getPrefString(PreferKey.launcherIcon))
}
LanguageUtils.setConfigurationOld(App.INSTANCE)
LanguageUtils.setConfiguration(App.INSTANCE)
App.INSTANCE.applyDayNight()
postEvent(EventBus.SHOW_RSS, "")
postEvent(EventBus.RECREATE, "")

@ -9,7 +9,6 @@ import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus
import io.legado.app.constant.IntentAction
import io.legado.app.help.AppConfig
import io.legado.app.help.AppConfig.backgroundVerification
import io.legado.app.help.IntentHelp
import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.service.help.CheckSource
@ -45,10 +44,8 @@ class CheckSourceService : BaseService() {
override fun onCreate() {
super.onCreate()
if (backgroundVerification) {
updateNotification(0, getString(R.string.start))
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when (intent?.action) {
@ -64,7 +61,7 @@ class CheckSourceService : BaseService() {
super.onDestroy()
tasks.clear()
searchPool.close()
postEvent(EventBus.CHECK_DONE, 0)
postEvent(EventBus.CHECK_SOURCE_DONE, 0)
}
private fun check(ids: List<String>) {
@ -78,7 +75,6 @@ class CheckSourceService : BaseService() {
allIds.addAll(ids)
processIndex = 0
threadCount = min(allIds.size, threadCount)
postEvent(EventBus.CHECK_INIT, allIds.size)
updateNotification(0, getString(R.string.progress_show, "", 0, allIds.size))
for (i in 0 until threadCount) {
check()
@ -113,15 +109,10 @@ class CheckSourceService : BaseService() {
synchronized(this) {
check()
checkedIds.add(sourceUrl)
if (backgroundVerification) {
updateNotification(
checkedIds.size,
getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size)
)
} else {
postEvent(EventBus.CHECK_UP_PROGRESS, checkedIds.size)
postEvent(EventBus.CHECK_UP_PROGRESS_STRING, getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size))
}
if (processIndex >= allIds.size + threadCount - 1) {
stopSelf()
}
@ -134,6 +125,7 @@ class CheckSourceService : BaseService() {
private fun updateNotification(state: Int, msg: String) {
notificationBuilder.setContentText(msg)
notificationBuilder.setProgress(allIds.size, state, false)
postEvent(EventBus.CHECK_SOURCE, msg)
startForeground(112202, notificationBuilder.build())
}

@ -5,8 +5,9 @@ import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.*
import android.view.Menu
import android.view.MenuItem
import android.view.SubMenu
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.core.content.FileProvider
@ -15,15 +16,14 @@ import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App
import io.legado.app.BuildConfig
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppPattern
import io.legado.app.constant.EventBus
import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppConfig
import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH
@ -42,9 +42,7 @@ import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_book_source.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_progressbar_view.*
import kotlinx.android.synthetic.main.view_search.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
@ -68,6 +66,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
private var groupMenu: SubMenu? = null
private var sort = 0
private var sortAscending = 0
private var snackBar: Snackbar? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
initRecyclerView()
@ -100,11 +99,20 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
val intent = Intent(Intent.ACTION_SEND)
val file = FileUtils.createFileWithReplace("$filesDir/shareBookSource.json")
file.writeText(json)
val fileUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileProvider", file)
val fileUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID + ".fileProvider",
file
)
intent.type = "text/*"
intent.putExtra(Intent.EXTRA_STREAM, fileUri)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
startActivity(Intent.createChooser(intent, getString(R.string.share_selected_source)))
startActivity(
Intent.createChooser(
intent,
getString(R.string.share_selected_source)
)
)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
}
@ -196,19 +204,19 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
}
}
bookSourceLiveDate?.observe(this, { data ->
val sourceList = when (sortAscending % 2){
val sourceList = when (sortAscending % 2) {
0 -> when (sort) {
1 -> data.sortedBy { it.weight }
2 -> data.sortedBy { it.bookSourceName }
3 -> data.sortedBy { it.bookSourceUrl }
4 -> data.sortedByDescending { it.lastUpdateTime}
4 -> data.sortedByDescending { it.lastUpdateTime }
else -> data
}
else -> when (sort) {
1 -> data.sortedByDescending { it.weight }
2 -> data.sortedByDescending { it.bookSourceName }
3 -> data.sortedByDescending { it.bookSourceUrl }
4 -> data.sortedBy { it.lastUpdateTime}
4 -> data.sortedBy { it.lastUpdateTime }
else -> data.reversed()
}
}
@ -218,11 +226,11 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
upCountView()
})
}
private fun sortCheck (sortId: Int){
if (sort == sortId){
sortAscending +=1
}
else{
private fun sortCheck(sortId: Int) {
if (sort == sortId) {
sortAscending += 1
} else {
sortAscending = 0
sort = sortId
}
@ -299,13 +307,6 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
CheckSource.keyword = it
}
}
if (!AppConfig.backgroundVerification) {
val bundle = Bundle()
bundle.putInt("maxProgress", adapter.getSelection().size)
CheckSourceDialog().apply {
arguments = bundle
}.show(supportFragmentManager, "CheckDialog")
}
CheckSource.start(this@BookSourceActivity, adapter.getSelection())
}
noButton { }
@ -396,8 +397,21 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
}
override fun observeLiveBus() {
observeEvent<Int>(EventBus.CHECK_DONE) {
groups.map { group->
observeEvent<String>(EventBus.CHECK_SOURCE) { msg ->
snackBar?.setText(msg) ?: let {
snackBar = Snackbar
.make(root_view, msg, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.cancel) {
CheckSource.stop(this)
}.apply { show() }
}
}
observeEvent<Int>(EventBus.CHECK_SOURCE_DONE) {
snackBar?.let {
it.dismiss()
snackBar = null
}
groups.map { group ->
if (group.contains("失效")) {
search_view.setQuery("失效", true)
toast("发现有失效书源,已为您自动筛选!")
@ -501,46 +515,4 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
}
}
class CheckSourceDialog : BaseDialogFragment() {
override fun onStart() {
super.onStart()
val dm = DisplayMetrics()
activity?.windowManager?.defaultDisplay?.getMetrics(dm)
dialog?.window?.setLayout(
(dm.widthPixels * 0.9).toInt(),
(dm.heightPixels * 0.14).toInt()
)
dialog?.setCancelable(false)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_progressbar_view, container)
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
arguments?.let { bundle ->
val maxProgress = bundle.getInt("maxProgress")
ck_progress_text.text = getString(R.string.progress_show, "", 0, maxProgress)
ck_progress.max = maxProgress
observeEvent<Int>(EventBus.CHECK_UP_PROGRESS) { progress->
ck_progress.progress = progress
}
observeEvent<String>(EventBus.CHECK_UP_PROGRESS_STRING) {
ck_progress_text.text = it
}
observeEvent<Int>(EventBus.CHECK_DONE) {
dismiss()
}
tv_footer_left.onClick {
CheckSource.stop(requireContext()).apply {
dismiss()
}
}
}
}
}
}

@ -7,6 +7,7 @@ import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Process
import android.view.View
import androidx.documentfile.provider.DocumentFile
import androidx.preference.ListPreference
@ -27,6 +28,7 @@ import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.theme.ATH
import io.legado.app.receiver.SharedReceiverActivity
import io.legado.app.service.WebService
import io.legado.app.ui.main.MainActivity
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.utils.*
@ -122,10 +124,13 @@ class OtherConfigFragment : BasePreferenceFragment(),
)
PreferKey.replaceEnableDefault -> AppConfig.replaceEnableDefault =
App.INSTANCE.getPrefBoolean(PreferKey.replaceEnableDefault, true)
PreferKey.language -> {
LanguageUtils.setConfigurationOld(App.INSTANCE)
postEvent(EventBus.RECREATE, "")
}
PreferKey.language -> listView.postDelayed({
LanguageUtils.setConfiguration(App.INSTANCE)
val intent = Intent(App.INSTANCE, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
App.INSTANCE.startActivity(intent)
Process.killProcess(Process.myPid())
}, 1000)
}
}

@ -4,6 +4,7 @@ import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Build
import android.os.LocaleList
import io.legado.app.constant.PreferKey
import java.util.*
@ -16,14 +17,14 @@ object LanguageUtils {
fun setConfiguration(context: Context): Context {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val resources: Resources = context.resources
val targetLocale: Locale = when (context.getPrefString(PreferKey.language)) {
"zh" -> Locale.CHINESE
"tw" -> Locale.TRADITIONAL_CHINESE
"en" -> Locale.ENGLISH
else -> getSystemLocale()
}
val metrics = resources.displayMetrics
val configuration: Configuration = resources.configuration
//Log.d("h11128", "set language to ${context.getPrefString(PreferKey.language)}")
val targetLocale = getSetLocale(context)
configuration.setLocale(targetLocale)
configuration.setLocales(LocaleList(targetLocale))
@Suppress("DEPRECATION")
resources.updateConfiguration(configuration, metrics)
context.createConfigurationContext(configuration)
} else {
setConfigurationOld(context)
@ -34,15 +35,10 @@ object LanguageUtils {
/**
* 设置语言
*/
fun setConfigurationOld(context: Context) {
private fun setConfigurationOld(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
val resources: Resources = context.resources
val targetLocale: Locale = when (context.getPrefString(PreferKey.language)) {
"zh" -> Locale.CHINESE
"tw" -> Locale.TRADITIONAL_CHINESE
"en" -> Locale.ENGLISH
else -> getSystemLocale()
}
val targetLocale = getSetLocale(context)
val configuration: Configuration = resources.configuration
@Suppress("DEPRECATION")
configuration.locale = targetLocale
@ -55,13 +51,62 @@ object LanguageUtils {
* 当前系统语言
*/
private fun getSystemLocale(): Locale {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多语言设置获取顶部的语言
Resources.getSystem().configuration.locales.get(0)
val locale: Locale
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多语言设置获取顶部的语言
locale = Resources.getSystem().configuration.locales.get(0)
} else {
@Suppress("DEPRECATION")
locale = Resources.getSystem().configuration.locale
}
return locale
}
/**
* 当前App语言
*/
private fun getAppLocale(context: Context): Locale {
val locale: Locale
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locale = context.resources.configuration.locales[0]
} else {
@Suppress("DEPRECATION")
Resources.getSystem().configuration.locale
locale = context.resources.configuration.locale
}
/*
Log.d("h11128", "displayName " + locale.displayName)
Log.d("h11128", "displayCountry " + locale.displayCountry)
Log.d("h11128", "displayLanguage " + locale.displayLanguage)
Log.d("h11128", "Language " + locale.language)
Log.d("h11128", "Country " + locale.country)
*/
return locale
}
/**
* 当前设置语言
*/
private fun getSetLocale(context: Context): Locale {
return when (context.getPrefString(PreferKey.language)) {
"zh" -> Locale.SIMPLIFIED_CHINESE
"tw" -> Locale.TRADITIONAL_CHINESE
"en" -> Locale.ENGLISH
else -> getSystemLocale()
}
}
/**
* 判断App语言和设置语言是否相同
*/
fun isSameWithSetting(context: Context): Boolean {
val locale = getAppLocale(context)
val language = locale.language
val country = locale.country
val pfLocale = getSetLocale(context)
val pfLanguage = pfLocale.language
val pfCountry = pfLocale.country
return language == pfLanguage && country == pfCountry
}
}

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

@ -9,7 +9,8 @@
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:gravity="center_vertical"
android:elevation="2dp" >
android:elevation="2dp"
tools:ignore="RtlHardcoded">
<io.legado.app.lib.theme.view.ATECheckBox
android:id="@+id/cb_selected_all"
@ -17,7 +18,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="5dp"
android:text="@string/select_all_count" />
android:text="@string/select_all" />
<io.legado.app.ui.widget.text.AccentStrokeTextView
android:id="@+id/btn_revert_selection"

@ -3,6 +3,12 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.main.MainActivity">
<item
android:id="@+id/menu_add_bookmark"
android:icon="@drawable/ic_bookmark"
android:title="@string/bookmark_add"
app:showAsAction="ifRoom" />
<group android:id="@+id/menu_group_on_line">
<item
android:id="@+id/menu_change_source"
@ -20,7 +26,7 @@
android:id="@+id/menu_download"
android:icon="@drawable/ic_download_line"
android:title="@string/offline_cache"
app:showAsAction="ifRoom" />
app:showAsAction="never" />
<item
android:id="@+id/menu_disable_book_source"
@ -58,13 +64,6 @@
</group>
<group android:id="@+id/menu_group_show">
<item
android:id="@+id/menu_add_bookmark"
android:icon="@drawable/ic_bookmark"
android:title="@string/bookmark_add"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_copy_text"
android:icon="@drawable/ic_copy"
@ -91,6 +90,4 @@
android:title="@string/book_info"
app:showAsAction="never" />
</group>
</menu>

@ -99,10 +99,10 @@
</string-array>
<string-array name="language">
<item>跟随系统</item>
<item>简体中文</item>
<item>繁体中文</item>
<item>英文</item>
<item>Auto</item>
<item>Simplified_Chinese</item>
<item>Traditional_Chinese</item>
<item>English</item>
</string-array>
</resources>

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pk_background_verification" translatable="false">background_verification</string>
<string name="pk_auto_refresh" translatable="false">auto_refresh</string>
<string name="pk_requested_direction" translatable="false">list_screen_direction</string>
<string name="pk_full_screen" translatable="false">full_screen</string>
@ -21,5 +20,5 @@
<string name="home_page_url" translatable="false">https://gedoor.github.io/MyBookshelf/</string>
<string name="latest_release_url" translatable="false">https://github.com/gedoor/legado/releases/latest</string>
<string name="latest_release_api" translatable="false">https://api.github.com/repos/gedoor/legado/releases/latest</string>
<string name="tg_url" translatable="false">https://t.me/joinchat/S_beh0a2BD_pGiHjrmGixA</string>
<string name="tg_url" translatable="false">https://t.me/yueduguanfang</string>
</resources>

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--App-->
<string name="app_name">Legado</string>

@ -51,13 +51,6 @@
app:iconSpaceReserved="false"
app:layout="@layout/view_preference_category">
<io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="true"
android:key="@string/pk_background_verification"
android:summary="@string/ps_background_verification"
android:title="@string/pt_background_verification"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="true"
android:key="replaceEnableDefault"

@ -15,7 +15,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'de.timfreiheit.resourceplaceholders:placeholders:0.3'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.gms:google-services:4.3.4'
classpath 'io.fabric.tools:gradle:1.31.2'
}
}

Loading…
Cancel
Save