Commit 1ccbc004 authored by p x's avatar p x
Browse files

first

parent 032ec619
Pipeline #3090 failed with stages
in 0 seconds
*.iml
.gradle
.idea
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
/build
\ No newline at end of file
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
id("dagger.hilt.android.plugin")
id("kotlin-kapt")
}
android {
namespace = "com.sd.cavphmi"
compileSdk = 35
defaultConfig {
applicationId = "com.sd.cavphmi"
minSdk = 29
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
dataBinding = true
}
lint {
abortOnError=false
checkReleaseBuilds=false
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs","include" to listOf("*.jar", "*.aar"))))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
// Hilt dependencies
val hilt_version = "2.56.1"
implementation("com.google.dagger:hilt-android:$hilt_version")
kapt("com.google.dagger:hilt-android-compiler:${hilt_version}")
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
//fragment-ktx
implementation("androidx.fragment:fragment-ktx:1.8.0")
// 权限请求框架
implementation("com.guolindev.permissionx:permissionx:1.8.1")
//加密库
implementation("androidx.security:security-crypto:1.0.0")
implementation("com.gyf.immersionbar:immersionbar:2.3.3-beta15")
//网络
implementation("io.reactivex.rxjava3:rxjava:3.0.8")
implementation("io.reactivex.rxjava3:rxandroid:3.0.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
implementation("com.squareup.retrofit2:converter-scalars:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.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.sd.cavphmi
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.sd.cavphmi", 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"
xmlns:tools="http://schemas.android.com/tools">
<!-- 打开关闭sdcard的权限 -->
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
tools:ignore="ProtectedPermissions" />
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许程序访问网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 允许用户改变WiFi连接状态 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 程序访问粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 允许用户访问精确位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Android Q 允许后台运行定位 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- 允许程序读取手机状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 打电话的权限 -->
<!-- <uses-permission android:name="android.permission.CALL_PHONE" />-->
<!-- 从SDCard读出数据权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 允许程序写入外部存储设备 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许程序读取所有者数据 -->
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<!-- 访问WiFi状态,需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 访问网络的变化, 需要某些信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 8.0 安装未知程序权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".MyAppcation"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SuZhouAvp"
tools:targetApi="31">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<meta-data
android:name="com.minedata.minenavi.apikey"
android:value="57ac7a0d56494912a0c28e651fa4a40a" />
<!-- android:screenOrientation="userLandscape"-->
<activity
android:name=".ui.BootActivity"
android:exported="true"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:launchMode="singleTask">
</activity>
</application>
</manifest>
\ No newline at end of file
package com.sd.cavphmi
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyAppcation : Application() {
companion object {
private lateinit var instance: MyAppcation
fun instance(): MyAppcation = instance
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
\ No newline at end of file
package com.sd.cavphmi.base
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.sd.cavphmi.R
import com.sd.cavphmi.databinding.ActivityBaseBinding
import com.sd.cavphmi.net.NetLoadStatus
import com.sd.cavphmi.utils.ToastHelper
//import com.gyf.immersionbar.ImmersionBar
abstract class BaseActivity<Bind : ViewDataBinding, VM : MyBaseViewModel> : AppCompatActivity(),
IBinding<VM> {
protected lateinit var viewModel: VM
protected lateinit var binding: Bind
private lateinit var baseBind: ActivityBaseBinding
// private val loadDialogFragment by lazy { LoadDialogFragment.newInstance() }
// private var loadDialogFragment: LoadDialogFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initDataBinding()
baseBind =
DataBindingUtil.setContentView(this, R.layout.activity_base)
setContentView(baseBind.root)
setSupportActionBar(baseBind.toolbar)
baseBind.toolbar.visibility = View.GONE
supportActionBar?.run {
setDisplayShowTitleEnabled(false)
setDisplayHomeAsUpEnabled(true)
// setHomeAsUpIndicator()
}
baseBind.rootLayout.addView(binding.root)
baseBind.toolbarTitle.text = title.toString()
// viewModel.owner=this
initView()
initStatuBar()
setListener()
// requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
initListener()
getToData()
}
// private lateinit var bar: ImmersionBar
/**
* 初始化状态栏
*/
private fun initStatuBar() {
// var color = getStatuBarColor()
// if (color == -1) {
//
// } else {
// bar = ImmersionBar.with(this)
// .fitsSystemWindows(true)
// .statusBarColor(color)
// .autoStatusBarDarkModeEnable(isAutoStatusBarDarkModeEnable())
// bar.init()
// }
}
abstract fun getStatuBarColor(): Int
open fun isAutoStatusBarDarkModeEnable(): Boolean {
return true
}
private fun initDataBinding() {
binding = DataBindingUtil.setContentView(this, initContentView())
viewModel = initViewModel()
if (viewModel == null) {
viewModel = ViewModelProvider(this).get(MyBaseViewModel::class.java) as VM
}
binding.setVariable(initVariableId(), viewModel)
}
private fun setListener() {
viewModel.loadStatu.observe(this, Observer { t: NetLoadStatus ->
when (t) {
NetLoadStatus.LOADING -> loading()
NetLoadStatus.SUCCESS -> success()
NetLoadStatus.ERROR -> onError(t.getErrorMsg())
NetLoadStatus.TOAST -> onToast(t.getToastMsg())
NetLoadStatus.COMPLETE -> complete()
NetLoadStatus.EMPTY -> empty()
NetLoadStatus.NOMOREDATA -> noMoreData()
NetLoadStatus.LOGINTIMEOUT -> loginTimeOut()
}
})
}
fun setTootBarTitle(title: String) {
baseBind.toolbarTitle.text = title
}
fun setTootBarTitleColor(color: Int) {
baseBind.toolbarTitle.setTextColor(ContextCompat.getColor(this, color))
}
/**
* 设置头的颜色
*/
fun setToorbarColor(toolbar: Int) {
baseBind.toolbar.setBackgroundResource(toolbar)
}
/**
*设置返回箭头
*/
fun setBackImg(@DrawableRes resId: Int) {
supportActionBar?.setHomeAsUpIndicator(resId)
}
abstract fun initView()
open fun initListener() {
}
open fun getToData() {
}
open fun loading() {
// loadDialogFragment = LoadDialogFragment.newInstance()
// loadDialogFragment?.show(supportFragmentManager, "")
}
open fun success() {
// loadDialogFragment?.dismiss()
}
open fun complete() {
// loadDialogFragment?.dismiss()
}
open fun onError(msg: String) {
// loadDialogFragment?.dismiss()
ToastHelper.showShort(this, msg)
}
open fun onToast(msg: String) {
ToastHelper.showShort(this, msg)
}
open fun empty() {
}
open fun noMoreData() {
}
open fun loginTimeOut() {
// println("-------------BaseActivity.loginTimeOut")
ToastHelper.showShort(this, "登录超时")
// startActivity(Intent(this, LoginActivity::class.java).apply {
// putExtra(MyContants.IS_LOGIN_TIMEOUT, true)
// })
}
protected fun hideToolBar() {
baseBind.toolbar.visibility = View.GONE
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
finish()
return true
}
else -> {
return onClickOptions(item)
}
}
return super.onOptionsItemSelected(item)
}
open fun onClickOptions(item: MenuItem): Boolean {
return super.onOptionsItemSelected(item)
}
// fun jumpActivity(cls: Class<Activity>,parameMap:Map<String,String>) {
// var intent = Intent(this, cls)
// for ((k,v) in parameMap){
// intent.putExtra(k,v)
// }
// }
}
\ No newline at end of file
package com.sd.cavphmi.base
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.sd.cavphmi.utils.SystemUtils
open class BaseDialogFrament : DialogFragment() {
override fun onStart() {
super.onStart()
// var window = dialog?.window
// window?.setBackgroundDrawableResource(R.color.trans)
// setWidth()
}
/**
* 设置对话款高度
*/
fun setWidth(widthPer: Float = 0.8f) {
var dialogWidth = SystemUtils.getScreenWidth().times(widthPer).toInt()
dialog?.window?.setLayout(dialogWidth, ViewGroup.LayoutParams.WRAP_CONTENT)
}
}
\ No newline at end of file
package com.sd.cavphmi.base
import android.app.ProgressDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.sd.cavphmi.net.NetLoadStatus
import com.sd.cavphmi.utils.ToastHelper
//import com.gyf.immersionbar.ImmersionBar
//import com.gyf.immersionbar.components.ImmersionFragment
open abstract class BaseFragment<Bind : ViewDataBinding, VM : MyBaseViewModel> :
Fragment(),
IBinding<VM> {
protected lateinit var viewModel: VM
protected lateinit var binding: Bind
// private var loadDialogFragment: LoadDialogFragment? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
initDataBinding(container)
return binding.root
}
// override fun initImmersionBar() {
// initStatuBar()
// }
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setListener()
initView()
initListener()
getToData()
}
private fun initDataBinding(viewGroup: ViewGroup?) {
binding = DataBindingUtil.inflate(layoutInflater, initContentView(), viewGroup, false)
viewModel = initViewModel()
binding.setVariable(initVariableId(), viewModel)
}
// private lateinit var bar: ImmersionBar
/**
* 初始化状态栏
*/
// private fun initStatuBar() {
// var color = getStatuBarColor()
// if (color == -1) {
//
// } else {
// bar = ImmersionBar.with(this)
// .fitsSystemWindows(true)
// .statusBarColor(color)
// .autoStatusBarDarkModeEnable(isAutoStatusBarDarkModeEnable())
// bar.init()
// }
//
// }
abstract fun getStatuBarColor(): Int
open fun isAutoStatusBarDarkModeEnable(): Boolean {
return true
}
abstract fun initView()
private fun setListener() {
viewModel.loadStatu.observe(viewLifecycleOwner, Observer { t: NetLoadStatus ->
netLoad(t)
})
}
private fun netLoad(t: NetLoadStatus) {
when (t) {
NetLoadStatus.LOADING -> loading()
NetLoadStatus.SUCCESS -> success()
NetLoadStatus.ERROR -> onerror(t.getErrorMsg())
NetLoadStatus.TOAST -> onToast(t.getToastMsg())
NetLoadStatus.COMPLETE -> complete()
NetLoadStatus.EMPTY -> empty()
NetLoadStatus.LOGINTIMEOUT -> loginOutTime()
NetLoadStatus.NOMOREDATA -> TODO()
}
}
open fun initListener() {
}
open fun getToData() {
}
open fun loading() {
// loadDialogFragment?.dismiss()
// loadDialogFragment = LoadDialogFragment.newInstance("")
// loadDialogFragment?.show(childFragmentManager, "")
}
open fun success() {
// loadDialogFragment?.dismiss()
}
open fun onerror(msg: String) {
// loadDialogFragment?.dismiss()
if (!msg.isNullOrEmpty()) {
// ToastHelper.showShort(requireContext(), msg)
}
}
open fun onToast(msg: String) {
// ToastHelper.showShort(requireContext(), msg)
}
open fun complete() {
// loadDialogFragment?.dismiss()
}
open fun empty() {
}
open fun loginOutTime() {
// LogUtil.e("----------------登录超时")
ToastHelper.showShort(requireContext(), "登录超时")
// startActivity(Intent(context, LoginActivity::class.java).apply {
// putExtra(MyContants.IS_LOGIN_TIMEOUT, true)
// })
}
fun setOtherViewModel(viewModel: OtherBaseViewModel) {
viewModel.loadStatu.observe(viewLifecycleOwner, {
netLoad(it)
})
}
// fun setThridViewModel(viewModel: MyBaseViewModel) {
// viewModel.loadStatu.observe(this, {
// netLoad(it)
// })
// }
private var myDialog: ProgressDialog? = null
/**
* 加载等待
*/
fun showProgressDialog(tip:String="正在加载") {
myDialog = ProgressDialog(requireContext())
myDialog!!.setProgressStyle(ProgressDialog.STYLE_SPINNER)
myDialog!!.setMessage(tip)
myDialog!!.setIndeterminate(false)
myDialog!!.setCancelable(true)
myDialog!!.show()
}
fun disDiaLog() {
myDialog?.dismiss()
}
}
\ No newline at end of file
package com.sd.cavphmi.base
interface IBinding<VM : MyBaseViewModel> {
/**
* 当期视图
*/
fun initContentView(): Int
/**
* 当期ViewModel 类型
*/
fun initViewModel(): VM
/**
* 初始化ViewModel的id
*
* @return layout 里BR的id
*/
fun initVariableId(): Int
}
\ No newline at end of file
package com.sd.cavphmi.base
//import javax.inject.Inject
open class MyBaseRepository {
// constructor()
// constructor(var onDataCallback: OnDataCallback<*>) : this()
// @Inject lateinit var onDataCallback: OnDataCallback<Any>
//
// init {
// this.onDataCallback = onDataCallback
// }
}
\ No newline at end of file
package com.sd.cavphmi.base
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.sd.cavphmi.net.NetLoadStatus
open class MyBaseViewModel : ViewModel() {
var totalPage = 1
var pages = 1
var limit = 20
var loadStatu = MutableLiveData<NetLoadStatus>()
var owner: LifecycleOwner? = null
}
package com.sd.cavphmi.base
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.sd.cavphmi.net.NetLoadStatus
open class OtherBaseViewModel : ViewModel() {
var totalPage = 1
var pages = 1
var limit = 20
var loadStatu = MutableLiveData<NetLoadStatus>()
}
package com.sd.cavphmi.net
import com.google.gson.JsonSyntaxException
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import retrofit2.HttpException
import java.net.SocketTimeoutException
abstract class MyBaseObserver<T> : Observer<MyBaseResource<T>> {
override fun onSubscribe(d: Disposable) {
// ToastHelper.showShort(context, "onSubscribe")
}
override fun onNext(t: MyBaseResource<T>) {
// onSuccess(t?.data ?: "" as T)
when (t?.code) {
200 -> onSuccess(t?.data ?: "" as T)
4001 -> loginTimeout()
else -> {
onFailed(t?.msg ?: "error")
}
}
}
override fun onError(e: Throwable) {
when (e) {
is HttpException -> {
// var body = e.response().errorBody()?.string() ?: "error"
onFailed(e.message.toString())
}
is JsonSyntaxException -> {
// onFailed("数据异常js")
e?.printStackTrace()
onFailed("0x00000001")
}
is SocketTimeoutException -> {
onFailed("Time Out")
}
else -> {
println(" -------------其他异常")
e?.printStackTrace()
onFailed(e?.message ?: "")
}
}
}
override fun onComplete() {
}
protected abstract fun loginTimeout()
protected abstract fun onSuccess(t: T)
protected abstract fun onFailed(error: String)
}
\ No newline at end of file
package com.sd.cavphmi.net
/**
* A generic class that holds a value with its loading status.
* @param <T>
</T> */
data class MyBaseResource<out T>(val data: T, var code: Int,var msg: String) {
// companion object {
// fun <T> success(data: T?): BaseResource<T> {
// return BaseResource(data, null)
// }
//
// fun <T> error(msg: String, data: T?): BaseResource<T> {
// return BaseResource(data, msg)
// }
//
// fun <T> loading(data: T?): BaseResource<T> {
// return BaseResource(data, null)
// }
// }
}
package com.sd.cavphmi.net
/**
* Status of a resource that is provided to the UI.
*
*
* These are usually created by the Repository classes where they return
* `LiveData<Resource<T>>` to pass back the latest data to the UI with its fetch status.
*/
enum class NetLoadStatus {
SUCCESS,
ERROR,
TOAST,
LOADING,
COMPLETE,
EMPTY,
NOMOREDATA,
LOGINTIMEOUT;//登录超时
private var errorMsg = ""
private var toastMsg = ""
fun setErrorMsg(error: String) {
errorMsg = error
}
fun getErrorMsg(): String {
return errorMsg
}
fun getToastMsg(): String {
return toastMsg
}
fun setToastMsg(toastMsg: String) {
this.toastMsg = toastMsg
}
}
package com.sd.cavphmi.net
abstract class OnDataBackService<T>: OnDataCallback<T> {
override fun onSubscribe() {
}
override fun onComplete() {
}
}
\ No newline at end of file
package com.sd.cavphmi.net
interface OnDataCallback<T> {
fun onSubscribe()
fun onSuccess(t: T)
fun onFailed(error: String)
fun onComplete()
fun loginTimeout()
}
\ No newline at end of file
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