修改注册接口,添加活动和防丢失功能

This commit is contained in:
laochen 2024-07-22 14:01:58 +08:00
parent 1264cb175b
commit 59c3217f38
39 changed files with 725 additions and 118 deletions

View File

@ -9,11 +9,10 @@ plugins {
id("kotlin-parcelize")
id("com.google.devtools.ksp")
id("kotlinx-serialization")
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
implementation(fileTree(mapOf("dir" to "src/main/libs", "include" to listOf("*.aar"))))
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
// compileOnly(project(":hideapi"))
@ -99,6 +98,11 @@ dependencies {
// https://mvnrepository.com/artifact/com.google.zxing/core
implementation("com.google.zxing:core:3.5.3")
implementation("com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4")
// https://mvnrepository.com/artifact/com.airbnb.android/lottie
implementation("com.airbnb.android:lottie:5.2.0")
// https://mvnrepository.com/artifact/com.github.bumptech.glide/glide
implementation("com.github.bumptech.glide:glide:4.13.2")
}
@ -159,15 +163,15 @@ android {
abiFilters.add("armeabi-v7a")
}
}
sourceSets {
getByName("main") {
jniLibs.srcDir("src/main/jniLibs")
}
sourceSets.all {
jniLibs.srcDir("src/main/jniLibs")
}
}
repositories {
flatDir {
dirs("libs")
dirs("src/main/libs")
}
mavenCentral()
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -134,6 +134,12 @@
<activity
android:name=".act.ForGetPwdActivity"
android:screenOrientation="portrait" />
<activity
android:name=".act.activityActivity"
android:screenOrientation="portrait" />
<activity
android:name=".act.LossPreventionActivity"
android:screenOrientation="portrait" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"

View File

@ -0,0 +1,12 @@
//package com.next.vpn
//
//import androidx.annotation.Keep
//
//@Keep
//object Stup {
// external fun key(): String
// init {
// System.loadLibrary("initSDK")
//
// }
//}

View File

@ -0,0 +1,87 @@
package com.yingmao.clash.act
import android.content.ContentValues
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.observe
import com.bumptech.glide.Glide
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.AppShareInfoRsp
import com.yingmao.clash.view.RxToast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class LossPreventionActivity : BaseActivity() {
var iv_lossper: ImageView? = null;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_activity_losspre)
showTitleBar("防丢失")
initView()
}
private fun initView() {
val tv_save = findViewById<TextView>(R.id.tv_save)
iv_lossper = findViewById<ImageView>(R.id.iv_gif)
tv_save.setOnClickListener {
lifecycleScope.launch {
saveImage()
}
}
Glide.with(this).load("https://www.lead2win.cc/assets/yingmao.jpg").fitCenter()
.into(iv_lossper!!)
}
private suspend fun saveImage() {
withContext(Dispatchers.IO) {
val imageUrl = this@LossPreventionActivity.contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
ContentValues()
) ?: kotlin.run {
Toast.makeText(this@LossPreventionActivity, "存储失败,请使用屏幕截屏功能保存", Toast.LENGTH_SHORT).show()
}
this@LossPreventionActivity.contentResolver.openOutputStream(imageUrl as Uri).use {
iv_lossper?.let { iv ->
if (iv.drawable.toBitmap().compress(Bitmap.CompressFormat.PNG, 90, it)) {
MainScope().launch {
Toast.makeText(
this@LossPreventionActivity,
"存储成功",
Toast.LENGTH_SHORT
).show()
}
} else {
MainScope().launch {
Toast.makeText(
this@LossPreventionActivity,
"存储失败,请使用屏幕截屏功能保存",
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
}
}

View File

@ -26,6 +26,7 @@ import androidx.viewpager2.widget.ViewPager2
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import com.airbnb.lottie.LottieAnimationView
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
@ -109,7 +110,6 @@ class NewMainActivity : BaseActivity() {
var isSubed = false
var newUuid: String? = null
var subUrl: String? = null
// private var profile: ProfileManager? = null
// private var clashManager: ClashManager? = null
var clashBinder: IClashManager? = null
@ -249,13 +249,13 @@ class NewMainActivity : BaseActivity() {
Log.i("newMainActGlo isGlobal==>${isGlobal}")
newMainActGlo = isGlobal
startLog()
showBindAccount()
}
private fun startLog() {
launch(Dispatchers.IO) {
// startForegroundServiceCompat(LogcatService::class.intent)
//
// val logcat = bindLogcatService()
// val ticker = ticker(500)
// var initial = true
@ -272,8 +272,13 @@ class NewMainActivity : BaseActivity() {
val observer = object : ILogObserver {
override fun newItem(log: LogMessage) {
var msg = log.message
if (BuildConfig.DEBUG) {
Log.i("startLog msg==>${msg}")
}
var domain = Utils.getDomainNameFromString(msg)
// Log.i("startLog meessage==>${domain}")
// if (BuildConfig.DEBUG) {
// Log.i("startLog meessage==>${domain}")
// }
if (!TextUtils.isEmpty(domain)) {
addOrSendHost(domain!!)
}
@ -283,10 +288,7 @@ class NewMainActivity : BaseActivity() {
clashBinder?.let {
it.setLogObserver(observer)
}
}
}
@ -492,7 +494,15 @@ class NewMainActivity : BaseActivity() {
fragments.add(RechargeFragment())
containerVP.adapter = MainVPAdapter(fragments, supportFragmentManager, lifecycle)
containerVP.isUserInputEnabled = false
var aniAct=findViewById<LottieAnimationView>(R.id.lottie_activity)
aniAct.setAnimation(R.raw.activity)
aniAct.playAnimation()
aniAct.setOnClickListener {
startActivity(Intent(CommonUtils.getApp(), activityActivity::class.java))
}
findViewById<LinearLayout>(R.id.ll_activity).setOnClickListener {
startActivity(Intent(CommonUtils.getApp(), activityActivity::class.java))
}
setSometion()
}
@ -544,15 +554,7 @@ class NewMainActivity : BaseActivity() {
// 临时用户显示默认密码
// findViewById<TextView>(R.id.tv_default_psw).visibility = View.VISIBLE
tv_band.setOnClickListener {//绑定
val dialog = DialogBandChoose(this@NewMainActivity)
dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener {
override fun onBandClick(isPhone: Boolean) {
val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java)
intent.putExtra("isPhone", isPhone)
startActivity(intent)
}
})
dialog.show()
showBingDialogChoose()
drawer.close()
}
tv_band.visibility = View.VISIBLE
@ -646,7 +648,10 @@ class NewMainActivity : BaseActivity() {
startActivity(Intent(this, BZYWebViewKeFu::class.java))
drawer.close()
}
findViewById<TextView>(R.id.tv_fds).setOnClickListener {//防丢失
startActivity(Intent(this, LossPreventionActivity::class.java))
drawer.close()
}
drawer = findViewById(R.id.drawer)
iv_slider.setOnClickListener {
if (containerVP.currentItem != 0) {
@ -659,6 +664,7 @@ class NewMainActivity : BaseActivity() {
}
var checkPayResultDia: MaterialDialog? = null
var checkBindAccountDia: MaterialDialog? = null
public fun goRechargeWeb() {
val mmkv = MMKV.defaultMMKV()
val a = mmkv.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")
@ -674,22 +680,64 @@ class NewMainActivity : BaseActivity() {
}
private fun showPayResultDialog() {
checkPayResultDia = MaterialDialog(this).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.payconfirm1_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
mainAtyVM.checkLogin()
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
}
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.payconfirm1_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
mainAtyVM.checkLogin()
showBindAccount()
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
showBindAccount()
}
}
}
private fun showBindAccount() {
var useraccount =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!;
if (Utils.isEmail(useraccount) || Utils.isPhoneNumber(useraccount)) {
return
}
checkBindAccountDia = MaterialDialog(this).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.bind_account_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
//跳转到绑定邮箱界面
showBingDialogChoose()
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
}
}
}
private fun showBingDialogChoose() {
val dialog = DialogBandChoose(this@NewMainActivity)
dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener {
override fun onBandClick(isPhone: Boolean) {
val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java)
intent.putExtra("isPhone", isPhone)
startActivity(intent)
}
})
dialog.show()
}
var payResultLoading: RxDialogShapeLoading? = null
@ -712,7 +760,7 @@ class NewMainActivity : BaseActivity() {
}
}
// fun setExpireDate() {
// fun setExpireDate() {
// val isExpired = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_VPN_EXPIRED)
// val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
//
@ -738,6 +786,7 @@ class NewMainActivity : BaseActivity() {
}
return true;
}
fun setExpireDate() {
var isExpire = checkExpire()
var endTimeInfo = "--"
@ -913,5 +962,4 @@ class NewMainActivity : BaseActivity() {
showPayResultDialog()
}
}
}

View File

@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.lifecycle.ViewModelProvider
import com.google.gson.JsonObject
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
@ -18,7 +19,9 @@ import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.RegisterRsp
import com.yingmao.clash.util.AESUtil
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.Utils
import com.yingmao.clash.view.PasswordTransformationMethodBigDot
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.SlidingVerification
@ -120,25 +123,43 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
}
fun register() {
// fun register() {
// val registerAtyVM = ViewModelProvider(this).get(RegisterAtyVM::class.java)
// val params: Map<String, String> = mutableMapOf(
// "phoneNumber" to username,
// "password" to password,
// "checkPassword" to password,
// "id" to BuildConfig.productId,
//// "clientIp" to "",
// "registerAddress" to "devTest",
//// "from" to ""
// )
//
// registerAtyVM.register(params)
// }
fun doRegisterByEncryption() {
val registerAtyVM = ViewModelProvider(this).get(RegisterAtyVM::class.java)
val params: Map<String, String> = mutableMapOf(
"phoneNumber" to username,
"password" to password,
"checkPassword" to password,
"id" to BuildConfig.productId,
// "clientIp" to "",
"registerAddress" to "devTest",
// "from" to ""
var req_json = JsonObject()
req_json.addProperty("phoneNumber", username)
req_json.addProperty("password", password)
req_json.addProperty("checkPassword", password)
req_json.addProperty("id", BuildConfig.productId)
req_json.addProperty("clientIp", Utils.getIPAddress())
req_json.addProperty("from", "5")
var data = AESUtil.byteArrayToHexStr(
AESUtil.encrypt(req_json.toString())
)
registerAtyVM.register(params)
val params: Map<String, String> = mutableMapOf(
"data" to data
)
registerAtyVM.registerByEncryption(params)
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.tv_register -> {
if (checkInput()) register()
if (checkInput()) doRegisterByEncryption()
}
R.id.tv_login -> {
@ -168,7 +189,6 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
}
} else it.progress = 0
}
}
}
@ -204,7 +224,7 @@ class RegisterActivity : BaseActivity(), View.OnClickListener {
getFocusAndShowSoftInput(passwordEt_check)
return false
}
if (!password.equals(password_check)){
if (!password.equals(password_check)) {
passwordErrorTv.visibility = View.VISIBLE
passwordErrorTv.text = getString(R.string.please_input_password_double_err)
return false

View File

@ -1,5 +1,6 @@
package com.yingmao.clash.act
import android.util.Log
import com.yingmao.clash.base.PublicViewMode
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
@ -7,8 +8,17 @@ import com.yingmao.clash.net.http.NetService
class RegisterAtyVM : PublicViewMode() {
fun register(params : Map<String,String>){
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.REGISTER) { httpApi.register(params) }
// fun register(params : Map<String,String>){
// val httpApi = NetService.instances.createHttps(HttpApi::class.java)
// doAsync(HttpReqType.REGISTER) { httpApi.register(params) }
// }
fun registerByEncryption(params: Map<String, String>) {
Log.e("data", "register ....")
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.REGISTER) {
httpApi.registerByEncryption(params)
}
}
}

View File

@ -7,6 +7,7 @@ import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
@ -19,6 +20,8 @@ import com.yingmao.clash.view.dialog.RxDialogSureCancel
import com.afollestad.materialdialogs.MaterialDialog
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.yingmao.clash.net.http.entity.RegisterRsp
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
@ -37,6 +40,7 @@ import com.yingmao.clash.listener.AsyncCallback
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.LoginRsp
import com.yingmao.clash.net.http.entity.RegisterRspOld
import com.yingmao.clash.net.http.entity.SubscriptionRsp
import com.yingmao.clash.service.model.Profile
import com.yingmao.clash.util.AESUtil
@ -81,13 +85,12 @@ class SplashActivity : BaseActivity() {
// mPermissions.add(Manifest.permission.ACCESS_NETWORK_STATE)
// if (checkPermissions(mPermissions)) {//权限请求通过
// Log.e("gg", "per sss")
//
// } else {//权限请求未通过
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// requestPermissions(mPermissions.toTypedArray(), PERMISSION_REQUEST_CODE)
// }
// }
// Log.e("gg", "Stup.key======================>" + Stup.key())
val routerSet = MMKV.defaultMMKV().decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST)
if (routerSet != null && routerSet.size > 0) {
isNeedRegister()
@ -109,7 +112,6 @@ class SplashActivity : BaseActivity() {
})
}
}
}
private fun checkPermission(): Boolean {
@ -128,16 +130,16 @@ class SplashActivity : BaseActivity() {
override fun onStarted() {
super.onStarted()
}
private fun isNeedRegister() {
if (BuildConfig.productId != "22222" && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录广州22222也是非自动注册
if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录广州22222也是非自动注册
rlPb.visibility = View.VISIBLE
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) {
splashAtyVM.checkLogin()
} else {
doRegister()
// doRegister()
doRegisterByEncryption()
}
} else {//非渠道自由包
val token = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_TOKEN)
@ -178,7 +180,24 @@ class SplashActivity : BaseActivity() {
"from" to "5",
)
splashAtyVM.register(params)
}
fun doRegisterByEncryption() {
var req_json = JsonObject()
req_json.addProperty("phoneNumber", username)
req_json.addProperty("password", BZYConstants.defaultPassword)
req_json.addProperty("checkPassword", BZYConstants.defaultPassword)
req_json.addProperty("id", BuildConfig.productId)
req_json.addProperty("clientIp", Utils.getIPAddress())
req_json.addProperty("from", "5")
var data = AESUtil.byteArrayToHexStr(
AESUtil.encrypt(req_json.toString())
)
val params: Map<String, String> = mutableMapOf(
"data" to data
)
splashAtyVM.registerByEncryption(params)
}
// private fun initSub() {
// var yaml = context?.getString(com.yingmao.clash.service.R.string.configuration_yaml)
@ -277,7 +296,7 @@ class SplashActivity : BaseActivity() {
when (httpStatus.reqType) {
HttpReqType.REGISTER -> {
with(httpStatus.rsp as RegisterRsp) {
if (code == "10000") {
if (code == "10000" || code == "200") {
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
MMKV.defaultMMKV()
.encode(MMKV_KEY_REMEMBER_PASSWORD, BZYConstants.defaultPassword)
@ -296,7 +315,16 @@ class SplashActivity : BaseActivity() {
RxToast.error(it)
}
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, data)
// if (data != null) {
//
// var jo =
// Gson().fromJson<JsonObject>(data, JsonObject::class.java)
// var userName = jo.get("data").asString;
// if (!TextUtils.isEmpty(userName)) {
//
// }
// }
MMKV.defaultMMKV().encode(MMKV_KEY_REMEMBER_USERNAME, username)
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
startActivity(intent)
finish()
@ -304,7 +332,8 @@ class SplashActivity : BaseActivity() {
MaterialDialog(this@SplashActivity).show {
message(text = "初始化失败")
positiveButton(R.string.retry) {
doRegister()
// doRegister()
doRegisterByEncryption()
}
negativeButton(R.string.cancel) {
it.dismiss()
@ -376,12 +405,14 @@ class SplashActivity : BaseActivity() {
com.yingmao.clash.common.log.Log.d("httpFailure HttpReqType.REGISTER")
if (Utils.switchServer()) {//切换服务器并直接重试
doRegister()
// doRegister()
doRegisterByEncryption()
} else {
MaterialDialog(this@SplashActivity).show {
message(text = "初始化失败")
positiveButton(R.string.retry) {
doRegister()
// doRegister()
doRegisterByEncryption()
}
negativeButton(R.string.cancel) {
it.dismiss()

View File

@ -0,0 +1,150 @@
package com.yingmao.clash.act
import android.app.Activity
import android.app.Application
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.yingmao.clash.R
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.ExpensesRecordRsp
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.adapter.ExpensesRecordAdapter
class activityActivity : BaseActivity() {
private lateinit var expensesRecordVM :ExpensesRecordVM
private lateinit var swipeLayout : SwipeRefreshLayout
private lateinit var expensesRecordRv : RecyclerView
private lateinit var expensesRecordAdapter : ExpensesRecordAdapter
private val mPageInfo = PageInfo()
companion object{
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_activity_activity)
showTitleBar("活动")
initView()
// initAdapter()
// initRefreshLayout()
// initLoadMore()
}
private fun initView() {
}
private fun initAdapter() {
expensesRecordAdapter = ExpensesRecordAdapter()
expensesRecordAdapter.animationEnable = true
expensesRecordRv.adapter = expensesRecordAdapter
}
private fun initRefreshLayout() {
swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
swipeLayout.setOnRefreshListener {
refresh()
}
}
private fun initLoadMore() {
expensesRecordAdapter.loadMoreModule.setOnLoadMoreListener {
loadMore()
}
expensesRecordAdapter.loadMoreModule.isAutoLoadMore = true
expensesRecordAdapter.loadMoreModule.isEnableLoadMoreIfNotFullPage = false
}
override fun onStart() {
super.onStart()
// 进入页面,刷新数据
loadFirstPage()
}
private fun refresh() {
// 这里的作用是防止下拉刷新的时候还可以上拉加载
expensesRecordAdapter.loadMoreModule.isEnableLoadMore = false
// 下拉刷新,需要重置页数
mPageInfo.reset()
loadFirstPage()
}
private fun loadFirstPage() {
// expensesRecordVM.getExpensesRecord(mPageInfo)
}
private fun loadMore() {
expensesRecordVM.getExpensesRecord(mPageInfo)
}
override fun httpLoading(httpStatus: HttpStatus.Loading) {
if(httpStatus.reqType == HttpReqType.EXPENSES_RECORD){
if(mPageInfo.isFirstPage) {
swipeLayout.isRefreshing = true
}
}
}
override fun httpSuccess(httpStatus: HttpStatus.Success) {
if(httpStatus.reqType == HttpReqType.EXPENSES_RECORD){
if(mPageInfo.isFirstPage) {
swipeLayout.isRefreshing = false
}
expensesRecordAdapter.loadMoreModule.isEnableLoadMore = true
if(httpStatus.rsp is ExpensesRecordRsp){
(httpStatus.rsp as ExpensesRecordRsp).let { expensesRecordRsp ->
if(expensesRecordRsp.code == "1000"){
if(expensesRecordRsp.data != null){
val expensesRecordList =expensesRecordRsp.data?.expensesRecords
if(!expensesRecordList.isNullOrEmpty()){
if(mPageInfo.isFirstPage) {
expensesRecordAdapter.data = expensesRecordList
}else{
expensesRecordAdapter.addData(expensesRecordList)
}
mPageInfo.nextPage()
if (expensesRecordList.size < 5) {
//如果不够一页,显示没有更多数据布局
expensesRecordAdapter.loadMoreModule.loadMoreEnd()
// RxToast.info("没有更多数据了")
} else {
expensesRecordAdapter.loadMoreModule.loadMoreComplete()
}
}else{
//如果不够一页,显示没有更多数据布局
expensesRecordAdapter.loadMoreModule.loadMoreEnd()
// RxToast.info("没有更多数据了")
}
}else{
expensesRecordAdapter.loadMoreModule.loadMoreComplete()
}
}else {
RxToast.error("${expensesRecordRsp.code}${expensesRecordRsp.message}")
expensesRecordAdapter.loadMoreModule.loadMoreFail()
}
}
}
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
if(httpStatus.reqType == HttpReqType.EXPENSES_RECORD){
if(mPageInfo.isFirstPage) {
swipeLayout.isRefreshing = true
}
RxToast.error("获取订单信息异常")
expensesRecordAdapter.loadMoreModule.loadMoreFail()
}
}
}

View File

@ -13,14 +13,11 @@ import androidx.core.content.getSystemService
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.common.Global
import com.yingmao.clash.common.compat.currentProcessName
import com.yingmao.clash.common.log.Log
import com.yingmao.clash.remote.Remote
import com.yingmao.clash.service.ProfileWorker
import com.yingmao.clash.service.ProfileWorker.Companion
import com.yingmao.clash.service.util.sendServiceRecreated
import com.yingmao.clash.util.clashDir
import java.io.File
import java.io.FileOutputStream
@ -111,6 +108,5 @@ class MainApplication : Application() {
)
nm.deleteNotificationChannel("service-nat") // NAT mode is gone for good
}
}
}

View File

@ -84,11 +84,9 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
private lateinit var nodeNameTv: TextView
private lateinit var countryIv: ImageView
// var currentNode: Profile? = null
private var reConnection = false
override fun init(
titleBarRl: RelativeLayout,
backIv: ImageView,
@ -124,7 +122,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
BZYConstants.MMKV_KEY_TOKEN
).toString()
com.yingmao.clash.common.log.Log.d("token==>$token")
Log.d("token==>$token")
}

View File

@ -23,6 +23,7 @@ import com.tencent.mmkv.MMKV
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.entity.AppVersionCheckRsp
import com.yingmao.clash.net.http.entity.LoginRsp2
import com.yingmao.clash.net.http.entity.RegisterRspOld
import com.yingmao.clash.net.http.entity.SendSmsRsp
import com.yingmao.clash.net.http.entity.VipSignRsp
import okhttp3.RequestBody
@ -66,6 +67,13 @@ interface HttpApi {
@POST("/netbarcloud/vpn/octopusRegister.do")
suspend fun register(@QueryMap params: Map<String, String>): RegisterRsp
//加密注册
@Headers(
"User-Agent: Octopus_Android"
)
@POST("/netbarcloud/vpn/appRegister.do")
suspend fun registerByEncryption(@QueryMap params: Map<String, String>): RegisterRsp
//显示赠送时长
@Headers(
"User-Agent: Octopus_Android"

View File

@ -1,6 +1,7 @@
package com.yingmao.clash.net.http.entity
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName
data class RegisterRsp(
@ -12,7 +13,7 @@ data class RegisterRsp(
val code: String? = null,
@field:SerializedName("data")
val data: String = "",
val data: Any? = null,
@field:SerializedName("message")
val message: String? = null,

View File

@ -0,0 +1,23 @@
package com.yingmao.clash.net.http.entity
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName
data class RegisterRspOld(
@field:SerializedName("validityPeriod")
val validityPeriod: String? = null,
@field:SerializedName("code")
val code: String? = null,
@field:SerializedName("data")
val data: String? = null,
@field:SerializedName("message")
val message: String? = null,
@field:SerializedName("userid")
val userid: String? = null
) : BaseRsp

View File

@ -64,22 +64,9 @@ object Utils {
// return imsi;
// }
fun getMac(): String {
var mac = ""
MainApplication.getApp()?.let {
var wm = it.getSystemService(Context.WIFI_SERVICE) as WifiManager
if (ActivityCompat.checkSelfPermission(
it, Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
mac = wm.connectionInfo.macAddress
if (!TextUtils.isEmpty(mac)) {
mac = AESUtil.byteArrayToHexStr(AESUtil.encrypt(mac))
}
}
}
return mac
}
fun getMacAddress(): String? {
try {
@ -115,11 +102,18 @@ object Utils {
}
fun isEmail(email: String): Boolean {
if (TextUtils.isEmpty(email)){
return false;
}
val pattern = Regex("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]+")
return pattern.matches(email)
}
fun isPhoneNumber(phone: String): Boolean {
if (TextUtils.isEmpty(phone)){
return false;
}
return phone.startsWith("1") && phone.length == 11
}

View File

@ -94,7 +94,14 @@ class SplashAtyVM : PublicViewMode() {
httpApi.register(params)
}
}
fun registerByEncryption(params: Map<String, String>) {
Log.e("data", "register ....")
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.REGISTER) {
httpApi.registerByEncryption(params)
}
}
fun login(username: String, password: String) {
val params: Map<String, String> =

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" tools:ignore="MissingDefaultResource">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<gradient android:type="linear"
android:angle="180"
android:startColor="#22D1E1"
android:endColor="#0A8DE0"
/>
<corners android:radius="24dp"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<stroke android:color="#1A2D4C" android:width="1dp"/>
<corners android:radius="24dp"/>
</shape>
</item>
</selector>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_bg"
android:background="@drawable/bg_signin"
android:paddingTop="18dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/recharge_user_info_bg"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center"
android:text="方便您在不同的设备登录,\n建议绑定账号."
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_10"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_pay_cancle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_weight="1"
android:background="@drawable/cancel_btn_bg_selector"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingTop="@dimen/dp_10"
android:paddingRight="20dp"
android:paddingBottom="@dimen/dp_10"
android:text="取消"
android:textColor="@color/white" />
<TextView
android:id="@+id/tv_pay_finish"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginBottom="20dp"
android:layout_weight="1"
android:background="@drawable/cancel_btn_bg_selector"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingTop="@dimen/dp_10"
android:paddingRight="20dp"
android:paddingBottom="@dimen/dp_10"
android:text="绑定"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>

View File

@ -67,17 +67,21 @@
android:textColor="@color/white"
android:textSize="17sp"></android.widget.Button>
</LinearLayout>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.95" /> <!-- 90% from top -->
<LinearLayout
android:id="@+id/ll_node"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/guideline"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="80dp"
android:background="@drawable/main_node_bg_spape"
android:gravity="center"
android:orientation="vertical"

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_bg"
android:paddingTop="18dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_expenses_record"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="26dp"
app:layout_constraintTop_toBottomOf="@+id/rl_title_bar"
/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_bg"
tools:ignore="MissingConstraints">
<ImageView
android:id="@+id/iv_gif"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:scaleType="fitXY"
android:src="@drawable/gift"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.80"
app:layout_constraintHorizontal_bias="0.487"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.95" />
<TextView
android:id="@+id/tv_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_login_tv_login_start_margin"
android:layout_marginTop="25dp"
android:layout_marginEnd="@dimen/layout_login_tv_login_end_margin"
android:background="@drawable/main_recharge_bg_selector"
android:gravity="center"
android:paddingTop="@dimen/layout_login_tv_login_top_padding"
android:paddingBottom="@dimen/layout_login_tv_login_bottom_padding"
android:text="保存至相册"
android:textColor="@color/text_yellow"
android:textSize="@dimen/layout_login_tv_login_textsize"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@+id/iv_gif" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -29,16 +29,29 @@
android:layout_marginTop="30dp"
android:src="@drawable/ic_s_menu" />
<ImageView
android:id="@+id/user_my"
android:layout_width="35dp"
android:layout_height="35dp"
<LinearLayout
android:id="@+id/ll_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="30dp"
android:visibility="gone"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:src="@drawable/user">
</ImageView>
android:gravity="center"
android:orientation="vertical">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_activity"
android:layout_width="45dp"
android:layout_height="40dp"
app:lottie_autoPlay="true"
app:lottie_loop="true"></com.airbnb.lottie.LottieAnimationView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="活动"
android:textColor="@color/text_yellow"
android:textSize="16sp"
android:textStyle="bold"></TextView>
</LinearLayout>
<!-- <TextView-->
<!-- android:id="@+id/tv_recharge"-->
<!-- android:layout_width="wrap_content"-->
@ -49,7 +62,7 @@
<!-- android:background="@drawable/cancel_btn_bg_selector"-->
<!-- android:drawablePadding="5dp"-->
<!-- android:gravity="center"-->
<!-- android:paddingLeft="@dimen/dp_10"-->
<!-- w android:paddingLeft="@dimen/dp_10"-->
<!-- android:paddingTop="5dp"-->
<!-- android:paddingRight="@dimen/dp_10"-->
<!-- android:paddingBottom="5dp"-->
@ -272,7 +285,24 @@
android:layout_marginBottom="10dp"
android:background="@color/white_50" />
<TextView
android:id="@+id/tv_fds"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="防丢失"
android:textColor="@color/white"
android:textSize="16sp"
app:drawableLeftCompat="@drawable/loss_pre" />
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="@color/white_50" />
<TextView
android:id="@+id/tv_setting"
android:layout_width="match_parent"
@ -287,24 +317,24 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_marginTop="15dp"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<TextView
android:id="@+id/tv_vip_recharge"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="@drawable/main_recharge_bg_selector"
android:gravity="center"
android:text="续费充值"
android:layout_marginRight="5dp"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_vip_sign"
android:layout_width="0dp"
android:layout_marginLeft="5dp"
android:layout_height="35dp"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="@drawable/main_recharge_bg_selector"
android:gravity="center"

View File

@ -46,7 +46,7 @@
android:layout_marginLeft="50dp"
android:layout_marginBottom="20dp"
android:layout_weight="1"
android:background="@drawable/login_btn_bg_selector"
android:background="@drawable/cancel_btn_bg_selector"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingTop="@dimen/dp_10"

View File

@ -46,7 +46,7 @@
android:layout_marginLeft="50dp"
android:layout_marginBottom="20dp"
android:layout_weight="1"
android:background="@drawable/login_btn_bg_selector"
android:background="@drawable/cancel_btn_bg_selector"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingTop="@dimen/dp_10"

File diff suppressed because one or more lines are too long

View File

@ -51,8 +51,8 @@ subprojects {
minSdk = 21
//noinspection ExpiredTargetSdkVersion
targetSdk = 31
versionName = "1.0.0.9"
versionCode = 1009
versionName = "1.0.1.0"
versionCode = 1010
resValue("string", "release_name", "v$versionName")
resValue("integer", "release_code", "$versionCode")
externalNativeBuild {
@ -89,6 +89,7 @@ subprojects {
if (isApp) {
// applicationIdSuffix = ".meta"
}
buildConfigField("boolean", "is_free", "false")
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
@ -108,6 +109,7 @@ subprojects {
if (isApp) {
// applicationIdSuffix = ".meta"
}
buildConfigField("boolean", "is_free", "false")
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
@ -127,6 +129,7 @@ subprojects {
if (isApp) {
// applicationIdSuffix = ".meta"
}
buildConfigField("boolean", "is_free", "false")
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
@ -147,6 +150,7 @@ subprojects {
if (isApp) {
// applicationIdSuffix = ".meta"
}
buildConfigField("boolean", "is_free", "false")
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
@ -173,7 +177,7 @@ subprojects {
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
// buildConfigField("String", "service_url", "\"https://api.gaogaoshousoft.cc:18001\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "productId", "\"9586\"")
manifestPlaceholders(
@ -195,7 +199,7 @@ subprojects {
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
// buildConfigField("String", "service_url", "\"https://api.gaogaoshousoft.cc:18001\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "productId", "\"9707\"")
manifestPlaceholders(
@ -213,6 +217,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"6789\"")
@ -231,6 +236,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"3229\"")
@ -249,6 +255,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"9583\"")
@ -267,6 +274,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"9972\"")
@ -285,6 +293,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"182242\"")
@ -306,6 +315,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "false")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
// buildConfigField("String", "service_url", "\"https://api.gaogaoshousoft.cc:18001\"")
buildConfigField("String", "service_url", "\"https://api.otcopusvpn.cc:18008\"")
@ -328,6 +338,7 @@ subprojects {
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "false")
buildConfigField("boolean", "is_free", "true")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
// buildConfigField("String", "service_url", "\"https://api.gaogaoshousoft.cc:18001\"")
buildConfigField("String", "service_url", "\"https://app.bazhuayujiasu.cc:18001\"")
@ -338,6 +349,26 @@ subprojects {
)
)
}
//影猫自由包
create("22223") {
isDefault = true
dimension = flavorDimensionList[0]
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
if (isApp) {
// applicationIdSuffix = ".meta"
}
buildConfigField("boolean", "is_back_cn", "false")
buildConfigField("boolean", "is_ym", "true")
buildConfigField("boolean", "is_free", "true")
buildConfigField("String", "applicationId", "\"com.yingmao.clash\"")
buildConfigField("String", "service_url", "\"https://api.yingmaovpnpro.win:18002\"")
buildConfigField("String", "productId", "\"22222\"")
manifestPlaceholders(
mapOf(
"APP_NAME" to "@string/app_name_gz", "APP_ICON" to "@mipmap/ic_logo_9972"
)
)
}
create("meta") {
dimension = flavorDimensionList[0]
@ -357,7 +388,7 @@ subprojects {
java.srcDirs("src/foss/java")
}
}
1
signingConfigs {
val keystore = rootProject.file("signing.properties")
if (keystore.exists()) {