1.新增删除用户支付信息并取消订阅

2.完善意大利语言
3.删除Room 数据库,解决C-05 - 敏感位置数据以明文存储在本地
4.优化通用弹窗,固定高度改为自适应
This commit is contained in:
2026-09-09 10:57:31 +08:00
parent 6b9e5de48c
commit 1a032383ce
40 changed files with 1158 additions and 1014 deletions

View File

@@ -1 +1 @@
#Fri Aug 07 11:10:38 CST 2026
#Tue Sep 08 18:11:01 CST 2026

View File

@@ -28,9 +28,9 @@ android {
applicationId "com.abbidot.tracker"
minSdkVersion 24
targetSdkVersion 35
versionCode 2500
// versionName "2.5.0"
versionName "2.5.0-Beta5"
versionCode 2501
versionName "2.5.1"
// versionName "2.5.1-Beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -0,0 +1,71 @@
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8" ><meta name=ProgId content=Word.Document ><meta name=Generator content="Microsoft Word 14" ><meta name=Originator content="Microsoft Word 14" ><title></title></head>
<body>
<div>
<p>Presso ABBI PET INC rispettiamo la tua privacy e ci impegniamo a proteggerla. La presente Informativa sulla privacy descrive come raccogliamo, utilizziamo, tuteliamo e manteniamo riservate le tue informazioni quando utilizzi la nostra applicazione mobile («App»).</p>
<h3>1. Informazioni che raccogliamo</h3>
<ul>
<li>Informazioni personali: Quando crei un account, potremmo raccogliere informazioni personali quali il tuo nome, l'indirizzo e-mail e il numero di telefono.</li>
<li>Informazioni sull'animale: Raccogliamo informazioni sui tuoi animali, tra cui nome, età, razza e peso, al fine di fornire servizi personalizzati.</li>
<li>Dati di utilizzo: Raccogliamo informazioni sulle modalità di interazione con la nostra App, come le funzionalità che utilizzi e il tempo trascorso sull'App.</li>
<li>Informazioni sul dispositivo: Potremmo raccogliere informazioni sul dispositivo che utilizzi per accedere all'App, inclusi il tipo di dispositivo, il sistema operativo e gli identificatori univoci del dispositivo.</li>
<li>Dati di localizzazione: Previo tuo consenso, potremmo raccogliere ed elaborare informazioni sulla posizione del tuo dispositivo e del tuo animale al fine di fornire servizi basati sulla localizzazione.</li>
</ul>
<h3>2. Come utilizziamo le tue informazioni</h3>
<ul>
<li>Per fornire e migliorare i nostri servizi: Utilizziamo le tue informazioni per gestire e migliorare l'App e i nostri servizi.</li>
<li>Per comunicare con te: Potremmo utilizzare le tue informazioni per inviarti aggiornamenti, newsletter, materiale di marketing e altre informazioni che potrebbero interessarti.</li>
<li>Per personalizzare la tua esperienza: Utilizziamo le tue informazioni per adattare i contenuti e i servizi che offriamo al fine di rispondere al meglio alle tue esigenze e preferenze.</li>
<li>Per garantire sicurezza e conformità: Utilizziamo le tue informazioni per garantire la sicurezza della nostra App e la conformità alle leggi e ai regolamenti applicabili.</li>
</ul>
<h3>3. Riservatezza e sicurezza dei dati</h3>
<ul>
<li>Crittografia dei dati: Utilizziamo protocolli di crittografia conformi agli standard del settore per proteggere le tue informazioni personali durante la trasmissione e l'archiviazione.</li>
<li>Controlli di accesso: L'accesso alle tue informazioni personali è limitato esclusivamente al personale autorizzato e implementiamo severi controlli di accesso per impedire accessi non autorizzati.</li>
<li>Minimizzazione dei dati: Raccogliamo e conserviamo solo la quantità minima di informazioni personali necessaria per fornire i nostri servizi.</li>
<li>Audit regolari: Eseguiamo regolarmente audit e valutazioni di sicurezza per assicurarci che le nostre misure di protezione dei dati siano aggiornate ed efficaci.</li>
</ul>
<h3>4. Condivisione delle tue informazioni</h3>
<ul>
<li>Fornitori di servizi: Potremmo condividere le tue informazioni con fornitori di servizi terzi che svolgono servizi per nostro conto, quali hosting, analisi dei dati e assistenza ai clienti. Tali fornitori di servizi sono contrattualmente obbligati a mantenere le tue informazioni riservate e sicure.</li>
<li>Requisiti legali: Potremmo divulgare le tue informazioni qualora la legge lo richieda o in risposta a una richiesta legale.</li>
<li>Cessioni aziendali: In caso di fusione, acquisizione o vendita di tutte o di parte delle nostre attività, le tue informazioni potrebbero essere trasferite al nuovo proprietario, subordinatamente ai medesimi impegni in materia di protezione dei dati.</li>
</ul>
<h3>5. Le tue scelte</h3>
<ul>
<li>Informazioni sull'account: Puoi aggiornare o eliminare le informazioni del tuo account tramite le impostazioni dell'App.</li>
<li>Comunicazioni di marketing: Puoi disiscriverti dalle comunicazioni di marketing seguendo le istruzioni di disiscrizione indicate nelle comunicazioni stesse o contattandoci direttamente.</li>
<li>Dati di localizzazione: Puoi disattivare i servizi di localizzazione tramite le impostazioni del tuo dispositivo, ma ciò potrebbe pregiudicare alcune funzionalità dell'App.</li>
</ul>
<h3>6. Sicurezza</h3>
<p>Adottiamo misure ragionevoli per proteggere le tue informazioni da accessi, utilizzi o divulgazioni non autorizzati. Tuttavia, nessun metodo di trasmissione su Internet o di archiviazione elettronica è sicuro al 100%.</p>
<h3>7. Privacy dei minori</h3>
<p>La nostra App non è destinata all'uso da parte di minori di età inferiore a 13 anni e non raccogliamo consapevolmente informazioni personali da minori di età inferiore a 13 anni. Qualora venissimo a conoscenza di aver raccolto informazioni personali da un minore di età inferiore a 13 anni, adotteremo le misure necessarie per eliminare tali informazioni.</p>
<h3>8. Modifiche alla presente Informativa sulla privacy</h3>
<p>Potremmo aggiornare di tanto in tanto la presente Informativa sulla privacy. Ti informeremo di eventuali modifiche pubblicando la nuova Informativa sulla privacy all'interno dell'App. Ti consigliamo di consultare periodicamente la presente Informativa per verificare eventuali modifiche.</p>
<h3>9. Contattaci</h3>
<p>Per qualsiasi domanda relativa alla presente Informativa sulla privacy, ti preghiamo di contattarci all'indirizzo:</p>
<p>ABBI PET INC</p>
<p>10700 Richmond Ave Suite 143</p>
<p>Houston, TX 77042</p>
<p>E-mail: support@abbidot.com</p>
</div>
</body></html>

View File

@@ -0,0 +1,54 @@
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8" ><meta name=ProgId content=Word.Document ><meta name=Generator content="Microsoft Word 14" ><meta name=Originator content="Microsoft Word 14" ><title></title></head>
<body>
<div>
<h2>Termini e condizioni di abbonamento al tracker ABBIDOT</h2>
<hr>
<h3>1. Piani di abbonamento</h3>
<p>ABBIDOT offre tre piani di abbonamento:</p>
<ul>
<li>Piano di 3 mesi</li>
<li>Piano di 1 anno</li>
<li>Piano di 2 anni</li>
</ul>
<p>Tutti gli abbonamenti si rinnovano automaticamente alla fine di ogni ciclo di fatturazione, salvo annullamento da parte dell'utente.</p>
<p>Gli utenti possono annullare il proprio abbonamento in qualsiasi momento. Dopo l'annullamento, l'abbonamento rimarrà attivo fino alla fine del periodo di fatturazione corrente e non verranno applicati ulteriori addebiti.</p>
<p>Il dispositivo continuerà a funzionare normalmente durante il periodo di abbonamento attivo.</p>
<hr>
<h3>2. Politica di rimborso</h3>
<h4>2.1 Rimborso automatico (entro 48 ore)</h4>
<p>Tutti gli acquisti di abbonamenti hanno diritto a un <strong>rimborso automatico completo entro 48 ore</strong> dal pagamento. I rimborsi verranno elaborati automaticamente, senza revisione manuale.</p>
<hr>
<h4>2.2 Periodo standard di rimborso (30 giorni)</h4>
<p>Trascorse le iniziali 48 ore, gli utenti possono richiedere un rimborso entro <strong>30 giorni dall'acquisto</strong>.</p>
<ul>
<li>Tutti i piani di abbonamento (3 mesi, 1 anno, 2 anni) sono idonei</li>
<li>Le richieste di rimborso sono soggette a revisione e approvazione</li>
<li>I rimborsi possono essere parzialmente adeguati in base all'utilizzo e al consumo dei servizi</li>
</ul>
<hr>
<h4>2.3 Nessun rimborso dopo 30 giorni</h4>
<p>Gli abbonamenti con più di 30 giorni non sono rimborsabili.</p>
<hr>
<h3>3. Annullamento dell'abbonamento</h3>
<p>Gli utenti possono annullare il proprio abbonamento in qualsiasi momento.</p>
<ul>
<li>L'annullamento interrompe le fatturazioni future</li>
<li>L'abbonamento corrente rimane attivo fino alla fine del periodo di fatturazione</li>
<li>Non viene emesso alcun rimborso parziale dopo l'annullamento, salvo entro il periodo di rimborso</li>
</ul>
<hr>
<h3>4. Aggiornamenti della politica</h3>
<p>ABBIDOT si riserva il diritto di aggiornare o modificare i presenti Termini e condizioni in qualsiasi momento. Gli utenti verranno informati in caso di modifiche significative.</p>
<p>Abbonandoti ai servizi ABBIDOT, accetti i presenti termini.</p>
<hr>
<h3>5. Assistenza ai clienti</h3>
<p>Qualora incontrassi difficoltà, ti preghiamo di contattarci all'indirizzo:</p>
<p><a title="Mail to subscription@abbidot.com" href="subscription@abbidot.com">subscription@abbidot.com</a></p>
<p>Il nostro team di assistenza ti aiuterà al più presto possibile.</p>
</div>
</body></html>

View File

@@ -0,0 +1,76 @@
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8" ><meta name=ProgId content=Word.Document ><meta name=Generator content="Microsoft Word 14" ><meta name=Originator content="Microsoft Word 14" ><title></title></head>
<body>
<div>
<h3>1. Accettazione dei termini</h3>
<p>Scaricando, installando e utilizzando l'applicazione mobile ABBIDOT («App»), accetti di essere vincolato ai presenti Termini e condizioni («Termini»). Se non accetti i presenti Termini, non utilizzare l'App.</p>
<h3>2. Utilizzo dell'App</h3>
<ul>
<li>Idoneità: Per utilizzare l'App devi avere almeno 13 anni. Utilizzando l'App, dichiari e garantisci di soddisfare tale requisito di idoneità.</li>
<li>Licenza: ABBI PET INC ti concede una licenza limitata, non esclusiva, non trasferibile e revocabile per utilizzare l'App esclusivamente per scopi personali e non commerciali.</li>
<li>Restrizioni: Accetti di non:</li>
</ul>
<ul>
<li>Modificare, sottoporre a reverse engineering, decompilare o disassemblare l'App.</li>
<li>Utilizzare l'App per scopi illeciti o in qualsiasi modo che possa danneggiare ABBI PET INC o i suoi utenti.</li>
<li>Accedere all'App o utilizzarla per realizzare un servizio o un prodotto concorrente.</li>
</ul>
<h3>3. Account e sicurezza</h3>
<ul>
<li>Creazione dell'account: Per utilizzare determinate funzionalità dell'App potrebbe essere necessario creare un account. Accetti di fornire informazioni accurate e complete durante il processo di registrazione.</li>
<li>Sicurezza dell'account: Sei responsabile della riservatezza delle credenziali del tuo account e di tutte le attività svolte tramite il tuo account. Accetti di segnalare immediatamente ad ABBI PET INC qualsiasi utilizzo non autorizzato del tuo account.</li>
</ul>
<h3>4. Privacy</h3>
<p>L'utilizzo dell'App è inoltre disciplinato dalla nostra Informativa sulla privacy, che è incorporata per riferimento nei presenti Termini. Ti invitiamo a consultare la nostra Informativa sulla privacy per conoscere le nostre pratiche in materia di trattamento delle tue informazioni.</p>
<h3>5. Contenuti dell'utente</h3>
<ul>
<li>Proprietà: Conservi la proprietà di tutti i contenuti che invii o pubblichi tramite l'App («Contenuti dell'utente»). Inviando i Contenuti dell'utente, concedi ad ABBI PET INC una licenza mondiale, non esclusiva e gratuita per utilizzare, riprodurre, distribuire e visualizzare i tuoi Contenuti dell'utente in connessione con l'App.</li>
<li>Responsabilità: Sei l'unico responsabile dei tuoi Contenuti dell'utente. Accetti di non pubblicare contenuti illeciti, dannosi o che violino i diritti di terzi.</li>
</ul>
<h3>6. Proprietà intellettuale</h3>
<p>Tutti i contenuti, le funzionalità e le caratteristiche dell'App, inclusi ma non limitati a testi, grafica, loghi e software, sono di proprietà esclusiva di ABBI PET INC o dei suoi licenzianti e sono protetti dalle normative in materia di diritto d'autore, marchi e altri diritti di proprietà intellettuale.</p>
<h3>7. Risoluzione</h3>
<p>ABBI PET INC può interrompere o sospendere il tuo accesso all'App in qualsiasi momento, senza preavviso e senza alcuna responsabilità, per qualsiasi motivo, incluso il caso di violazione dei presenti Termini. In caso di risoluzione, il tuo diritto di utilizzare l'App cesserà immediatamente.</p>
<h3>8. Esclusioni di responsabilità e limitazione della responsabilità</h3>
<ul>
<li>Esclusioni di responsabilità: L'App è fornita «così come è» e «come disponibile», senza garanzie di alcun tipo, esplicite o implicite. ABBI PET INC non garantisce che l'App sia priva di interruzioni o di errori.</li>
<li>Limitazione della responsabilità: Nella misura massima consentita dalla legge, ABBI PET INC non sarà responsabile per eventuali danni indiretti, incidentali, speciali o consequenziali derivanti da o in connessione con l'utilizzo dell'App.</li>
</ul>
<h3>9. Legge applicabile</h3>
<p>I presenti Termini saranno disciplinati e interpretati in conformità alle leggi dello Stato del Texas, senza tener conto dei principi in materia di conflitti di leggi.</p>
<h3>10. Modifiche ai Termini</h3>
<p>ABBI PET INC si riserva il diritto di modificare i presenti Termini in qualsiasi momento. Ti informeremo di eventuali modifiche pubblicando i nuovi Termini all'interno dell'App. Il continuo utilizzo dell'App dopo l'entrata in vigore delle modifiche costituisce accettazione dei nuovi Termini.</p>
<h3>11. Riservatezza dei dati</h3>
<p>Ci impegniamo a garantire la riservatezza dei tuoi dati. A tal fine adottiamo le seguenti misure di protezione dei dati:</p>
<ul>
<li>Accordi di riservatezza: Tutti i dipendenti e i fornitori di servizi terzi che hanno accesso ai tuoi dati sono tenuti a firmare accordi di riservatezza.</li>
<li>Anonimizzazione dei dati: Ove possibile, anonimizziamo i tuoi dati per proteggere la tua privacy.</li>
<li>Politica di conservazione dei dati: Conserviamo i tuoi dati solo per il tempo strettamente necessario alle finalità descritte nella nostra Informativa sulla privacy, dopodiché vengono eliminati in modo sicuro o anonimizzati.</li>
</ul>
<h3>12. Contattaci</h3>
<p>Per qualsiasi domanda relativa ai presenti Termini, ti preghiamo di contattarci all'indirizzo:</p>
<p>ABBI PET INC</p>
<p>10700 Richmond Ave Suite 143</p>
<p>Houston, TX 77042</p>
<p>E-mail: support@abbidot.com</p>
</div></body></html>

View File

@@ -5,11 +5,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatDialog
import androidx.viewbinding.ViewBinding
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.tracker.R
import com.qmuiteam.qmui.alpha.QMUIAlphaButton
import com.qmuiteam.qmui.alpha.QMUIAlphaImageButton
@@ -18,7 +16,6 @@ import com.qmuiteam.qmui.alpha.QMUIAlphaImageButton
/**
*Created by .yzq on 2022/1/11/011.-
* @link
* @dialogHeightDp 默认高度350dp
* @description:BaseDialog
*/
abstract class BaseDialog<T : ViewBinding>
@@ -44,15 +41,14 @@ abstract class BaseDialog<T : ViewBinding>
//设置Dialog动画
window!!.setWindowAnimations(mAnimationResId)
//设置弹窗的高度
val layoutParams: WindowManager.LayoutParams = window!!.attributes
if (mDialogHeightDp == 0) {
//采用自适应高度
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
} else {
layoutParams.height = AppUtils.dpToPx(mDialogHeightDp)
}
// layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT
window!!.attributes = layoutParams
// val layoutParams: WindowManager.LayoutParams = window!!.attributes
// if (mDialogHeightDp == 0) {
// //采用自适应高度
// layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
// } else {
// layoutParams.height = AppUtils.dpToPx(mDialogHeightDp)
// }
// window!!.attributes = layoutParams
initView()
}

View File

@@ -1,11 +1,6 @@
package com.abbidot.tracker.bean
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.abbidot.tracker.database.MyDatabase
import kotlinx.parcelize.Parcelize
/**
@@ -14,20 +9,20 @@ import kotlinx.parcelize.Parcelize
* @description:保存用户输入信用卡
*/
@Parcelize
@Entity(tableName = MyDatabase.CREDIT_CARD_TABLE)
//@Entity(tableName = MyDatabase.CREDIT_CARD_TABLE)
data class CreditCardBean(
@PrimaryKey @ColumnInfo var cardNumber: String,
@ColumnInfo var firstName: String,
@ColumnInfo var lastName: String,
@ColumnInfo var cardName: String,
@ColumnInfo var expirationDate: String,
@ColumnInfo var cvv: String,//信用卡验证值(Card Verification Value)
@ColumnInfo var countryCode: String,
@ColumnInfo var isPrimary: Boolean,
@Ignore var checked: Boolean = false,
@Ignore var expMonth: Int,
@Ignore var expYear: Int,
@Ignore var lastFourNumber: String,
var cardNumber: String,
var firstName: String,
var lastName: String,
var cardName: String,
var expirationDate: String,
var cvv: String,//信用卡验证值(Card Verification Value)
var countryCode: String,
var isPrimary: Boolean,
var checked: Boolean = false,
var expMonth: Int,
var expYear: Int,
var lastFourNumber: String,
) : Parcelable {
constructor() : this("", "", "", "", "", "", "USA", false, false, 0, 0, "")
}

View File

@@ -1,13 +1,9 @@
package com.abbidot.tracker.bean
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import com.abbidot.baselibrary.constant.ConState
import com.abbidot.baselibrary.constant.DeviceType
import com.abbidot.tracker.base.BaseDiffBean
import com.abbidot.tracker.database.MyDatabase
import kotlinx.parcelize.Parcelize
/**
@@ -16,26 +12,26 @@ import kotlinx.parcelize.Parcelize
* @description:连接保存的设备表
*/
// 定义表名称,SQLite 中的表名称不区分大小写,2个主键
@Entity(tableName = MyDatabase.DEVICE_TABLE, primaryKeys = ["deviceOutId", "deviceId"])
//@Entity(tableName = MyDatabase.DEVICE_TABLE, primaryKeys = ["deviceOutId", "deviceId"])
@Parcelize
data class DeviceBean(//@PrimaryKey(autoGenerate = true) var id: Long,//autoGenerate = true 自动增长分配ID
@ColumnInfo @DeviceType var type: Int,//设备类型
@ColumnInfo var deviceName: String,
@ColumnInfo var deviceOutId: String,
@ColumnInfo var deviceId: String,
@ColumnInfo var shared: Int, //0=没有分享,1=是授权分享的
@ColumnInfo var batteryCapacity: Int,
@ColumnInfo var ledSwitch: Int,
@ColumnInfo @ConState var conState: Int,//连接状态
@ColumnInfo var macId: String,
@ColumnInfo var deviceInfoId: String,
@ColumnInfo var surplusDays: Int,
@ColumnInfo var gnssSignal: Int,
@ColumnInfo var lteSignal: Int,
@ColumnInfo var turnOff: Int,
@ColumnInfo var lightMode: Int,
@Ignore var deviceType: Int,
@Ignore var pet: PetBean?
var type: Int,//设备类型
var deviceName: String,
var deviceOutId: String,
var deviceId: String,
var shared: Int, //0=没有分享,1=是授权分享的
var batteryCapacity: Int,
var ledSwitch: Int,
var conState: Int,//连接状态
var macId: String,
var deviceInfoId: String,
var surplusDays: Int,
var gnssSignal: Int,
var lteSignal: Int,
var turnOff: Int,
var lightMode: Int,
var deviceType: Int,
var pet: PetBean?
) : BaseDiffBean(), Parcelable {
// 如果某个实体中有您不想保留的字段,则可以使用 @Ignore 为这些字段添加注释

View File

@@ -8,5 +8,5 @@ package com.abbidot.tracker.bean
*/
data class OrderBean(
var orderId: String, var orderNo: String, var availableOrder: Int,//判断套餐是否可用或过期,1是可用 0不可用
var isCanRefund: Int
var isCanRefund: Int, var isNeedCancel: Int//是否需要取消订阅 0:不存在 1存在
)

View File

@@ -1,13 +1,8 @@
package com.abbidot.tracker.database
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.abbidot.tracker.MyApplication
import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.bean.DeviceBean
import com.abbidot.tracker.database.dao.CreditCardDao
import com.abbidot.tracker.database.dao.DeviceDao
/**
*Created by .yzq on 2021/11/6/006.
@@ -15,15 +10,14 @@ import com.abbidot.tracker.database.dao.DeviceDao
* @description:RoomDatabase实例
*/
//exportSchema = false,防止改数据库内容版本自动增加
@Database(
entities = [DeviceBean::class, CreditCardBean::class],
version = 5,
// autoMigrations = [AutoMigration(from = 1, to = 2)],
exportSchema = false,
)
//@Database(
// entities = [DeviceBean::class, CreditCardBean::class],
// version = 5,
//// autoMigrations = [AutoMigration(from = 1, to = 2)],
// exportSchema = false,
//)
abstract class MyDatabase : RoomDatabase() {
abstract fun deviceDao(): DeviceDao
abstract fun creditCardDao(): CreditCardDao
// abstract fun creditCardDao(): CreditCardDao
companion object {
@@ -47,14 +41,9 @@ abstract class MyDatabase : RoomDatabase() {
//表名
const val CREDIT_CARD_TABLE = "creditCard"
const val DEVICE_TABLE = "device"
fun deviceDao(): DeviceDao {
return db.deviceDao()
}
fun creditCardDao(): CreditCardDao {
return db.creditCardDao()
}
// fun creditCardDao(): CreditCardDao {
// return db.creditCardDao()
// }
}
}

View File

@@ -1,6 +1,5 @@
package com.abbidot.tracker.database.dao
import androidx.room.Dao
import com.abbidot.tracker.bean.CreditCardBean
/**
@@ -8,5 +7,5 @@ import com.abbidot.tracker.bean.CreditCardBean
* @link
* @description:
*/
@Dao
//@Dao
interface CreditCardDao : BaseDao<CreditCardBean>

View File

@@ -1,18 +1,15 @@
package com.abbidot.tracker.database.dao
import androidx.room.Dao
import androidx.room.Query
import com.abbidot.tracker.bean.DeviceBean
import com.abbidot.tracker.database.MyDatabase
/**
*Created by .yzq on 2021/11/8/008.
* @link
* @description:DeviceBean表的dao
*/
@Dao
//@Dao
interface DeviceDao : BaseDao<DeviceBean> {
@Query("SELECT * FROM ${MyDatabase.DEVICE_TABLE} WHERE macId LIKE :mac LIMIT 1")
fun findByMac(mac: String): DeviceBean?
// @Query("SELECT * FROM ${MyDatabase.DEVICE_TABLE} WHERE macId LIKE :mac LIMIT 1")
// fun findByMac(mac: String): DeviceBean?
}

View File

@@ -21,7 +21,6 @@ import com.abbidot.tracker.bean.SetMealBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivitySelectPaymentMethodBinding
import com.abbidot.tracker.deprecated.adapter.SelectPaymentMethodAdapter
import com.abbidot.tracker.deprecated.ui.activity.vm.BraintreePalViewModel
@@ -99,8 +98,8 @@ class PaymentMethodPayPalActivity :
withContext(Dispatchers.IO) {
ViewUtil.instance.addMenuBean(paymentMethodList, "", "", R.drawable.ico_lay_paypal)
val list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
list?.forEach {
val list = mutableListOf<CreditCardBean>()
list.forEach {
val imageId = Util.getCreditCardType(it.cardNumber)
ViewUtil.instance.addMenuBean(
paymentMethodList, it.cardNumber, it.expirationDate, imageId
@@ -115,7 +114,7 @@ class PaymentMethodPayPalActivity :
)
}
mSelectPaymentMethodAdapter = SelectPaymentMethodAdapter(mContext!!, paymentMethodList)
mSelectPaymentMethodAdapter = SelectPaymentMethodAdapter(mContext, paymentMethodList)
mSelectPaymentMethodAdapter.setOnItemClickListener(object :
BaseRecyclerAdapter.OnItemClickListener {
override fun onItemClick(itemView: View?, pos: Int) {
@@ -123,7 +122,7 @@ class PaymentMethodPayPalActivity :
}
})
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
mContext!!,
mContext,
mViewBinding.paymentMethodRecyclerView,
mSelectPaymentMethodAdapter,
bottom = 40

View File

@@ -21,7 +21,6 @@ import com.abbidot.tracker.bean.RechargeDeviceBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivitySelectPaymentMethodBinding
import com.abbidot.tracker.deprecated.adapter.SelectPaymentMethodAdapter
import com.abbidot.tracker.deprecated.ui.activity.vm.BraintreePalViewModel
@@ -113,8 +112,8 @@ class PaymentMethodStripeActivity :
withContext(Dispatchers.IO) {
// ViewUtil.instance.addMenuBean(paymentMethodList, "", "", R.drawable.ico_lay_paypal)
val list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
list?.forEach {
val list = mutableListOf<CreditCardBean>()
list.forEach {
val imageId = Util.getCreditCardType(it.cardNumber)
ViewUtil.instance.addMenuBean(
paymentMethodList, it.cardNumber, it.expirationDate, imageId

View File

@@ -11,7 +11,6 @@ import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.bean.*
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.diff.PaymentMethodDiffCallBack
import com.abbidot.tracker.retrofit2.NetworkApi
import com.abbidot.tracker.util.Util
@@ -59,9 +58,11 @@ class BraintreePalViewModel : ViewModel() {
/**
* 显示添加的信用卡
*/
fun addCreditCard(activity: BaseActivity<*>,
card: CreditCardBean,
adapter: BaseRecyclerAdapter<MenuTxtBean>) {
fun addCreditCard(
activity: BaseActivity<*>,
card: CreditCardBean,
adapter: BaseRecyclerAdapter<MenuTxtBean>
) {
val oldList = adapter.getData()
val newList = mutableListOf<MenuTxtBean>()
newList.addAll(oldList)
@@ -76,12 +77,14 @@ class BraintreePalViewModel : ViewModel() {
}
}
if (!isSame) {
newList.removeLast()
// newList.removeLast()
val imageId = Util.getCreditCardType(card.cardNumber)
ViewUtil.instance.addMenuBean(newList, card.cardNumber, card.expirationDate, imageId)
ViewUtil.instance.addMenuBean(newList,
activity.getString(R.string.txt_pay_order_add_card), "",
R.drawable.ico_lay_newcard)
ViewUtil.instance.addMenuBean(
newList,
activity.getString(R.string.txt_pay_order_add_card), "",
R.drawable.ico_lay_newcard
)
}
viewModelScope.launch {
@@ -116,11 +119,13 @@ class BraintreePalViewModel : ViewModel() {
/**
*@param orderStatus:0待支付 1是支付成功 2是取消支付/失败
*/
fun updateOrderStatus(activity: BaseActivity<*>,
orderId: String,
orderStatus: Int,//0待支付 1是支付成功 2是取消支付/失败
deviceId: String,
mealDays: Int) {
fun updateOrderStatus(
activity: BaseActivity<*>,
orderId: String,
orderStatus: Int,//0待支付 1是支付成功 2是取消支付/失败
deviceId: String,
mealDays: Int
) {
activity.showLoading(true)
viewModelScope.launch {
val result = NetworkApi.updateOrderStatus(orderId, orderStatus, deviceId, mealDays)
@@ -131,12 +136,14 @@ class BraintreePalViewModel : ViewModel() {
/**
* 信用卡发起支付
*/
fun cardPayment(activity: BaseActivity<*>,
mealName: String,
mealDays: Int,
totalCost: String,
paymentMethodNonce: String,
deviceId: String) {
fun cardPayment(
activity: BaseActivity<*>,
mealName: String,
mealDays: Int,
totalCost: String,
paymentMethodNonce: String,
deviceId: String
) {
activity.showLoading(true)
viewModelScope.launch {
val result =
@@ -148,19 +155,23 @@ class BraintreePalViewModel : ViewModel() {
/**
* 信用卡订阅支付
*/
private fun cardSubscription(activity: BaseActivity<*>,
userId: String,
paymentMethodNonce: String,
firstName: String,
lastName: String,
username: String,
deviceId: String,
setMealBean: SetMealBean) {
private fun cardSubscription(
activity: BaseActivity<*>,
userId: String,
paymentMethodNonce: String,
firstName: String,
lastName: String,
username: String,
deviceId: String,
setMealBean: SetMealBean
) {
activity.showLoading(true)
viewModelScope.launch {
val result =
NetworkApi.cardSubscription(userId, paymentMethodNonce, firstName, lastName,
username, deviceId, setMealBean)
NetworkApi.cardSubscription(
userId, paymentMethodNonce, firstName, lastName,
username, deviceId, setMealBean
)
mCardPaymentResultLiveData.value = result
}
}
@@ -169,11 +180,13 @@ class BraintreePalViewModel : ViewModel() {
/**
* 开始调起payPal支付
*/
fun launchPayPal(activity: BaseActivity<*>,
braintreeClient: BraintreeClient?,
payPalClient: PayPalClient?,
setMealBean: SetMealBean?,
orderNo: String) {
fun launchPayPal(
activity: BaseActivity<*>,
braintreeClient: BraintreeClient?,
payPalClient: PayPalClient?,
setMealBean: SetMealBean?,
orderNo: String
) {
activity.showLoading(true)
viewModelScope.launch(Dispatchers.IO) {
braintreeClient?.getConfiguration { _, _ ->
@@ -196,11 +209,13 @@ class BraintreePalViewModel : ViewModel() {
/**
* 开始调起信用卡支付,自动订阅
*/
fun launchCardPay(activity: BaseActivity<*>,
cardClient: CardClient?,
card: Card,
setMealBean: SetMealBean?,
deviceId: String) {
fun launchCardPay(
activity: BaseActivity<*>,
cardClient: CardClient?,
card: Card,
setMealBean: SetMealBean?,
deviceId: String
) {
if (null == setMealBean) return
activity.apply {
@@ -218,20 +233,18 @@ class BraintreePalViewModel : ViewModel() {
// activity.showLoading(true)
// cardPayment(activity, setMealBean.mealPackage, setMealBean.days,
// setMealBean.cost.toString(), nonce, deviceId)
var list: List<CreditCardBean>?
withContext(Dispatchers.IO) {
list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
}
if (null != list) {
val userId = MMKVUtil.getString(MMKVKey.UserId)
val userName = MMKVUtil.getString(MMKVKey.UserName)
for (creditCard in list!!) {
if (card.number == creditCard.cardNumber) {
//信用卡订阅支付
cardSubscription(activity, userId, nonce, creditCard.firstName,
creditCard.lastName, userName, deviceId, setMealBean)
break
}
var list = mutableListOf<CreditCardBean>()
val userId = MMKVUtil.getString(MMKVKey.UserId)
val userName = MMKVUtil.getString(MMKVKey.UserName)
for (creditCard in list!!) {
if (card.number == creditCard.cardNumber) {
//信用卡订阅支付
cardSubscription(
activity, userId, nonce, creditCard.firstName,
creditCard.lastName, userName, deviceId, setMealBean
)
break
}
}
}

View File

@@ -8,11 +8,11 @@ import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.bean.LKSimSetMealBean
import com.abbidot.tracker.bean.MenuTxtBean
import com.abbidot.tracker.bean.RechargeDeviceBean
import com.abbidot.tracker.bean.StripeSubscriptionPriceBean
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.retrofit2.NetworkApi
import com.stripe.android.PaymentConfiguration
import com.stripe.android.model.CardParams
@@ -60,24 +60,22 @@ class StripePalViewModel : ViewModel() {
fun startCheckout(activity: BaseActivity<*>, card: MenuTxtBean) {
activity.showLoading(true)
viewModelScope.launch(Dispatchers.IO) {
val list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
if (null != list) {
for (it in list) {
if (card.menuName == it.cardNumber) {
val dates = it.expirationDate.split("/")
val name = "${it.lastName} ${it.firstName}"
val params = PaymentMethodCreateParams.createCard(
CardParams(
it.cardNumber, dates[0].toInt(), dates[1].toInt(), it.cvv, name
)
val list = mutableListOf<CreditCardBean>()
for (it in list) {
if (card.menuName == it.cardNumber) {
val dates = it.expirationDate.split("/")
val name = "${it.lastName} ${it.firstName}"
val params = PaymentMethodCreateParams.createCard(
CardParams(
it.cardNumber, dates[0].toInt(), dates[1].toInt(), it.cvv, name
)
val confirmParams =
ConfirmPaymentIntentParams.createWithPaymentMethodCreateParams(
params, mPaymentIntentClientSecret
)
mPaymentLauncher.confirm(confirmParams)
break
}
)
val confirmParams =
ConfirmPaymentIntentParams.createWithPaymentMethodCreateParams(
params, mPaymentIntentClientSecret
)
mPaymentLauncher.confirm(confirmParams)
break
}
}
}

View File

@@ -7,6 +7,7 @@ import androidx.annotation.StyleRes
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.databinding.DialogMyLayoutBinding
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.widget.TypefaceRoundButton
import com.abbidot.tracker.widget.TypefaceTextView
@@ -14,11 +15,12 @@ import com.abbidot.tracker.widget.TypefaceTextView
*Created by .yzq on 2021/12/24/024.
* @link
* @description: 自定义对话框,背景阴影
* @dialogHeightDp 默认高度240dp
*/
class MyAlertDialog(
context: Context, @StyleRes themeResId: Int = R.style.my_Dialog_style
) : BaseDialog<DialogMyLayoutBinding>(
DialogMyLayoutBinding::inflate, context, dialogHeightDp = 260, themeResId = themeResId
DialogMyLayoutBinding::inflate, context, themeResId = themeResId
) {
private lateinit var mTitleTextView: TypefaceTextView
@@ -55,6 +57,8 @@ class MyAlertDialog(
if (!TextUtils.isEmpty(title)) {
mTitleTextView.visibility = View.VISIBLE
mTitleTextView.text = title
val typeface = ViewUtil.instance.setTypeface(context, ViewUtil.FONT_COMMON_NAME)
mContentTextView.setTypeface(typeface)
}
}

View File

@@ -263,6 +263,23 @@ interface INetworkService {
@Field("userId") userId: String, @Field("measurementUnitType") measurementUnit: Int
): BaseResponse<String>
/**
* 获取用户订单中是否存在开启自动续订状态
*/
@GET("user/getOrderAutoRenewalStatus")
suspend fun getOrderAutoRenewalStatus(@Query("userId") userId: String): BaseResponse<OrderBean>
/**
* 移除用户支付信息
* paymentMethodType=1为信用卡 2为PayPal
*/
@FormUrlEncoded
@POST("user/removePaymentMethodID")
suspend fun removePaymentMethodID(
@Field("userId") userId: String, @Field("paymentMethodType") paymentMethodType: Int
): BaseResponse<String>
/**
* 获取蓝牙设备Mac
*/

View File

@@ -109,6 +109,21 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
service.updateMeasureUnit(userId, measurementUnit)
}
/**
*获取用户订单中是否存在开启自动续订状态
*/
suspend fun getOrderAutoRenewalStatus(userId: String) = getResult {
service.getOrderAutoRenewalStatus(userId)
}
/**
*移除用户支付信息
* paymentMethodType=1为信用卡 2为PayPal
*/
suspend fun removePaymentMethodID(userId: String, paymentMethodType: Int) = getResult {
service.removePaymentMethodID(userId, paymentMethodType)
}
/**
* 图片上传
*/
@@ -1321,8 +1336,13 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
/**
* 手机号验证码验证
*/
suspend fun validatePhoneCode(phone: String, code: String, type: Int,openidIdentifier: String) = getResult {
service.validatePhoneCode(phone, code, type,openidIdentifier)
suspend fun validatePhoneCode(
phone: String,
code: String,
type: Int,
openidIdentifier: String
) = getResult {
service.validatePhoneCode(phone, code, type, openidIdentifier)
}
/**

View File

@@ -37,7 +37,6 @@ import com.abbidot.tracker.bean.ReceiveDeviceData
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivityHomeV2Binding
import com.abbidot.tracker.dialog.CommonDialog1
import com.abbidot.tracker.dialog.CommonListDialog
@@ -540,23 +539,6 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
* 显示被删除邀请的弹窗
*/
private fun showDeleteInviteDialog(deleteArray: MutableList<FamilyBean>) {
lifecycleScope.launch(Dispatchers.IO) {
val myDeviceDb = MyDatabase.deviceDao().findAll(MyDatabase.DEVICE_TABLE)
myDeviceDb?.apply {
for (deviceDb in myDeviceDb) {
for (item in deleteArray) {
if (deviceDb.deviceId == item.deviceId) {
MyDatabase.deviceDao().delete(deviceDb)
LogUtil.e("删除了邀请的设备")
}
}
}
}
val newDeviceDb = MyDatabase.deviceDao().findAll(MyDatabase.DEVICE_TABLE)
newDeviceDb?.apply {
LogUtil.e("删去了邀请,还剩${newDeviceDb.size}下个设备")
}
}
CommonDialog1(
mContext,
getString(R.string.txt_setting_notification),

View File

@@ -74,12 +74,6 @@ class DeleteTracker1Activity :
)
}
}
//删除设备成功后,把本地数据库中的设备也删除
MyDatabase.deviceDao().deleteByParams(
ConstantString.DeviceId,
device.deviceId,
MyDatabase.DEVICE_TABLE
)
runOnUiThread {
showDeleteDialog()
}

View File

@@ -20,7 +20,6 @@ import com.abbidot.tracker.bean.ReceiveDeviceData
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivityDeleteTracker2Binding
import com.abbidot.tracker.dialog.CommonDialog1
import com.abbidot.tracker.util.Util
@@ -162,12 +161,6 @@ class DeleteTracker2Activity :
withContext(Dispatchers.IO) {
mDeviceBean?.let { device ->
SRBleUtil.instance.disconnectToMac(device.macId)
//删除设备成功后,把本地数据库中的设备也删除
MyDatabase.deviceDao().deleteByParams(
ConstantString.DeviceId,
device.deviceId,
MyDatabase.DEVICE_TABLE
)
runOnUiThread {
showDeleteDialog()
}

View File

@@ -166,14 +166,8 @@ class MyTrackerV2Activity :
//保存本地数据库
if (!TextUtils.isEmpty(device.deviceOutId) && null != device.pet) {
bindDeviceNumber++
// MyDatabase.deviceDao().insert(device)
} else if (!TextUtils.isEmpty(device.deviceOutId) && null == device.pet) {
//删除本地没绑定的设备
MyDatabase.deviceDao().deleteByParams(
ConstantString.DeviceId,
device.deviceId,
MyDatabase.DEVICE_TABLE
)
}
}
if (bindDeviceNumber == 1) isOnlyBindOneDevice = true
@@ -269,15 +263,6 @@ class MyTrackerV2Activity :
dealRequestResult(it, object : GetResultCallback {
override fun onResult(any: Any) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val device = mMyTrackerAdapter.getData()[mCurrentBeanOption]
//解绑成功后,把本地数据库中的设备也删除
MyDatabase.deviceDao().deleteByParams(
ConstantString.DeviceId,
device.deviceId,
MyDatabase.DEVICE_TABLE
)
}
mUnAssignDeviceList.clear()
mUnAssignPetList.clear()
XEventBus.post(EventName.RefreshPet)

View File

@@ -21,7 +21,6 @@ import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivityAddCreditCardPaymentBinding
import com.abbidot.tracker.util.ThirdPartyUtil
import com.abbidot.tracker.util.Util
@@ -211,143 +210,7 @@ class AddCreditCardPaymentActivity :
}
}
private fun confirmSaveCard() {
val cardNumber =
mViewBinding.ilAddCardNumber.etInputView2Content.text.toString().replace(" ", "")
val cardName = mViewBinding.ilAddCardNameOnCard.etInputView2Content.text.toString()
val creditCardValidity = mViewBinding.etAddCardMmDdContent.text.toString()
val cvv = mViewBinding.etAddCardCvcContent.text.toString()
if (TextUtils.isEmpty(cardNumber) || TextUtils.isEmpty(cardName) || TextUtils.isEmpty(
creditCardValidity
) || TextUtils.isEmpty(cvv)
) {
showToast(R.string.txt_not_null)
return
}
if (!creditCardValidity.contains("/")) {
showToast(R.string.txt_card_validity_format)
return
} else {
val dates = creditCardValidity.split("/")
try {
if (dates[0].toInt() > 12) {
showToast(R.string.txt_card_validity_format)
return
}
} catch (e: Exception) {
showToast(R.string.txt_card_validity_format)
return
}
}
if (Util.getCreditCardType(cardNumber) == 0 || cardNumber.length < 9) {
showToast(R.string.txt_card_number_format)
return
}
lifecycleScope.launch(Dispatchers.IO) {
val list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
var existCard: CreditCardBean? = null
list?.apply {
if (isNotEmpty()) {
for (c in list) {
if (!isEdit && c.cardNumber == cardNumber) {
existCard = c
break
} else if (isEdit && null != mOldCard && c.cardNumber == mOldCard!!.cardNumber) {
existCard = c
break
}
}
}
}
if (isEdit) {
existCard?.let {
it.cardName = cardName
it.cardNumber = cardNumber
it.expirationDate = creditCardValidity
it.cvv = cvv
it.isPrimary = mViewBinding.cbAddCardSetPrimarySwitch.isChecked
if (null != mOldCard && mOldCard!!.cardNumber != cardNumber) {
MyDatabase.creditCardDao().delete(mOldCard!!)
}
saveCard(list)
}
} else {
if (null != existCard) {
launch(Dispatchers.Main) {
ViewUtil.instance.showDialog(
mContext,
R.string.txt_credit_card_exists,
object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) {
dialog.dismiss()
lifecycleScope.launch(Dispatchers.IO) {
saveCard(list)
}
}
},
okTextResId = R.string.start_txt_yes,
cancelTextResId = R.string.txt_no
)
}
} else saveCard(list)
}
}
}
/**
* 保存信用卡
*/
private fun saveCard(list: List<CreditCardBean>?) {
mViewBinding.apply {
val cardNumber = ilAddCardNumber.etInputView2Content.text.toString().replace(" ", "")
val cardName = ilAddCardNameOnCard.etInputView2Content.text.toString()
val creditCardValidity = etAddCardMmDdContent.text.toString()
val cvv = etAddCardCvcContent.text.toString()
if (cbAddCardSetPrimarySwitch.isChecked) {
mCreditCard?.isPrimary = true
list?.apply {
if (isNotEmpty()) {
for (c in list) {
if (c.isPrimary) {
c.isPrimary = false
MyDatabase.creditCardDao().update(c)
}
}
}
}
}
mCreditCard?.let {
if (isEdit) {
list?.apply {
if (isNotEmpty()) {
for (c in list) {
//因卡号唯一,编辑卡号删除存在的信用卡
if (c.cardNumber == it.cardNumber) {
MyDatabase.creditCardDao().delete(c)
}
}
}
}
}
it.cardNumber = cardNumber
it.cardName = cardName
it.expirationDate = creditCardValidity
it.cvv = cvv
// MyDatabase.creditCardDao().insert(it)
}
runOnUiThread {
// val intent = Intent()
// intent.putExtra(ConstantString.Card, mCreditCard)
setResult(ResultCode.ResultCode_1, null)
showToast(R.string.txt_save_successful, isFinish = true)
}
}
}
private fun confirmSaveCardV2() {
mViewBinding.apply {
@@ -416,12 +279,10 @@ class AddCreditCardPaymentActivity :
}
})
} else {
// MyDatabase.creditCardDao().deleteAll(MyDatabase.CREDIT_CARD_TABLE)
it.cardNumber = cardNumber
it.cardName = cardName
it.expirationDate = creditCardValidity
it.cvv = cvv
// MyDatabase.creditCardDao().insert(it)
runOnUiThread {
val intent = Intent()
intent.putExtra(ConstantString.Card, it)
@@ -440,7 +301,7 @@ class AddCreditCardPaymentActivity :
override fun onOkClick(dialog: BaseDialog<*>) {
lifecycleScope.launch(Dispatchers.IO) {
mCreditCard?.apply {
MyDatabase.creditCardDao().delete(this)
// MyDatabase.creditCardDao().delete(this)
}
}
dialog.dismiss()

View File

@@ -1,13 +1,16 @@
package com.abbidot.tracker.ui.activity.subscribe
import android.view.Gravity
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.abbidot.baselibrary.constant.EventName
import com.abbidot.baselibrary.eventbus.XEventBus
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.tracker.R
import com.abbidot.tracker.adapter.ViewPagerAdapter
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.bean.PaymentIDBean
import com.abbidot.tracker.bean.SubscriptionsOrderBean
import com.abbidot.tracker.constant.ConstantInt
@@ -37,6 +40,9 @@ class PaymentMethodActivity :
//支付id
var mPaymentIDBean: PaymentIDBean? = null
//删除支付方式id
private var mRemovePaymentMethodType = 0
override fun getTopBar() = mViewBinding.ilPaymentMethodTopBar.titleTopBar
override fun initData() {
@@ -90,18 +96,86 @@ class PaymentMethodActivity :
finish()
}
mSubscriptionPayViewModel.mPaymentMethodIDLiveData.observe(this) {
dealRequestResult(it, object : GetResultCallback {
override fun onResult(any: Any) {
it.getOrNull()?.let { p ->
mPaymentIDBean = p
(mPayFragments[0] as CreditCardPaymentFragment).getCardData(p.stripeMethodInfo)
if (mPayFragments.size > 1) {
(mPayFragments[1] as PaypalPaymentFragment).showPaypalInfo()
mSubscriptionPayViewModel.apply {
mPaymentMethodIDLiveData.observe(this@PaymentMethodActivity) {
dealRequestResult(it, object : GetResultCallback {
override fun onResult(any: Any) {
it.getOrNull()?.let { p ->
mPaymentIDBean = p
(mPayFragments[0] as CreditCardPaymentFragment).getCardData(p.stripeMethodInfo)
if (mPayFragments.size > 1) {
(mPayFragments[1] as PaypalPaymentFragment).showPaypalInfo()
}
}
}
}
})
})
}
mOrderAutoRenewalStatusLiveData.observe(this@PaymentMethodActivity) {
dealRequestResult(it, object : GetResultCallback {
override fun onResult(any: Any) {
it.getOrNull()?.let { d ->
showRemoveDialog(d.isNeedCancel)
}
}
})
}
mRemovePaymentMethodLiveData.observe(this@PaymentMethodActivity) {
dealRequestResult(it, object : GetResultCallback {
override fun onResult(any: Any) {
showToast(R.string.txt_delete_succe, gravity = Gravity.CENTER)
getUserPaymentMethodID()
}
})
}
}
}
/**
* 删除支付方式
* @param paymentMethodType 支付方式类型 1为信用卡 2为PayPal
*/
fun removePaymentMethodID(paymentMethodType: Int) {
mRemovePaymentMethodType = paymentMethodType
mSubscriptionPayViewModel.getOrderAutoRenewalStatus()
}
/**
* 显示删除支付方式弹窗
* @param haveAutoRenewal 是否有自动续费 1为有 0为无
*/
private fun showRemoveDialog(haveAutoRenewal: Int) {
if (haveAutoRenewal == ConstantInt.Type1) {
ViewUtil.instance.showDialog(
this@PaymentMethodActivity,
R.string.txt_remove_pay_method_tips2,
object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) {
dialog.dismiss()
mSubscriptionPayViewModel.removePaymentMethodID(
mRemovePaymentMethodType
)
}
},
getString(R.string.txt_auto_renewal_on),
R.string.txt_turn_off_remove, R.string.txt_cancel
)
} else {
ViewUtil.instance.showDialog(
this@PaymentMethodActivity,
R.string.txt_remove_pay_method_tips1,
object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) {
dialog.dismiss()
mSubscriptionPayViewModel.removePaymentMethodID(
mRemovePaymentMethodType
)
}
},
getString(R.string.txt_remove_pay_method) + if (AppUtils.isChina()) "?" else "?",
R.string.txt_remove, R.string.txt_cancel
)
}
}
}

View File

@@ -14,6 +14,7 @@ import com.abbidot.tracker.R
import com.abbidot.tracker.adapter.CreditCardAdapter
import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.FragmentCreditCardPaymentBinding
@@ -85,7 +86,11 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
)
ilCreditCardPaymentNoData.btnSureSubscribePlan1Continue.visibility = View.GONE
setOnClickListenerViews(btnCreditCardPaymentAdd, btnMakePaymentCreditCard)
setOnClickListenerViews(
btnCreditCardPaymentAdd,
btnMakePaymentCreditCard,
btnCreditCardPaymentRemove
)
}
// getCardData()
}
@@ -126,9 +131,11 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
btnCreditCardPaymentAdd.visibility = View.INVISIBLE
//卡管理 不需要点击效果
if (null == getHostActivity(PaymentMethodActivity::class.java)?.mOrderBean) {
btnCreditCardPaymentRemove.visibility = View.VISIBLE
btnMakePaymentCreditCard.visibility = View.GONE
} else {
stripeMethodInfo.checked = true
btnCreditCardPaymentRemove.visibility = View.GONE
btnMakePaymentCreditCard.visibility = View.VISIBLE
}
}
@@ -207,6 +214,7 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
}
//卡管理 不需要点击效果
if (null == getHostActivity(PaymentMethodActivity::class.java)?.mOrderBean) {
mViewBinding.btnCreditCardPaymentRemove.visibility = View.VISIBLE
mViewBinding.btnMakePaymentCreditCard.visibility = View.GONE
} else {
var haveCheck = false
@@ -219,6 +227,7 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
if (!haveCheck) {
list[0].checked = true
}
mViewBinding.btnCreditCardPaymentRemove.visibility = View.GONE
mViewBinding.btnMakePaymentCreditCard.visibility = View.VISIBLE
}
mViewBinding.apply {
@@ -327,6 +336,9 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
}
override fun onClick(v: View?) {
if (isLimitClick())
return
mViewBinding.apply {
when (v!!) {
btnCreditCardPaymentAdd -> {
@@ -334,6 +346,10 @@ class CreditCardPaymentFragment : BaseFragment<FragmentCreditCardPaymentBinding>
launchActivity(mActivity!!, mActivityResultLauncher, intent)
}
btnCreditCardPaymentRemove -> getHostActivity(PaymentMethodActivity::class.java)?.removePaymentMethodID(
ConstantInt.Type1
)
btnMakePaymentCreditCard -> startCreditCardPayment()
}
}

View File

@@ -7,6 +7,7 @@ import android.view.View
import androidx.fragment.app.viewModels
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.FragmentPaypalPaymentBinding
@@ -33,7 +34,7 @@ class PaypalPaymentFragment :
override fun initData() {
mViewBinding.apply {
root.setBackgroundResource(R.color.transparent)
setOnClickListenerViews(btnSureRedirectPaypal)
setOnClickListenerViews(btnSureRedirectPaypal, btnPaypalPaymentRemove)
ilPaypalPaymentNoData.btnSureSubscribePlan1Continue.visibility = View.GONE
getHostActivity(PaymentMethodActivity::class.java)?.let {
@@ -65,6 +66,7 @@ class PaypalPaymentFragment :
View.GONE
else
View.VISIBLE
btnPaypalPaymentRemove.visibility = tvPaypalPaymentEmail.visibility
ilPaypalPaymentNoData.root.visibility =
if (null == it.mOrderBean && TextUtils.isEmpty(pId.paypalMethodInfo.email)) {
@@ -105,12 +107,19 @@ class PaypalPaymentFragment :
}
override fun onClick(v: View?) {
if (isLimitClick())
return
mViewBinding.apply {
when (v!!) {
btnSureRedirectPaypal -> getHostActivity(PaymentMethodActivity::class.java)?.mOrderBean?.let {
showNoCancelableLoading(true)
mSubscriptionPayViewModel.createPaypalOrder(it)
}
btnPaypalPaymentRemove -> getHostActivity(PaymentMethodActivity::class.java)?.removePaymentMethodID(
ConstantInt.Type2
)
}
}
}

View File

@@ -621,10 +621,6 @@ class Util {
//保存最后一次登录的邮箱
MMKVUtil.putString(MMKVKey.Email, email)
MMKVUtil.putString(MMKVKey.Phone, phone)
withContext(Dispatchers.IO) {
MyDatabase.deviceDao().deleteAll(MyDatabase.DEVICE_TABLE)
MyDatabase.creditCardDao().deleteAll(MyDatabase.CREDIT_CARD_TABLE)
}
activity.startActivityFinish(Intent(activity, SayHelloActivity::class.java))
}
}

View File

@@ -988,7 +988,7 @@ class ViewUtil private constructor() {
* 适配不同语言跳转h5
*/
fun goHtmlAssetContent(activity: Activity, title: String, fileKey: String) {
val url="file:///android_asset/$fileKey"
val url = "file:///android_asset/$fileKey"
LogUtil.e(url)
WebViewActivity.startWebViewActivity(activity, title, url)
}

View File

@@ -1,6 +1,5 @@
package com.abbidot.tracker.vm
import android.content.Context
import android.os.CountDownTimer
import android.text.TextUtils
import androidx.lifecycle.ViewModel
@@ -11,14 +10,11 @@ import com.abbidot.baselibrary.eventbus.XEventBus
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.bean.DeviceBean
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleScanCallback
import com.clj.fastble.data.BleDevice
import com.clj.fastble.data.BleScanState
import com.clj.fastble.scan.BleScanRuleConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@@ -33,88 +29,6 @@ class ConnectionDeviceViewModel : ViewModel() {
private var mCountDownTimer: CountDownTimer? = null
fun autoConnectBleDevice(context: Context) {
//判断蓝牙是否打开
if (!SRBleUtil.instance.isBleEnable(context)) {
LogUtil.e("automaticConnection,蓝牙没打开")
return
}
if (BleManager.getInstance().scanSate == BleScanState.STATE_SCANNING) {
LogUtil.e("automaticConnection,已经在扫描蓝牙,开始扫描失败")
return
}
viewModelScope.launch(Dispatchers.IO) {
val localDevices = MyDatabase.deviceDao()
.findAll(MyDatabase.DEVICE_TABLE) as MutableList<DeviceBean>
LogUtil.e("查找本地ble设备有${localDevices.size}个")
if (localDevices.size == 0) {
return@launch
}
val scanTrackBle = mutableListOf<BleDevice>()
val scanRuleConfig = BleScanRuleConfig.Builder().build()
BleManager.getInstance().initScanRule(scanRuleConfig)
BleManager.getInstance().scan(object : BleScanCallback() {
override fun onScanStarted(success: Boolean) {
SRBleUtil.instance.isScanInterrupt = false
LogUtil.e("开始扫描...$success")
}
override fun onScanning(bleDevice: BleDevice?) {
LogUtil.d("onScanning....$bleDevice")
bleDevice?.apply {
if (null != name && name.contains(SRBleUtil.instance.trackDeviceBleStartName)) {
scanTrackBle.add(this)
}
}
}
override fun onScanFinished(scanResultList: MutableList<BleDevice>?) {
val interrupt = SRBleUtil.instance.isScanInterrupt
LogUtil.e("automaticConnection--扫描完成..中断扫描$interrupt,${scanResultList?.size}")
if (!interrupt) {
compareDevice(scanTrackBle, localDevices)
}
}
})
}
}
/**
* 从扫描到的设备中查找已添加的设备,并连接设备
*/
private fun compareDevice(
scanResultList: MutableList<BleDevice>, localDevices: MutableList<DeviceBean>
) {
if (scanResultList.size > 0) {
var connected = false
viewModelScope.launch(Dispatchers.IO) {
//创建新的变量,防止别的蓝牙扫描(蓝牙找设备功能)改变scanResultList变量,导致异常
val scanBleList = mutableListOf<BleDevice>()
scanBleList.addAll(scanResultList)
for (device in localDevices) {
for (bleDevice in scanBleList) {
if (!TextUtils.isEmpty(bleDevice.name)) {
if (device.macId == bleDevice.mac) {
SRBleUtil.instance.connect(bleDevice)
connected = true
break
}
}
}
}
if (!connected) {
LogUtil.e("没有蓝牙设备可连")
SRBleUtil.instance.isBleConnecting = false
// XEventBus.post(EventName.ActionConDeviceState, ConState.DEVICE_NOT_FOUND)
}
}
} else {
LogUtil.e("蓝牙设备为0")
SRBleUtil.instance.isBleConnecting = false
// XEventBus.post(EventName.ActionConDeviceState, ConState.DEVICE_NOT_FOUND)
}
}
/**
* 连接中倒计时20s变为未连接状态
*/

View File

@@ -9,6 +9,7 @@ import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.baselibrary.util.rsa.RSA
import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.bean.OrderBean
import com.abbidot.tracker.bean.PayResultBean
import com.abbidot.tracker.bean.PaymentIDBean
import com.abbidot.tracker.bean.StripeSubscriptionPriceBean
@@ -30,6 +31,8 @@ class SubscriptionPayViewModel : ViewModel() {
val mCreatePaypalOrderLiveData = MutableLiveData<Result<PayResultBean>>()
val mPaymentMethodIDLiveData = MutableLiveData<Result<PaymentIDBean>>()
val mSavePaymentMethodIDLiveData = MutableLiveData<Result<String>>()
val mOrderAutoRenewalStatusLiveData = MutableLiveData<Result<OrderBean>>()
val mRemovePaymentMethodLiveData = MutableLiveData<Result<String>>()
/**
* Stripe支付创建消费用户
@@ -88,4 +91,27 @@ class SubscriptionPayViewModel : ViewModel() {
mSavePaymentMethodIDLiveData.value = result
}
}
/**
*获取用户订单中是否存在开启自动续订状态
*/
fun getOrderAutoRenewalStatus() {
viewModelScope.launch {
val userId = MMKVUtil.getString(MMKVKey.UserId)
val result = NetworkApi.getOrderAutoRenewalStatus(userId)
mOrderAutoRenewalStatusLiveData.value = result
}
}
/**
*移除用户支付信息
* paymentMethodType=1为信用卡 2为PayPal
*/
fun removePaymentMethodID(paymentMethodType: Int) {
viewModelScope.launch {
val userId = MMKVUtil.getString(MMKVKey.UserId)
val result = NetworkApi.removePaymentMethodID(userId, paymentMethodType)
mRemovePaymentMethodLiveData.value = result
}
}
}

View File

@@ -4,63 +4,63 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog"
android:paddingStart="@dimen/dp_8"
android:paddingEnd="@dimen/dp_8">
android:gravity="center"
android:paddingHorizontal="@dimen/dp_8">
<com.abbidot.tracker.widget.TypefaceTextView
android:id="@+id/my_dialog_title"
style="@style/my_TextView_style"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginBottom="@dimen/dp_10"
android:text="@string/app_name"
android:textSize="@dimen/textSize18"
android:visibility="invisible"
android:visibility="gone"
app:typeface="@string/roboto_bold_font" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<com.abbidot.tracker.widget.TypefaceTextView
android:id="@+id/my_dialog_content"
style="@style/my_TextView_style"
android:layout_marginTop="@dimen/dp_4"
android:paddingStart="@dimen/dp_28"
android:paddingEnd="@dimen/dp_28"
android:text="fdgdgdfgdfgdfgdf dfgdf gdfgdfgdfgdf dfgdf gdfgdfgdf dfgdf gdfgdfgdf dfgdf gdfgh dfhg df "
android:textSize="@dimen/textSize16"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceTextView
android:id="@+id/my_dialog_content"
style="@style/my_TextView_style"
android:layout_below="@id/my_dialog_title"
android:layout_marginTop="@dimen/dp_4"
android:paddingStart="@dimen/dp_28"
android:paddingEnd="@dimen/dp_28"
android:text="fdgdgdfgdfgdfgdf dfgdf gdfgdfgdfgdf dfgdf gdfgdfgdf dfgdf gdfgdfgdf dfgdf gdfgh dfhg df "
android:textSize="@dimen/textSize16"
app:lineHeight="@dimen/dp_18"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/my_dialog_cancel"
style="@style/my_QMUIRoundButton_big_style"
android:layout_width="@dimen/dp_110"
android:layout_height="@dimen/dp_42"
android:layout_below="@id/my_dialog_content"
android:layout_alignParentStart="true"
android:layout_marginStart="@dimen/dp_36"
android:layout_marginTop="@dimen/dp_36"
android:text="@string/tracker_activate_no"
android:textSize="@dimen/textSize14"
app:qmui_borderColor="@color/txt_button"
app:qmui_borderWidth="0.55dp"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/my_dialog_cancel"
style="@style/my_QMUIRoundButton_big_style"
android:layout_width="@dimen/dp_110"
android:layout_height="@dimen/dp_42"
android:layout_below="@id/my_dialog_content"
android:layout_alignParentStart="true"
android:layout_marginStart="@dimen/dp_36"
android:layout_marginTop="@dimen/dp_30"
android:text="@string/tracker_activate_no"
android:textSize="@dimen/textSize14"
app:qmui_borderColor="@color/txt_button"
app:qmui_borderWidth="0.55dp"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/my_dialog_ok"
style="@style/my_QMUIRoundButton_big_style"
android:layout_width="@dimen/dp_110"
android:layout_height="@dimen/dp_42"
android:layout_alignTop="@id/my_dialog_cancel"
android:layout_alignBottom="@id/my_dialog_cancel"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/dp_36"
android:text="@string/txt_ok"
android:textSize="@dimen/textSize14"
app:qmui_backgroundColor="@color/btn_yellow_color"
app:typeface="@string/roboto_bold_font" />
</RelativeLayout>
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/my_dialog_ok"
style="@style/my_QMUIRoundButton_big_style"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_42"
android:layout_alignTop="@id/my_dialog_cancel"
android:layout_alignBottom="@id/my_dialog_cancel"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/dp_36"
android:minWidth="@dimen/dp_110"
android:paddingHorizontal="@dimen/dp_8"
android:text="@string/txt_ok"
android:textSize="@dimen/textSize14"
app:qmui_backgroundColor="@color/btn_yellow_color"
app:typeface="@string/roboto_bold_font" />
</RelativeLayout>

View File

@@ -27,15 +27,38 @@
app:qmui_borderWidth="@dimen/dp_1"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceButton
android:id="@+id/btn_make_payment_credit_card"
style="@style/my_match_RoundRect_Button_style"
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll_payment_card_action_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginHorizontal="@dimen/dp_16"
android:text="@string/txt_make_payment"
android:visibility="gone"
app:qmui_radius="@dimen/dp_64"
app:typeface="@string/roboto_bold_font" />
android:gravity="center_horizontal"
android:orientation="vertical">
<com.abbidot.tracker.widget.TypefaceButton
android:id="@+id/btn_make_payment_credit_card"
style="@style/my_match_RoundRect_Button_style"
android:text="@string/txt_make_payment"
android:visibility="gone"
app:qmui_radius="@dimen/dp_64"
app:typeface="@string/roboto_bold_font" />
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/btn_credit_card_payment_remove"
style="@style/my_QMUIRoundButton_very_small_style"
android:layout_marginTop="@dimen/dp_16"
android:layout_marginBottom="@dimen/dp_68"
android:text="@string/txt_remove_pay_method"
android:textColor="@color/btn_color"
android:textSize="@dimen/textSize14"
android:visibility="gone"
app:qmui_backgroundColor="@color/chart_line_e5e5"
app:qmui_borderWidth="0dp"
app:qmui_radius="@dimen/dp_64"
app:typeface="@string/roboto_regular_font" />
</androidx.appcompat.widget.LinearLayoutCompat>
<include
android:id="@+id/il_credit_card_payment_no_data"
@@ -46,7 +69,7 @@
android:id="@+id/rv_credit_card_payment_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/btn_make_payment_credit_card"
android:layout_above="@id/ll_payment_card_action_layout"
android:layout_below="@id/btn_credit_card_payment_add"
android:layout_marginTop="@dimen/dp_12"
android:visibility="gone" />

View File

@@ -21,12 +21,12 @@
android:id="@+id/tv_paypal_payment_email"
style="@style/my_TextView_style_v2"
android:layout_width="match_parent"
android:gravity="start|center"
android:layout_marginHorizontal="@dimen/dp_16"
android:layout_height="@dimen/dp_56"
android:layout_marginHorizontal="@dimen/dp_16"
android:background="@drawable/shape8_dark_gray_border_white_yellow_bg"
android:drawableStart="@drawable/icon_payment_paypal_svg"
android:drawablePadding="@dimen/dp_6"
android:gravity="start|center"
android:paddingStart="@dimen/dp_20"
android:text="@string/app_name"
android:textSize="@dimen/textSize16"
@@ -61,4 +61,18 @@
android:layout_centerHorizontal="true"
android:src="@drawable/icon_payment_paypal_svg" />
<com.abbidot.tracker.widget.TypefaceRoundButton
android:id="@+id/btn_paypal_payment_remove"
style="@style/my_QMUIRoundButton_very_small_style"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/dp_68"
android:text="@string/txt_remove_pay_method"
android:textColor="@color/btn_color"
android:textSize="@dimen/textSize14"
android:visibility="gone"
app:qmui_backgroundColor="@color/chart_line_e5e5"
app:qmui_borderWidth="0dp"
app:qmui_radius="@dimen/dp_64"
app:typeface="@string/roboto_regular_font" />
</RelativeLayout>

View File

@@ -897,5 +897,13 @@
<string name="txt_terms_html">terms_de.html</string>
<string name="txt_privacy_html">privacy_de.html</string>
<string name="txt_subscription_terms_conditions_html">subscription_terms_conditions_de.html</string>
<string name="system_txt_copyright">Copyright © %d ABBIDOT. Alle Rechte vorbehalten</string>
<string name="txt_login_info_invalid">Sitzung abgelaufen. Bitte erneut anmelden</string>
<string name="txt_remove_pay_method">Zahlungsmethode entfernen</string>
<string name="txt_remove_pay_method_tips1">Möchten Sie diese Zahlungsmethode wirklich entfernen?</string>
<string name="txt_remove_pay_method_tips2">Bitte deaktivieren Sie die automatische Verlängerung, bevor Sie Ihre Zahlungsmethode entfernen.</string>
<string name="txt_auto_renewal_on">Automatische Verlängerung ist aktiviert</string>
<string name="txt_remove">Entfernen</string>
<string name="txt_turn_off_remove">Deaktivieren &amp; entfernen</string>
</resources>

View File

@@ -899,4 +899,11 @@
<string name="txt_privacy_html">privacy_fr.html</string>
<string name="txt_subscription_terms_conditions_html">subscription_terms_conditions_fr.html</string>
<string name="txt_login_info_invalid">Session expirée. Veuillez vous reconnecter</string>
<string name="txt_remove_pay_method">Supprimer le mode de paiement</string>
<string name="txt_remove_pay_method_tips1">Voulez-vous vraiment supprimer ce mode de paiement ?</string>
<string name="txt_remove_pay_method_tips2">Veuillez désactiver le renouvellement automatique avant de supprimer votre mode de paiement.</string>
<string name="txt_auto_renewal_on">Renouvellement automatique activé</string>
<string name="txt_remove">Supprimer</string>
<string name="txt_turn_off_remove">Désactiver et supprimer</string>
</resources>

File diff suppressed because it is too large Load Diff

View File

@@ -942,4 +942,10 @@
<string name="txt_privacy_html">privacy_zh.html</string>
<string name="txt_subscription_terms_conditions_html">subscription_terms_conditions_zh.html</string>
<string name="txt_login_info_invalid">登录信息失效,请重新登录</string>
<string name="txt_remove_pay_method">移除支付方式</string>
<string name="txt_remove_pay_method_tips1">确定要移除该支付方式吗?</string>
<string name="txt_remove_pay_method_tips2">移除支付方式前,请先关闭自动续订。</string>
<string name="txt_auto_renewal_on">自动续订已开启</string>
<string name="txt_remove">移除</string>
<string name="txt_turn_off_remove">关闭并移除</string>
</resources>

View File

@@ -993,4 +993,10 @@
<string name="txt_privacy_html">privacy_en.html</string>
<string name="txt_subscription_terms_conditions_html">subscription_terms_conditions_en.html</string>
<string name="txt_login_info_invalid">Login session expired. Please log in again</string>
<string name="txt_remove_pay_method">Remove Payment Method</string>
<string name="txt_remove_pay_method_tips1">Are you sure you want to remove this payment method?</string>
<string name="txt_remove_pay_method_tips2">Please turn off auto-renewal before removing your payment method.</string>
<string name="txt_auto_renewal_on">Auto-Renewal Is On</string>
<string name="txt_remove">Remove</string>
<string name="txt_turn_off_remove">Turn Off &amp; Remove</string>
</resources>

View File

@@ -94,7 +94,7 @@ class AppUtils {
* 是否是国内
*/
fun isChina(type: String = SWITCH_PAGE_TYPE): Boolean {
return true
return false
if (isDebug()) {
if (type == SWITCH_MAP_TYPE && MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)) {
//只启用谷歌地图