Commit b6ff6cd1 authored by UIUANG\Zsc's avatar UIUANG\Zsc

抽离

parent d4492da6
......@@ -13,6 +13,9 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/base" />
<option value="$PROJECT_DIR$/common" />
<option value="$PROJECT_DIR$/http" />
<option value="$PROJECT_DIR$/self_yppos" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
......
......@@ -36,5 +36,15 @@
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://maven.aliyun.com/repository/google" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
</component>
</project>
\ No newline at end of file
......@@ -4,7 +4,9 @@ plugins {
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
static def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
......@@ -13,8 +15,8 @@ android {
applicationId "com.ypsx.yppos"
minSdkVersion 21
targetSdkVersion 30
versionCode 100001
versionName "1.00.001"
versionCode 100003
versionName "1.00.003"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
......@@ -75,7 +77,8 @@ android {
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = 'yppos-v-' + variant.buildType.name + '.apk'
outputFileName = "yppos_v${variant.versionCode}-${variant.versionName}-${variant.buildType.name}-${releaseTime()}.apk"
// outputFileName = 'yppos-v-' + variant.buildType.name+'-' +variant.versionCode+ '.apk'
}
}
......@@ -83,10 +86,11 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$rootProject.kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation project(path: ':base')
implementation files('libs/platform_sdk_v3.1.0326.jar')
implementation project(path: ':common')
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
......@@ -97,22 +101,12 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.cardview:cardview:1.0.0'
implementation "com.afollestad.material-dialogs:lifecycle:3.3.0"
implementation "com.afollestad.material-dialogs:core:3.3.0"
implementation 'com.afollestad.material-dialogs:input:3.3.0'
//微信开源项目,替代SP
implementation 'com.tencent:mmkv:1.2.10'
implementation 'com.blankj:utilcodex:1.26.0'
//第三方recyclerview
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
implementation 'com.vmadalin:easypermissions-ktx:1.0.0'
//管理界面状态库
implementation 'com.kingja.loadsir:loadsir:1.3.8'
//屏幕适配
implementation 'me.jessyan:autosize:1.2.1'
implementation 'com.elvishew:xlog:1.10.1'
//BaseAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'
......
......@@ -10,9 +10,9 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 100001,
"versionName": "1.00.001",
"outputFile": "yppos-v-release.apk"
"versionCode": 100003,
"versionName": "1.00.003",
"outputFile": "yppos_v100003-1.00.003-release-2021-10-27.apk"
}
]
}
\ No newline at end of file
package com.ypsx.yppos
import android.content.Intent
import android.os.Build
import android.os.Process
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
import com.elvishew.xlog.formatter.border.DefaultBorderFormatter
import com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter
import com.elvishew.xlog.formatter.message.throwable.DefaultThrowableFormatter
import com.elvishew.xlog.formatter.message.xml.DefaultXmlFormatter
import com.elvishew.xlog.formatter.stacktrace.DefaultStackTraceFormatter
import com.elvishew.xlog.formatter.thread.DefaultThreadFormatter
import com.elvishew.xlog.printer.AndroidPrinter
import com.elvishew.xlog.printer.Printer
import com.elvishew.xlog.printer.file.FilePrinter
import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy2
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
import com.hjq.toast.ToastUtils
import com.tencent.mmkv.MMKV
import com.ypsx.base.base.BaseApp
import com.ypsx.yppos.app.event.AppViewModel
import com.ypsx.yppos.app.event.EventViewModel
import com.ypsx.base.util.dXLog
import com.ypsx.common.app.event.AppViewModel
import com.ypsx.common.app.event.EventViewModel
import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.utils.PathUtils
import com.ypsx.yppos.utils.XLogFlattener
import com.ypsx.yppos.utils.dXLog
const val maxSize: Long = 1024 * 1024 * 50
const val maxTimeMillis: Long = 1000 * 60 * 60 * 24 * 30
const val maxBackupIndex: Int = 10
class PosApp : BaseApp() {
......@@ -44,7 +19,6 @@ class PosApp : BaseApp() {
override fun onCreate() {
super.onCreate()
MMKV.initialize(this)
// 初始化 Toast 框架
ToastUtils.init(this);
......@@ -58,40 +32,6 @@ class PosApp : BaseApp() {
}
private fun initXlog() {
val config = LogConfiguration.Builder()
.logLevel(LogLevel.ALL)// 指定日志级别,低于该级别的日志将不会被打印,默认为 LogLevel.ALL
.tag(getString(R.string.global_tag)) // 指定 TAG,默认为 "X-LOG"
.enableThreadInfo() // 允许打印线程信息,默认禁止
.enableStackTrace(2) // 允许打印深度为 2 的调用栈信息,默认禁止
.enableBorder() // 允许打印日志边框,默认禁止
.jsonFormatter(DefaultJsonFormatter()) // 指定 JSON 格式化器,默认为 DefaultJsonFormatter
.xmlFormatter(DefaultXmlFormatter()) // 指定 XML 格式化器,默认为 DefaultXmlFormatter
.throwableFormatter(DefaultThrowableFormatter()) // 指定可抛出异常格式化器,默认为 DefaultThrowableFormatter
.threadFormatter(DefaultThreadFormatter()) // 指定线程信息格式化器,默认为 DefaultThreadFormatter
.stackTraceFormatter(DefaultStackTraceFormatter()) // 指定调用栈信息格式化器,默认为 DefaultStackTraceFormatter
.borderFormatter(DefaultBorderFormatter()) // 指定边框格式化器,默认为 DefaultBorderFormatter
.build()
val androidPrinter: Printer = AndroidPrinter(true) // 通过 android.util.Log 打印日志的打印器
// val consolePrinter: Printer = ConsolePrinter() // 通过 System.out 打印日志到控制台的打印器
val filePrinter: Printer = FilePrinter.Builder(PathUtils.getLogParent()) // 指定保存日志文件的路径
.fileNameGenerator(DateFileNameGenerator()) // 指定日志文件名生成器,默认为 ChangelessFileNameGenerator("log")
.backupStrategy(NeverBackupStrategy()) // 指定日志文件备份策略,默认为 FileSizeBackupStrategy(1024 * 1024)
.backupStrategy(
FileSizeBackupStrategy2(maxSize, maxBackupIndex)
) // Default: FileSizeBackupStrategy(1024 * 1024)
.cleanStrategy(FileLastModifiedCleanStrategy(maxTimeMillis)) // Default: NeverCleanStrategy(), 7天
.flattener(XLogFlattener()) // 指定日志平铺器,默认为 DefaultFlattener
.build()
XLog.init( // 初始化 XLog
config, // 指定日志配置,如果不指定,会默认使用 new LogConfiguration.Builder().build()
androidPrinter, // 添加任意多的打印器。如果没有添加任何打印器,会默认使用 AndroidPrinter(Android)/ConsolePrinter(java)
filePrinter
)
val header = "\n>>>>>>>>>>>>>>>> File Header >>>>>>>>>>>>>>>>" +
"\nDevice Manufacturer: " + Build.MANUFACTURER +
"\nDevice Brand : " + Build.BRAND +
......@@ -106,15 +46,8 @@ class PosApp : BaseApp() {
}
/**
* 重启当前应用
*/
fun restartApplication() {
val intent = packageManager.getLaunchIntentForPackage(packageName)
intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
Process.killProcess(Process.myPid())
}
}
\ No newline at end of file
package com.ypsx.yppos.app.ext
import android.app.Activity
fun intentFinish(activity: Activity) {
}
\ No newline at end of file
......@@ -2,8 +2,8 @@
package com.ypsx.yppos.http
import com.elvishew.xlog.XLog
import com.ypsx.yppos.utils.dXLog
import com.ypsx.yppos.utils.eXLog
import com.ypsx.base.util.dXLog
import com.ypsx.base.util.eXLog
import okhttp3.*
import okhttp3.internal.http.HttpHeaders
import okio.Buffer
......
......@@ -11,8 +11,8 @@ import org.json.JSONObject
class RetryInterceptor: Interceptor {
val NOT_LOGIN_CODE = 20
val TOKEN_AUTHENTICATION_FAILED = 19
private val NOT_LOGIN_CODE = 20
private val TOKEN_AUTHENTICATION_FAILED = 19
private val CODE = "code"
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
......
......@@ -3,6 +3,8 @@ package com.ypsx.yppos.http.repository.request
import com.ypsx.base.base.appContext
import com.ypsx.base.network.AppException
import com.ypsx.base.util.LogUtils
import com.ypsx.base.util.PathUtils
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.http.data.bean.*
import com.ypsx.yppos.http.data.entity.OrderStatusEnum
......@@ -10,6 +12,7 @@ import com.ypsx.yppos.http.data.entity.PosCommandType
import com.ypsx.yppos.http.data.entity.PosPayMethod
import com.ypsx.yppos.http.data.entity.PosStatus
import com.ypsx.yppos.http.data.request.*
import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.room.database.name
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.room.repository.PosProductRepository
......@@ -28,6 +31,8 @@ class HttpRequestManger {
* 申请注册
*/
suspend fun applyPos(applyPosMachineRequest: ApplyPosMachineRequest): ApiResponse<PosMachineResponse> {
CacheUtil.setUpdateTimeBigger("")
PosDatabase.clearAllTables()
val applyPosData = apiService.applyPos(applyPosMachineRequest)
if (applyPosData.isSuccess()) {
val id = applyPosData.data
......@@ -42,25 +47,23 @@ class HttpRequestManger {
* 注册并登陆
*/
suspend fun getById(id: String): ApiResponse<PosMachineResponse> {
// val current = LocalDateTime.now()
// println("当前日期和时间为: $current")
delay(2000)
val registerData = apiService.getById(id)
//判断注册结果 注册成功,调用登录接口
if (registerData.isSuccess()) {
return if (registerData.isSuccess()) {
val posId = registerData.data.id
val status = registerData.data.status
if (status == PosStatus.APPLY.name) {
delay(2000)
getById(posId)
} else {
LogUtils.debugInfo("status")
return registerData
registerData
}
} else {
throw AppException(registerData.code, registerData.message)
}
//抛出错误异常
throw AppException(registerData.code, registerData.message)
// throw AppException(registerData.code, registerData.message)
}
......@@ -296,7 +299,7 @@ class HttpRequestManger {
val data = productData.data
PosProductRepository.getInstance().insertAll(data)
CacheUtil.setUpdateTimeBigger(todayDateTime)
delay(1000 * 60 )
delay(1000 * 60 * 3)
syncProduct(storeId)
}
}
......
......@@ -10,8 +10,8 @@ import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.room.entity.PosBuy
import com.ypsx.yppos.room.entity.PosBuyPart
import com.ypsx.yppos.room.entity.PosBuyPayment
import com.ypsx.yppos.utils.dXLog
import com.ypsx.yppos.utils.eXLog
import com.ypsx.base.util.dXLog
import com.ypsx.base.util.eXLog
class PosBuyRepository {
......
......@@ -5,7 +5,7 @@ import com.ypsx.yppos.room.dao.PosConfigDao
import com.ypsx.yppos.room.dao.PosProductDao
import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.room.entity.PosProduct
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
class PosProductRepository {
......@@ -23,6 +23,7 @@ class PosProductRepository {
fun insertAll(posProduct: List<PosProduct>) {
"插入数据${posProduct.size}".dXLog()
getPosProductDao().insertList(posProduct)
}
......
......@@ -13,14 +13,15 @@ import com.ypsx.base.network.manager.NetState
import com.ypsx.base.util.RegexUtils
import com.ypsx.yppos.PosApp
import com.ypsx.yppos.R
import com.ypsx.yppos.app.base.BaseActivity
import com.ypsx.yppos.app.ext.startKtxActivityFinish
import com.ypsx.yppos.databinding.ActivityLoginBinding
import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.ui.popup.AppUpdaterPopupWindow
import com.ypsx.yppos.ui.popup.MessagePopupWindow
import com.ypsx.yppos.utils.CacheUtil
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.common.app.base.BaseActivity
import com.ypsx.common.app.ext.showServerHostExt
import com.ypsx.common.app.ext.startKtxActivityFinish
import com.ypsx.yppos.utils.toast
import com.ypsx.yppos.viewmodel.request.RequestLoginViewModel
import com.ypsx.yppos.viewmodel.state.LoginViewModel
......@@ -30,16 +31,9 @@ import com.ypsx.yppos.viewmodel.state.LoginViewModel
*/
class LoginActivity : BaseActivity<LoginViewModel, ActivityLoginBinding>() {
private val requestLoginViewModel: RequestLoginViewModel by viewModels()
private var exitTime: Long = 0
private var clickNum = 1
override fun layoutId(): Int = R.layout.activity_login
private val hostMap = mapOf(
"sit开发环境Host" to "https://sit-cpos.ypshengxian.com/",
"预发Host" to "https://pre-cpos.ypshengxian.com/",
"线上正式Host" to "https://cpos.ypshengxian.com/",
)
private val hosts = hostMap.values.toTypedArray()
private val names = hostMap.keys.toList()
override fun initView(savedInstanceState: Bundle?) {
mDatabind.vm = mViewModel
......@@ -100,47 +94,18 @@ class LoginActivity : BaseActivity<LoginViewModel, ActivityLoginBinding>() {
}
fun combosClick(){
if (System.currentTimeMillis() - exitTime > 2000) {
clickNum = 1
exitTime = System.currentTimeMillis()
} else {
exitTime = System.currentTimeMillis()
clickNum += 1
}
if (clickNum >= 5) {
showServerHostPopWindow()
fun combosClick() {
showServerHostExt(CacheUtil.getHost()) {
CacheUtil.setHost(it)
CacheUtil.clearAll()
PosDatabase.clearAllTables()
PosApp.instance.restartApplication()
}
}
}
private fun showServerHostPopWindow() {
//选中的host
val checkHost = CacheUtil.getHost()
var checkedIndex = hosts.indexOf(checkHost)
if (checkedIndex < 0) checkedIndex = names.size - 1//也就是研发Native那个
//启用输入的host
MaterialDialog(this).title(text = "切换Server接口")
.cancelable(false)
.cancelOnTouchOutside(false)
.listItemsSingleChoice(
items = names,
initialSelection = checkedIndex,
selection = object : SingleChoiceListener {
override fun invoke(dialog: MaterialDialog, index: Int, text: CharSequence) {
//如果选择了研发native,index就会超过host的index
if (index < hosts.size) {
CacheUtil.setHost(hosts[index])
CacheUtil.clearAll()
PosDatabase.clearAllTables()
PosApp.instance.restartApplication()
}
}
})
.positiveButton(text = "确定")
.negativeButton(text = "取消")
.show()
}
override fun createObserver() {
requestLoginViewModel.posDetails.observe(this, {
......@@ -156,6 +121,7 @@ class LoginActivity : BaseActivity<LoginViewModel, ActivityLoginBinding>() {
messagePopupWindow.showPopupWindow()
messagePopupWindow.setData("提示", it.errorMsg, "取消", "确定")
messagePopupWindow.setMessageClick {
messagePopupWindow.dismiss()
val username = mDatabind.etAccount.textStringTrim()
showLoading(getString(R.string.loading))
requestLoginViewModel.posKickOff(username)
......@@ -164,7 +130,7 @@ class LoginActivity : BaseActivity<LoginViewModel, ActivityLoginBinding>() {
it.errorMsg.toast()
}
})
requestLoginViewModel.appVersion.observe(this,{
requestLoginViewModel.appVersion.observe(this, {
val appUpdaterPopupWindow = AppUpdaterPopupWindow(this)
appUpdaterPopupWindow.showPopupWindow()
appUpdaterPopupWindow.setData(it)
......
......@@ -11,11 +11,12 @@ import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.activity.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ypsx.base.ext.view.textStringTrim
import com.ypsx.base.util.RecyclerViewUtil
import com.ypsx.base.util.dXLog
import com.ypsx.common.app.base.BaseActivity
import com.ypsx.common.app.ext.hideKeyboard
import com.ypsx.yppos.R
import com.ypsx.yppos.app.base.BaseActivity
import com.ypsx.yppos.app.ext.hideKeyboard
import com.ypsx.yppos.databinding.ActivityMainBinding
import com.ypsx.yppos.http.data.bean.InsertOrderProductDTO
import com.ypsx.yppos.http.data.bean.OrderActivityResponse
......@@ -158,6 +159,7 @@ class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(),
requestMainViewModel.getKeyWords(barcode)
}
}
mDatabind.ivSettings.clearFocus();
}
......@@ -195,6 +197,7 @@ class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(),
messageDialog.showPopupWindow()
messageDialog.setData("单品删除", "是否取消当前商品", "取消", "确定")
messageDialog.setMessageClick {
messageDialog.dismiss()
var insertOrderProductDTO = orderProductAdapter.data[position]
orderProductAdapter.remove(insertOrderProductDTO)
insertOrderProductDTO.deleted = true
......@@ -369,6 +372,7 @@ class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>(),
messageDialog.showPopupWindow()
messageDialog.setData("支付超时", "请确认是否支付成功", gone = false)
messageDialog.setMessageClick {
messageDialog.dismiss()
mViewModel.resetOrderNo()
productPromotionRequest.orderNo = mViewModel.orderNo.get()
"${realName}点击我知道了,并重置小票号:${productPromotionRequest.orderNo}".dXLog()
......
......@@ -2,22 +2,28 @@ package com.ypsx.yppos.ui.activity
import android.os.Bundle
import androidx.activity.viewModels
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.SingleChoiceListener
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import com.elvishew.xlog.XLog
import com.ypsx.base.ext.util.toJson
import com.ypsx.base.network.manager.NetState
import com.ypsx.base.util.AppUtils
import com.ypsx.base.util.DeviceUtils
import com.ypsx.base.util.LogUtils
import com.ypsx.yppos.PosApp
import com.ypsx.yppos.R
import com.ypsx.yppos.app.base.BaseActivity
import com.ypsx.yppos.app.ext.startKtxActivityFinish
import com.ypsx.yppos.databinding.ActivityRegisterBinding
import com.ypsx.yppos.http.data.entity.PosStatus
import com.ypsx.yppos.http.data.request.ApplyPosMachineRequest
import com.ypsx.yppos.room.database.PosDatabase
import com.ypsx.yppos.ui.popup.MessagePopupWindow
import com.ypsx.yppos.utils.CacheUtil
import com.ypsx.yppos.utils.dXLog
import com.ypsx.yppos.utils.toast
import com.ypsx.base.util.dXLog
import com.ypsx.common.app.base.BaseActivity
import com.ypsx.common.app.ext.getIntent
import com.ypsx.common.app.ext.showServerHostExt
import com.ypsx.common.app.ext.startKtxActivityFinish
import com.ypsx.yppos.viewmodel.request.RequestRegisterViewModel
import com.ypsx.yppos.viewmodel.state.RegisterViewModel
......@@ -25,16 +31,31 @@ import com.ypsx.yppos.viewmodel.state.RegisterViewModel
* 注册页
*/
class RegisterActivity : BaseActivity<RegisterViewModel, ActivityRegisterBinding>() {
private var exitTime: Long = 0
private var clickNum = 1
private val requestMeViewModel: RequestRegisterViewModel by viewModels()
override fun layoutId(): Int = R.layout.activity_register
private val hostMap = mapOf(
"sit开发环境Host" to "https://sit-cpos.ypshengxian.com/",
"预发Host" to "https://pre-cpos.ypshengxian.com/",
"线上正式Host" to "https://cpos.ypshengxian.com/",
)
private val hosts = hostMap.values.toTypedArray()
private val names = hostMap.keys.toList()
override fun initView(savedInstanceState: Bundle?) {
mDatabind.vm = mViewModel
mDatabind.click = ProxyClick()
val state = intent.getBooleanExtra("state", false)
val posId:String? = intent.getStringExtra("posId")
if (state) {
mViewModel.submitState.set(false)
mViewModel.submitText.set("审核中")
requestMeViewModel.getById(posId!!)
}
}
......@@ -66,8 +87,19 @@ class RegisterActivity : BaseActivity<RegisterViewModel, ActivityRegisterBinding
// showLoading("请求网络中...")
requestMeViewModel.applyPos(applyPosMachineRequest)
}
fun combosClick(){
showServerHostExt(CacheUtil.getHost()) {
CacheUtil.setHost(it)
CacheUtil.clearAll()
PosDatabase.clearAllTables()
PosApp.instance.restartApplication()
}
}
}
override fun createObserver() {
requestMeViewModel.posDetails.observe(this, { data ->
val id = data.id
......@@ -91,6 +123,8 @@ class RegisterActivity : BaseActivity<RegisterViewModel, ActivityRegisterBinding
messagePopupWindow.showPopupWindow()
messagePopupWindow.setData("提示", "该POS机已停用,是否将删除本地数据", "取消", "确定", false)
messagePopupWindow.setMessageClick {
messagePopupWindow.dismiss()
CacheUtil.setUpdateTimeBigger("")
CacheUtil.setLoginResponse(null)
}
}
......@@ -121,4 +155,34 @@ class RegisterActivity : BaseActivity<RegisterViewModel, ActivityRegisterBinding
"我特么怎么断网了!".dXLog()
}
}
private fun showServerHostPopWindow() {
//选中的host
val checkHost = CacheUtil.getHost()
var checkedIndex = hosts.indexOf(checkHost)
if (checkedIndex < 0) checkedIndex = names.size - 1//也就是研发Native那个
//启用输入的host
MaterialDialog(this).title(text = "切换Server接口")
.cancelable(false)
.cancelOnTouchOutside(false)
.listItemsSingleChoice(
items = names,
initialSelection = checkedIndex,
selection = object : SingleChoiceListener {
override fun invoke(dialog: MaterialDialog, index: Int, text: CharSequence) {
//如果选择了研发native,index就会超过host的index
if (index < hosts.size) {
CacheUtil.setHost(hosts[index])
CacheUtil.clearAll()
PosDatabase.clearAllTables()
PosApp.instance.restartApplication()
}
}
})
.positiveButton(text = "确定")
.negativeButton(text = "取消")
.show()
}
}
\ No newline at end of file
......@@ -5,24 +5,28 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Process
import android.provider.Settings
import android.view.KeyEvent
import androidx.activity.viewModels
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.base.ext.parseState
import com.ypsx.base.network.manager.NetState
import com.ypsx.yppos.R
import com.ypsx.yppos.app.base.BaseActivity
import com.ypsx.yppos.app.ext.startKtxActivityFinish
import com.ypsx.yppos.databinding.ActivitySplashBinding
import com.ypsx.yppos.http.data.entity.PosStatus
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.ui.popup.MessagePopupWindow
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.common.app.base.BaseActivity
import com.ypsx.common.app.ext.hideKeyboard
import com.ypsx.common.app.ext.startKtxActivity
import com.ypsx.common.app.ext.startKtxActivityFinish
import com.ypsx.yppos.utils.toast
import com.ypsx.yppos.viewmodel.request.RequestSplashViewModel
import kotlin.system.exitProcess
/**
......@@ -36,6 +40,7 @@ class SplashActivity : BaseActivity<BaseViewModel, ActivitySplashBinding>() {
WRITE_EXTERNAL_STORAGE
)
private val requestSplashViewModel: RequestSplashViewModel by viewModels()
private var messagePopupWindow: MessagePopupWindow? = null
// 是否需要系统权限检测
var isRequireCheck = false
......@@ -152,33 +157,107 @@ class SplashActivity : BaseActivity<BaseViewModel, ActivitySplashBinding>() {
override fun createObserver() {
requestSplashViewModel.posDetails.observe(this, { data ->
val status = data.status
requestSplashViewModel.savePosConfig(data)
when (status) {
PosStatus.APPLY.name -> {
// startLogin()
showError("提示", getString(R.string.pos_apply), getString(R.string.see))
}
PosStatus.ACTIVE.name -> {
startLogin()
}
PosStatus.APPLY_FAILED.name -> {
val applyFailedMessage = data.applyFailedMessage
"错误原因:${applyFailedMessage}".dXLog()
showError("提示", getString(R.string.pos_failed), getString(R.string.see))
val status = data.status
requestSplashViewModel.savePosConfig(data)
when (status) {
PosStatus.APPLY.name -> {
val arrayOf = arrayOf(Pair<String, Any>("state", true),Pair<String, Any>("posId", data.id))
startKtxActivity<RegisterActivity>(values = arrayOf)
}
PosStatus.ACTIVE.name -> {
startLogin()
}
PosStatus.APPLY_FAILED.name -> {
val applyFailedMessage = data.applyFailedMessage
"错误原因:${applyFailedMessage}".dXLog()
val messagePopupWindow = MessagePopupWindow(this)
messagePopupWindow.showPopupWindow()
messagePopupWindow.setData(
"提示",
getString(R.string.pos_failed),
sure = getString(R.string.see),
gone = false
)
messagePopupWindow.setMessageClick {
messagePopupWindow.dismiss()
startKtxActivityFinish<RegisterActivity>()
}
PosStatus.DISABLED.name -> {
showError("提示", getString(R.string.pos_disabled), getString(R.string.see))
}
PosStatus.DISABLED.name -> {
val messagePopupWindow = MessagePopupWindow(this)
messagePopupWindow.showPopupWindow()
messagePopupWindow.setData(
"提示",
getString(R.string.pos_disabled),
sure = getString(R.string.see),
gone = false
)
messagePopupWindow.setMessageClick {
messagePopupWindow.dismiss()
startKtxActivityFinish<RegisterActivity>()
}
}
}
})
requestSplashViewModel.posDetails2.observe(this, Observer { data ->
val status = data.status
requestSplashViewModel.savePosConfig(data)
when (status) {
PosStatus.APPLY.name -> {
}
PosStatus.ACTIVE.name -> {
messagePopupWindow!!.dismiss()
startKtxActivityFinish<LoginActivity>()
}
PosStatus.APPLY_FAILED.name -> {
val applyFailedMessage = data.applyFailedMessage
"错误原因:${applyFailedMessage}".dXLog()
startKtxActivityFinish<RegisterActivity>()
// showError("提示", getString(R.string.pos_failed), getString(R.string.see))
}
PosStatus.DISABLED.name -> {
// showError("提示", getString(R.string.pos_disabled), getString(R.string.see))
val messagePopupWindow = MessagePopupWindow(this)
messagePopupWindow.showPopupWindow()
messagePopupWindow.setData(
"提示",
getString(R.string.pos_disabled),
sure = getString(R.string.see),
gone = false
)
messagePopupWindow.setMessageClick {
messagePopupWindow.dismiss()
startKtxActivityFinish<RegisterActivity>()
}
}
}
})
}
private fun startLogin() {
startKtxActivityFinish<LoginActivity>()
// startActivity(Intent(this, LoginActivity::class.java))
// finish()
}
private var exitTime: Long = 0
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((System.currentTimeMillis() - exitTime) > 2000) {
"再按一次退出程序".toast()
exitTime = System.currentTimeMillis()
} else {
this.finish()
exitProcess(0)
Process.killProcess(Process.myPid())
}
return true
}
return super.onKeyDown(keyCode, event)
}
private fun showError(title: String, content: String, sure: String) {
......
......@@ -13,7 +13,7 @@ import com.ypsx.yppos.utils.toast
import com.ypsx.yppos.R
import com.ypsx.yppos.databinding.PopupAppUpdaterBinding
import com.ypsx.yppos.http.data.bean.AppVersionResponse
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.viewmodel.state.AppUpdaterViewModel
import razerdp.basepopup.BasePopupWindow
import java.io.File
......
......@@ -21,6 +21,7 @@ class MessagePopupWindow(context: Context) : BasePopupWindow(context) {
popupGravity = Gravity.CENTER
isOutSideTouchable = false
setOutSideDismiss(false)
setBackPressEnable(false)
}
override fun onViewCreated(contentView: View) {
......@@ -50,14 +51,10 @@ class MessagePopupWindow(context: Context) : BasePopupWindow(context) {
inner class ProxyClick {
fun cancel() {
dismiss()
// listener?.cancel()
}
fun sure() {
dismiss()
messageAction.invoke()
// listener?.sure()
}
}
......
......@@ -8,7 +8,7 @@ import com.ypsx.yppos.R
import com.ypsx.yppos.databinding.PopupOfferDetailsBinding
import com.ypsx.yppos.databinding.PopupSettingsBinding
import com.ypsx.yppos.utils.CacheUtil
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.viewmodel.state.OfferDetailsViewModel
import com.ypsx.yppos.viewmodel.state.SettingsViewModel
import razerdp.basepopup.BasePopupWindow
......
......@@ -9,7 +9,7 @@ import com.ypsx.yppos.databinding.PopupOrderPayAmountBinding
import com.ypsx.yppos.http.data.entity.PosPayMethod
import com.ypsx.yppos.room.entity.PosConfig
import com.ypsx.yppos.utils.CacheUtil
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.viewmodel.state.OrderPayAmountViewModel
import razerdp.basepopup.BasePopupWindow
import razerdp.util.animation.AnimationHelper
......
......@@ -11,7 +11,7 @@ import com.ypsx.yppos.R
import com.ypsx.yppos.databinding.PopupPayAmountBinding
import com.ypsx.yppos.http.data.entity.PosPayMethod
import com.ypsx.yppos.utils.CacheUtil
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.viewmodel.state.PayAmountViewModel
import razerdp.basepopup.BasePopupWindow
import razerdp.util.animation.AnimationHelper
......
......@@ -6,8 +6,9 @@ import android.view.View
import android.view.animation.Animation
import com.ypsx.base.base.appContext
import com.ypsx.base.ext.util.screenWidth
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.R
import com.ypsx.yppos.app.ext.startKtxActivityFinish
import com.ypsx.common.app.ext.startKtxActivityFinish
import com.ypsx.yppos.databinding.PopupSettingsBinding
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.room.repository.PosBuyRepository
......
......@@ -7,6 +7,7 @@ import com.elvishew.xlog.XLog
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.ypsx.base.ext.util.toJson
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.http.data.bean.ActivityInfoDTO
import com.ypsx.yppos.http.data.bean.OrderActivityResponse
import com.ypsx.yppos.http.data.bean.OrderDetailsResponse
......
......@@ -5,7 +5,6 @@ import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.base.ext.request
import com.ypsx.base.ext.requestNoCheck
import com.ypsx.base.ext.util.loge
import com.ypsx.yppos.utils.toast
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.http.data.bean.AppVersionResponse
import com.ypsx.yppos.http.data.bean.LoginResponse
......@@ -13,7 +12,7 @@ import com.ypsx.yppos.http.data.request.KickoffRequest
import com.ypsx.yppos.http.repository.request.HttpRequestCoroutine
import com.ypsx.yppos.http.state.UpdateUiState
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.utils.dXLog
import com.ypsx.base.util.dXLog
class RequestLoginViewModel : BaseViewModel() {
var posDetails = MutableLiveData<UpdateUiState<LoginResponse>>()
......
......@@ -8,6 +8,7 @@ import com.ypsx.base.ext.request
import com.ypsx.base.ext.requestNoCheck
import com.ypsx.base.ext.util.toJson
import com.ypsx.base.network.AppException
import com.ypsx.base.util.dXLog
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.http.data.bean.*
import com.ypsx.yppos.http.data.entity.PosPayMethod
......
......@@ -10,8 +10,7 @@ import com.ypsx.yppos.http.data.bean.PosMachineResponse
import com.ypsx.yppos.http.data.request.ApplyPosMachineRequest
import com.ypsx.yppos.http.repository.request.HttpRequestCoroutine
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.utils.dXLog
import com.ypsx.yppos.utils.eXLog
import com.ypsx.base.util.eXLog
class RequestRegisterViewModel : BaseViewModel() {
var posDetails = MutableLiveData<PosMachineResponse>()
......
......@@ -5,30 +5,33 @@ import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.base.ext.launch
import com.ypsx.base.ext.request
import com.ypsx.base.ext.util.loge
import com.ypsx.base.state.ResultState
import com.ypsx.base.util.dXLog
import com.ypsx.base.util.eXLog
import com.ypsx.yppos.http.apiService
import com.ypsx.yppos.http.data.bean.PosMachineResponse
import com.ypsx.yppos.http.repository.request.HttpRequestCoroutine
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.utils.dXLog
import com.ypsx.yppos.utils.eXLog
import com.ypsx.yppos.utils.toast
class RequestSplashViewModel : BaseViewModel() {
var posDetails = MutableLiveData<PosMachineResponse>()
var posDetails2 = MutableLiveData<PosMachineResponse>()
fun getById(id: String) {
request({ apiService.getById(id) },{
request({ apiService.getById(id) }, {
posDetails.postValue(it)
} ,{
}, {
it.errorMsg.loge()
it.errorMsg.toast()
},true)
}, true)
}
fun savePosConfig(posMachineResponse: PosMachineResponse) {
launch({ PosConfigRepository.getInstance().savePosDetail(posMachineResponse)},{
launch({ PosConfigRepository.getInstance().savePosDetail(posMachineResponse) }, {
"保存数据库PosConfig成功".dXLog()
},{
}, {
"保存数据库PosConfig失败".eXLog()
})
}
......
......@@ -8,7 +8,6 @@ import com.ypsx.base.callback.databind.BooleanObservableField
import com.ypsx.base.callback.databind.StringObservableField
import com.ypsx.yppos.http.data.entity.PosPayMethod
import com.ypsx.yppos.room.repository.PosConfigRepository
import com.ypsx.yppos.utils.dXLog
import kotlinx.coroutines.launch
class OrderPayAmountViewModel : BaseViewModel() {
......
......@@ -45,6 +45,7 @@
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->click.combosClick()}"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="@+id/guideline4"
......
......@@ -8,7 +8,7 @@
<string name="loading">请求网络中…</string>
<string name="pos_apply">该POS机已在申请中,请耐心等待!</string>
<string name="pos_failed">您的审核未通过,请重新提交!</string>
<string name="pos_disabled">该POS机已禁用,请联系店长</string>
<string name="pos_disabled">该POS机已禁用,请联系管理员</string>
<string name="see">我知道了</string>
<string name="account">账号</string>
<string name="password">密码</string>
......
......@@ -72,5 +72,7 @@ dependencies {
api 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
//动态替换BaseUrl库 使用可参考 https://github.com/JessYanCoding/RetrofitUrlManager
api 'me.jessyan:retrofit-url-manager:1.4.0'
api 'com.tencent:mmkv:1.2.10'
api 'com.elvishew:xlog:1.10.1'
}
\ No newline at end of file
package com.ypsx.base.base
import android.app.Application
import android.content.Intent
import android.os.Build
import android.os.Process
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
import com.elvishew.xlog.formatter.border.DefaultBorderFormatter
import com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter
import com.elvishew.xlog.formatter.message.throwable.DefaultThrowableFormatter
import com.elvishew.xlog.formatter.message.xml.DefaultXmlFormatter
import com.elvishew.xlog.formatter.stacktrace.DefaultStackTraceFormatter
import com.elvishew.xlog.formatter.thread.DefaultThreadFormatter
import com.elvishew.xlog.printer.AndroidPrinter
import com.elvishew.xlog.printer.Printer
import com.elvishew.xlog.printer.file.FilePrinter
import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy2
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
import com.tencent.mmkv.MMKV
import com.ypsx.base.R
import com.ypsx.base.util.PathUtils
import com.ypsx.base.util.XLogFlattener
/**
* 作者 : hegaojian
......@@ -16,6 +39,10 @@ import androidx.lifecycle.ViewModelStoreOwner
open class BaseApp : Application(), ViewModelStoreOwner {
private val maxSize: Long = 1024 * 1024 * 50
private val maxTimeMillis: Long = 1000 * 60 * 60 * 24 * 30
private val maxBackupIndex: Int = 10
private lateinit var mAppViewModelStore: ViewModelStore
private var mFactory: ViewModelProvider.Factory? = null
......@@ -26,8 +53,10 @@ open class BaseApp : Application(), ViewModelStoreOwner {
override fun onCreate() {
super.onCreate()
MMKV.initialize(this)
mAppViewModelStore = ViewModelStore()
initXlog()
}
/**
......@@ -43,4 +72,54 @@ open class BaseApp : Application(), ViewModelStoreOwner {
}
return mFactory as ViewModelProvider.Factory
}
private fun initXlog() {
val config = LogConfiguration.Builder()
.logLevel(LogLevel.ALL)// 指定日志级别,低于该级别的日志将不会被打印,默认为 LogLevel.ALL
.tag(getString(R.string.global_tag)) // 指定 TAG,默认为 "X-LOG"
.enableThreadInfo() // 允许打印线程信息,默认禁止
.enableStackTrace(2) // 允许打印深度为 2 的调用栈信息,默认禁止
.enableBorder() // 允许打印日志边框,默认禁止
.jsonFormatter(DefaultJsonFormatter()) // 指定 JSON 格式化器,默认为 DefaultJsonFormatter
.xmlFormatter(DefaultXmlFormatter()) // 指定 XML 格式化器,默认为 DefaultXmlFormatter
.throwableFormatter(DefaultThrowableFormatter()) // 指定可抛出异常格式化器,默认为 DefaultThrowableFormatter
.threadFormatter(DefaultThreadFormatter()) // 指定线程信息格式化器,默认为 DefaultThreadFormatter
.stackTraceFormatter(DefaultStackTraceFormatter()) // 指定调用栈信息格式化器,默认为 DefaultStackTraceFormatter
.borderFormatter(DefaultBorderFormatter()) // 指定边框格式化器,默认为 DefaultBorderFormatter
.build()
val androidPrinter: Printer = AndroidPrinter(true) // 通过 android.util.Log 打印日志的打印器
// val consolePrinter: Printer = ConsolePrinter() // 通过 System.out 打印日志到控制台的打印器
val filePrinter: Printer = FilePrinter.Builder(PathUtils.getLogParent()) // 指定保存日志文件的路径
.fileNameGenerator(DateFileNameGenerator()) // 指定日志文件名生成器,默认为 ChangelessFileNameGenerator("log")
.backupStrategy(NeverBackupStrategy()) // 指定日志文件备份策略,默认为 FileSizeBackupStrategy(1024 * 1024)
.backupStrategy(
FileSizeBackupStrategy2(maxSize, maxBackupIndex)
) // Default: FileSizeBackupStrategy(1024 * 1024)
.cleanStrategy(FileLastModifiedCleanStrategy(maxTimeMillis)) // Default: NeverCleanStrategy(), 7天
.flattener(XLogFlattener()) // 指定日志平铺器,默认为 DefaultFlattener
.build()
XLog.init( // 初始化 XLog
config, // 指定日志配置,如果不指定,会默认使用 new LogConfiguration.Builder().build()
androidPrinter, // 添加任意多的打印器。如果没有添加任何打印器,会默认使用 AndroidPrinter(Android)/ConsolePrinter(java)
filePrinter
)
}
/**
* 重启当前应用
*/
fun restartApplication() {
val intent = packageManager.getLaunchIntentForPackage(packageName)
intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)
Process.killProcess(Process.myPid())
}
}
\ No newline at end of file
package com.ypsx.yppos.utils
package com.ypsx.base.util
import android.os.Environment
import com.ypsx.base.base.appContext
......
package com.ypsx.yppos.utils
package com.ypsx.base.util
import androidx.recyclerview.widget.RecyclerView
......
package com.ypsx.yppos.utils
package com.ypsx.base.util
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.flattener.Flattener2
import java.text.SimpleDateFormat
import java.util.*
class XLogFlattener: Flattener2 {
class XLogFlattener : Flattener2 {
private val DATE_FORMATTER = "yyyy-MM-dd HH:mm:ss.SSS"
private val sdf = SimpleDateFormat(DATE_FORMATTER, Locale.CHINA)
override fun flatten(
timeMillis: Long,
logLevel: Int,
tag: String?,
message: String?
): CharSequence {
return (DateUtil.getLogTime(timeMillis)
val date = Date(timeMillis)
return (sdf.format(date)
+ '|' + LogLevel.getShortLevelName(logLevel)
+ '|' + tag
+ '|' + message)
......
package com.ypsx.yppos.utils
package com.ypsx.base.util
import com.elvishew.xlog.XLog
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="global_tag">YPPOS</string>
</resources>
\ No newline at end of file
......@@ -2,37 +2,35 @@
buildscript {
ext.kotlin_version = "1.5.20"
repositories {
google()
jcenter()
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url "https://jitpack.io" }
mavenCentral()
maven {
url 'https://jitpack.io'
}
maven { url 'https://maven.google.com' }
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url "https://jitpack.io" }
mavenCentral()
maven {
url 'https://jitpack.io'
}
maven { url 'https://maven.google.com' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
kotlin_version = "1.5.20"
core_ktx_version = "1.3.2"
appcompat_version = "1.3.0"
material_version = "1.2.1"
}
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.00.000"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$rootProject.kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
api project(path: ':base')
api "com.afollestad.material-dialogs:lifecycle:3.3.0"
api "com.afollestad.material-dialogs:core:3.3.0"
testImplementation 'junit:junit:4.+'
}
\ No newline at end of file
# 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
\ No newline at end of file
package com.ypsx.common
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext
assertEquals("com.ypsx.common.test", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ypsx.common">
</manifest>
\ No newline at end of file
package com.ypsx.yppos.app.base
package com.ypsx.common.app.base
import android.os.Bundle
import androidx.databinding.ViewDataBinding
import com.ypsx.base.base.activity.BaseVmDbActivity
import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.yppos.app.ext.dismissLoadingExt
import com.ypsx.yppos.app.ext.showLoadingExt
import com.ypsx.common.app.ext.dismissLoadingExt
import com.ypsx.common.app.ext.showLoadingExt
/**
* 时间 : 2019/12/21
......
package com.ypsx.yppos.app.base
package com.ypsx.common.app.base
import android.os.Bundle
import androidx.databinding.ViewDataBinding
import com.ypsx.base.base.fragment.BaseVmDbFragment
import com.ypsx.base.base.viewmodel.BaseViewModel
import com.ypsx.yppos.app.ext.dismissLoadingExt
import com.ypsx.yppos.app.ext.hideSoftKeyboard
import com.ypsx.yppos.app.ext.showLoadingExt
import com.ypsx.common.app.ext.dismissLoadingExt
import com.ypsx.common.app.ext.hideSoftKeyboard
import com.ypsx.common.app.ext.showLoadingExt
/**
* 作者 : hegaojian
......
package com.ypsx.yppos.app.event
package com.ypsx.common.app.event
import com.ypsx.base.base.viewmodel.BaseViewModel
......
package com.ypsx.yppos.app.event
package com.ypsx.common.app.event
import com.ypsx.base.base.viewmodel.BaseViewModel
......
package com.ypsx.yppos.app.ext
package com.ypsx.common.app.ext
import android.app.Activity
import android.content.Context
......
package com.ypsx.yppos.app.ext
package com.ypsx.common.app.ext
import android.app.Activity
import android.view.inputmethod.InputMethodManager
......
package com.ypsx.yppos.app.ext
package com.ypsx.common.app.ext
import android.app.Activity
import android.widget.TextView
......@@ -8,7 +8,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.ypsx.yppos.R
import com.ypsx.common.R
/**
* @author : hgj
......@@ -73,3 +73,8 @@ fun Fragment.dismissLoadingExt() {
loadingDialog?.dismiss()
loadingDialog = null
}
fun AppCompatActivity.showServerHostExt(message: String) {
}
package com.ypsx.common.app.ext
import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.SingleChoiceListener
import com.afollestad.materialdialogs.list.listItemsSingleChoice
private var exitTime: Long = 0
private var clickNum = 1
private val hostMap = mapOf(
"sit开发环境Host" to "https://sit-cpos.ypshengxian.com/",
"预发Host" to "https://pre-cpos.ypshengxian.com/",
"线上正式Host" to "https://cpos.ypshengxian.com/",
)
private val hosts = hostMap.values.toTypedArray()
private val names = hostMap.keys.toList()
private var materialDialog: MaterialDialog? = null
fun AppCompatActivity.showServerHostExt(host:String,success: (String) -> Unit) {
if (!this.isFinishing) {
if (System.currentTimeMillis() - exitTime > 2000) {
clickNum = 1
exitTime = System.currentTimeMillis()
} else {
exitTime = System.currentTimeMillis()
clickNum += 1
}
if (clickNum >= 5) {
//选中的host
val checkHost = host
var checkedIndex = hosts.indexOf(checkHost)
if (checkedIndex < 0) checkedIndex = names.size - 1//也就是研发Native那个
//启用输入的host
if (materialDialog != null) {
if (materialDialog!!.isShowing) {
materialDialog!!.dismiss()
materialDialog = null
}
}
materialDialog = MaterialDialog(this).title(text = "切换Server接口")
.cancelable(false)
.cancelOnTouchOutside(false)
.listItemsSingleChoice(
items = names,
initialSelection = checkedIndex,
selection = object : SingleChoiceListener {
override fun invoke(
dialog: MaterialDialog,
index: Int,
text: CharSequence
) {
//如果选择了研发native,index就会超过host的index
if (index < hosts.size) {
success(hosts[index])
}
}
})
.positiveButton(text = "确定")
.negativeButton(text = "取消")
materialDialog!!.show()
}
}
}
fun showServerHostPopWindow() {
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:indeterminateTint="@color/purple_700"
android:indeterminateTintMode="src_atop" />
<TextView
android:id="@+id/loading_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="请求网络中..."
android:textColor="#666"
android:textSize="16dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutview xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayoutview>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="black_333">#FF333333</color>
<color name="white">#FFFFFFFF</color>
<color name="purple_200">#ffa14eff</color>
<color name="purple_500">#ffa14eff</color>
<color name="purple_700">#ffa14eff</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
</resources>
\ No newline at end of file
package com.ypsx.common
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)
}
}
\ No newline at end of file
// 统一版本控制
ext{
version = [
junitVersion : "4.12",
]
var = [
junit : "junit:junit:$version.junitVersion",
]
}
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation project(path: ':common')
}
\ No newline at end of file
# 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
\ No newline at end of file
package com.ypsx.http
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext
assertEquals("com.ypsx.http.test", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ypsx.http">
</manifest>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.ypsx.self_yppos"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
\ No newline at end of file
# 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
\ No newline at end of file
package com.ypsx.self_yppos
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext
assertEquals("com.ypsx.self_yppos", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ypsx.self_yppos">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.YPPos">
<activity android:name=".ui.activity.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.activity.MainActivity">
</activity>
</application>
</manifest>
\ No newline at end of file
package com.ypsx.self_yppos.ui.activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.ypsx.self_yppos.R
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
\ No newline at end of file
package com.ypsx.self_yppos.ui.activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.ypsx.self_yppos.R
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<?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"
tools:context=".ui.activity.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?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"
tools:context=".ui.activity.SplashActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
This diff is collapsed.
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.YPPos" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">self_yppos</string>
</resources>
\ No newline at end of file
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.YPPos" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
package com.ypsx.self_yppos
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)
}
}
\ No newline at end of file
rootProject.name = "YPPos"
include ':app'
include ':base'
include ':self_yppos'
include ':http'
include ':common'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment