Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
F
File Recovery RecycleBin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
File Recovery RecycleBin
Commits
83fae7df
Commit
83fae7df
authored
Jul 26, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
....
parent
2beef962
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
685 additions
and
619 deletions
+685
-619
build.gradle
app/build.gradle
+2
-1
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+0
-3
MyApplication.kt
...ain/java/com/base/filerecoveryrecyclebin/MyApplication.kt
+0
-3
RepeatActivity.kt
.../filerecoveryrecyclebin/activity/repeat/RepeatActivity.kt
+0
-3
AdDisplayUtils.java
...a/com/base/filerecoveryrecyclebin/ads/AdDisplayUtils.java
+158
-91
AdmobMaxHelper.kt
...ava/com/base/filerecoveryrecyclebin/ads/AdmobMaxHelper.kt
+3
-1
AdMaxInterstitialUtils.kt
.../filerecoveryrecyclebin/ads/max/AdMaxInterstitialUtils.kt
+1
-0
AdMaxOpenUtils.kt
...com/base/filerecoveryrecyclebin/ads/max/AdMaxOpenUtils.kt
+1
-0
BillingActivity.kt
...om/base/filerecoveryrecyclebin/billing/BillingActivity.kt
+17
-17
BillingClientLifecycle.kt
.../filerecoveryrecyclebin/billing/BillingClientLifecycle.kt
+269
-269
BillingUtilities.kt
...m/base/filerecoveryrecyclebin/billing/BillingUtilities.kt
+170
-170
BillingViewModel.kt
...m/base/filerecoveryrecyclebin/billing/BillingViewModel.kt
+49
-49
MessagingService.java
...com/base/filerecoveryrecyclebin/fcm/MessagingService.java
+2
-3
NewComUtils.kt
...java/com/base/filerecoveryrecyclebin/utils/NewComUtils.kt
+9
-5
build.gradle
build.gradle
+2
-2
libs.versions.toml
gradle/libs.versions.toml
+1
-1
gradle-wrapper.properties
gradle/wrapper/gradle-wrapper.properties
+1
-1
No files found.
app/build.gradle
View file @
83fae7df
...
@@ -107,8 +107,9 @@ dependencies {
...
@@ -107,8 +107,9 @@ dependencies {
//firebase
//firebase
implementation
platform
(
'com.google.firebase:firebase-bom:32.3.1'
)
implementation
platform
(
'com.google.firebase:firebase-bom:32.3.1'
)
implementation
'com.google.firebase:firebase-analytics:21.6.2'
implementation
(
"com.google.firebase:firebase-messaging"
)
implementation
(
"com.google.firebase:firebase-messaging"
)
implementation
'com.google.firebase:firebase-crashlytics'
implementation
'com.google.firebase:firebase-analytics:21.6.2'
//google 内购订阅
//google 内购订阅
...
...
app/src/main/AndroidManifest.xml
View file @
83fae7df
...
@@ -25,9 +25,6 @@
...
@@ -25,9 +25,6 @@
android:supportsRtl=
"true"
android:supportsRtl=
"true"
android:theme=
"@style/Theme.DataRecovery"
android:theme=
"@style/Theme.DataRecovery"
tools:targetApi=
"34"
>
tools:targetApi=
"34"
>
<activity
android:name=
".billing.BillingActivity"
android:exported=
"false"
/>
<activity
<activity
android:name=
".activity.SplashActivity"
android:name=
".activity.SplashActivity"
android:exported=
"true"
android:exported=
"true"
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/MyApplication.kt
View file @
83fae7df
...
@@ -9,7 +9,6 @@ import com.base.filerecoveryrecyclebin.activity.SplashActivity
...
@@ -9,7 +9,6 @@ import com.base.filerecoveryrecyclebin.activity.SplashActivity
import
com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import
com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobOpenUtils
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobOpenUtils
import
com.base.filerecoveryrecyclebin.bean.ConstObject.ifAgreePrivacy
import
com.base.filerecoveryrecyclebin.bean.ConstObject.ifAgreePrivacy
import
com.base.filerecoveryrecyclebin.billing.BillingClientLifecycle
import
com.base.filerecoveryrecyclebin.fcm.FCMManager
import
com.base.filerecoveryrecyclebin.fcm.FCMManager
import
com.base.filerecoveryrecyclebin.fcm.RecoveryTimerManager
import
com.base.filerecoveryrecyclebin.fcm.RecoveryTimerManager
import
com.base.filerecoveryrecyclebin.fcm.ScreenStatusReceiver
import
com.base.filerecoveryrecyclebin.fcm.ScreenStatusReceiver
...
@@ -32,8 +31,6 @@ class MyApplication : BaseApplication() {
...
@@ -32,8 +31,6 @@ class MyApplication : BaseApplication() {
private
val
TAG
=
"MyApplication"
private
val
TAG
=
"MyApplication"
var
uuid
=
""
var
uuid
=
""
val
billingClientLifecycle
:
BillingClientLifecycle
get
()
=
BillingClientLifecycle
.
getInstance
(
this
)
companion
object
{
companion
object
{
@JvmField
@JvmField
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/activity/repeat/RepeatActivity.kt
View file @
83fae7df
...
@@ -7,10 +7,7 @@ import androidx.core.view.updatePadding
...
@@ -7,10 +7,7 @@ import androidx.core.view.updatePadding
import
androidx.lifecycle.lifecycleScope
import
androidx.lifecycle.lifecycleScope
import
com.base.filerecoveryrecyclebin.adapter.MediaAdapter
import
com.base.filerecoveryrecyclebin.adapter.MediaAdapter
import
com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import
com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobInterstitialUtils
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobInterstitialUtils.showInterAdSp
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobInterstitialUtils.showInterAdSp
import
com.base.filerecoveryrecyclebin.ads.admob.AdmobNativeUtils
import
com.base.filerecoveryrecyclebin.ads.max.AdMaxInterstitialUtils
import
com.base.filerecoveryrecyclebin.bean.MediaBean
import
com.base.filerecoveryrecyclebin.bean.MediaBean
import
com.base.filerecoveryrecyclebin.bean.MediaTimeBean
import
com.base.filerecoveryrecyclebin.bean.MediaTimeBean
import
com.base.filerecoveryrecyclebin.databinding.ActivityRepeatBinding
import
com.base.filerecoveryrecyclebin.databinding.ActivityRepeatBinding
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/ads/AdDisplayUtils.java
View file @
83fae7df
...
@@ -6,6 +6,7 @@ import android.util.Log;
...
@@ -6,6 +6,7 @@ import android.util.Log;
import
com.base.filerecoveryrecyclebin.BuildConfig
;
import
com.base.filerecoveryrecyclebin.BuildConfig
;
import
com.base.filerecoveryrecyclebin.help.BaseApplication
;
import
com.base.filerecoveryrecyclebin.help.BaseApplication
;
import
com.base.filerecoveryrecyclebin.utils.AppPreferences
;
import
com.base.filerecoveryrecyclebin.utils.EventUtils
;
import
com.base.filerecoveryrecyclebin.utils.EventUtils
;
import
com.base.filerecoveryrecyclebin.utils.LogEx
;
import
com.base.filerecoveryrecyclebin.utils.LogEx
;
...
@@ -18,37 +19,47 @@ import java.util.Date;
...
@@ -18,37 +19,47 @@ import java.util.Date;
import
java.util.Locale
;
import
java.util.Locale
;
public
class
AdDisplayUtils
{
public
class
AdDisplayUtils
{
private
static
final
int
DEFAULT_MAX_AD_DISPLAY_COUNT
=
45
;
// 总广告展示次数限制默认值
private
String
TAG
=
"AdDisplayUtils"
;
private
static
final
int
DEFAULT_MAX_AD_CLICK_COUNT
=
10
;
// 单个广告点击次数限制默认值
public
static
final
int
DEFAULT_MAX_AD_REQUEST_COUNT
=
100
;
// 广告请求次数限制默认值
private
static
final
int
DEFAULT_MAX_AD_REQUEST_FAIL_COUNT
=
20
;
// 单个广告点击次数限制默认值
public
static
final
int
DEFAULT_MAX_AD_REQUEST_FAIL_COUNT
=
20
;
// 单个广告点击次数限制默认值
public
static
final
int
DEFAULT_MAX_AD_DISPLAY_COUNT
=
45
;
// 总广告展示次数限制默认值
public
static
final
int
DEFAULT_MAX_AD_CLICK_COUNT
=
10
;
// 单个广告点击次数限制默认值
private
static
final
String
AD_PREFS_NAME
=
"ad_prefs"
;
// SharedPreferences 名称
private
static
final
String
AD_PREFS_NAME
=
"ad_prefs"
;
// SharedPreferences 名称
private
static
final
String
AD_DISPLAY_COUNT_KEY
=
"ad_display_count"
;
// 广告展示次数的键
private
static
final
String
AD_CLICK_COUNT_KEY
=
"ad_click_count"
;
// 广告点击次数的键
private
static
final
String
MAX_AD_DISPLAY_COUNT_KEY
=
"max_ad_display_count"
;
// 总广告展示次数限制的键
private
static
final
String
MAX_AD_CLICK_COUNT_KEY
=
"max_ad_click_count"
;
// 单个广告点击次数限制的键
private
static
final
String
MAX_AD_REQUEST_FAIL_COUNT_KEY
=
"max_ad_request_fail_count"
;
// 单个广告点击次数限制的键
private
static
final
String
AD_REQUEST_FAIL_COUNT_KEY
=
"ad_request_fail_count"
;
// 单个广告点击次数限制的键
private
static
AdDisplayUtils
instance
;
// 单例对象
private
static
AdDisplayUtils
instance
;
// 单例对象
private
int
adDisplayCount
=
0
;
// 当前广告展示次数
private
int
adClickCount
=
0
;
// 当前广告点击次数
private
int
maxAdDisplayCount
;
// 总广告展示次数限制
private
int
maxAdClickCount
;
// 单个广告点击次数限制
private
int
maxAdRequestFailCount
;
// 请求失败总
private
int
adRequestFailCount
=
0
;
// 请求失败当前
private
String
currentDate
;
// 当前日期
private
String
currentDate
;
// 当前日期
public
void
saveSp
()
{
this
.
maxAdRequestCount
=
Integer
.
parseInt
(
AppPreferences
.
getInstance
().
getString
(
"adMaxRequestCount"
,
String
.
valueOf
(
DEFAULT_MAX_AD_REQUEST_COUNT
)));
saveMaxAdRequestCount
();
this
.
maxAdRequestFailCount
=
Integer
.
parseInt
(
AppPreferences
.
getInstance
().
getString
(
"adRequestFailCount"
,
String
.
valueOf
(
DEFAULT_MAX_AD_REQUEST_FAIL_COUNT
)));
saveMaxAdRequestFailCount
();
this
.
maxAdDisplayCount
=
Integer
.
parseInt
(
AppPreferences
.
getInstance
().
getString
(
"adShowCount"
,
String
.
valueOf
(
DEFAULT_MAX_AD_DISPLAY_COUNT
)));
saveMaxAdDisplayCount
();
this
.
maxAdClickCount
=
Integer
.
parseInt
(
AppPreferences
.
getInstance
().
getString
(
"adClickCount"
,
String
.
valueOf
(
DEFAULT_MAX_AD_CLICK_COUNT
)));
saveMaxAdClickCount
();
}
private
AdDisplayUtils
()
{
private
AdDisplayUtils
()
{
currentDate
=
getCurrentDate
();
currentDate
=
getCurrentDate
();
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
maxAdRequestCount
=
prefs
.
getInt
(
MAX_AD_REQUEST_COUNT_KEY
,
DEFAULT_MAX_AD_REQUEST_COUNT
);
maxAdRequestFailCount
=
prefs
.
getInt
(
MAX_AD_REQUEST_FAIL_COUNT_KEY
,
DEFAULT_MAX_AD_REQUEST_FAIL_COUNT
);
maxAdDisplayCount
=
prefs
.
getInt
(
MAX_AD_DISPLAY_COUNT_KEY
,
DEFAULT_MAX_AD_DISPLAY_COUNT
);
maxAdDisplayCount
=
prefs
.
getInt
(
MAX_AD_DISPLAY_COUNT_KEY
,
DEFAULT_MAX_AD_DISPLAY_COUNT
);
maxAdClickCount
=
prefs
.
getInt
(
MAX_AD_CLICK_COUNT_KEY
,
DEFAULT_MAX_AD_CLICK_COUNT
);
maxAdClickCount
=
prefs
.
getInt
(
MAX_AD_CLICK_COUNT_KEY
,
DEFAULT_MAX_AD_CLICK_COUNT
);
maxAdRequestFailCount
=
prefs
.
getInt
(
MAX_AD_REQUEST_FAIL_COUNT_KEY
,
DEFAULT_MAX_AD_REQUEST_FAIL_COUNT
);
adRequestCount
=
prefs
.
getInt
(
getAdRequestCountKey
(),
0
);
adRequestFailCount
=
prefs
.
getInt
(
getAdRequestFailCountKey
(),
0
);
adDisplayCount
=
prefs
.
getInt
(
getAdDisplayCountKey
(),
0
);
adDisplayCount
=
prefs
.
getInt
(
getAdDisplayCountKey
(),
0
);
adClickCount
=
prefs
.
getInt
(
getAdClickCountKey
(),
0
);
adClickCount
=
prefs
.
getInt
(
getAdClickCountKey
(),
0
);
adRequestFailCount
=
prefs
.
getInt
(
getAdRequestFailCountKey
(),
0
);
}
}
public
static
synchronized
AdDisplayUtils
getInstance
()
{
public
static
synchronized
AdDisplayUtils
getInstance
()
{
...
@@ -58,53 +69,104 @@ public class AdDisplayUtils {
...
@@ -58,53 +69,104 @@ public class AdDisplayUtils {
return
instance
;
return
instance
;
}
}
public
boolean
should
DisplayAd
()
{
public
boolean
should
SendAdRequest
()
{
return
ad
DisplayCount
<
getMaxAdDisplayCount
()
;
return
ad
RequestCount
<
maxAdRequestCount
;
}
}
public
boolean
shouldIncrementRequestFailAd
()
{
public
boolean
shouldIncrementRequestFailAd
()
{
return
adRequestFailCount
<
getMaxAdRequestFailCount
();
return
adRequestFailCount
<
maxAdRequestFailCount
;
}
public
boolean
shouldDisplayAd
()
{
return
adDisplayCount
<
maxAdClickCount
;
}
}
public
boolean
shouldIncrementClickCount
()
{
public
boolean
shouldIncrementClickCount
()
{
return
adClickCount
<
getMaxAdClickCount
()
;
return
adClickCount
<
maxAdClickCount
;
}
}
public
boolean
shouldShowAd
(
String
ad_unit
)
{
public
boolean
shouldShowAd
(
String
ad_unit
)
{
if
(
BuildConfig
.
DEBUG
)
{
if
(
BuildConfig
.
DEBUG
)
{
return
true
;
return
true
;
}
}
boolean
s
=
shouldDisplayAd
()
&&
shouldIncrementClickCount
()
&&
shouldIncrementRequestFailAd
();
boolean
shouldDisplayAd
=
shouldDisplayAd
();
if
(!
s
)
{
boolean
shouldIncrementClickCount
=
shouldIncrementClickCount
();
boolean
shouldIncrementRequestFailAd
=
shouldIncrementRequestFailAd
();
boolean
shouldSendAdRequest
=
shouldSendAdRequest
();
LogEx
.
INSTANCE
.
logDebug
(
TAG
,
"shouldSendAdRequest="
+
shouldSendAdRequest
,
false
);
LogEx
.
INSTANCE
.
logDebug
(
TAG
,
"shouldIncrementRequestFailAd="
+
shouldIncrementRequestFailAd
,
false
);
LogEx
.
INSTANCE
.
logDebug
(
TAG
,
"shouldIncrementClickCount="
+
shouldIncrementClickCount
,
false
);
LogEx
.
INSTANCE
.
logDebug
(
TAG
,
"shouldDisplayAd="
+
shouldDisplayAd
,
false
);
boolean
show
=
shouldIncrementRequestFailAd
&&
shouldSendAdRequest
&&
shouldDisplayAd
&&
shouldIncrementClickCount
;
if
(!
show
)
{
LogEx
.
INSTANCE
.
logDebug
(
"glc"
,
"!shouldShowAd"
,
false
);
LogEx
.
INSTANCE
.
logDebug
(
"glc"
,
"!shouldShowAd"
,
false
);
JSONObject
obj2
=
new
JSONObject
();
JSONObject
obj2
=
new
JSONObject
();
try
{
try
{
obj2
.
put
(
"reason"
,
"ad limit"
);
obj2
.
put
(
"reason"
,
"ad limit"
);
obj2
.
put
(
"shouldSendAdRequest"
,
shouldSendAdRequest
);
obj2
.
put
(
"shouldIncrementRequestFailAd"
,
shouldIncrementRequestFailAd
);
obj2
.
put
(
"shouldDisplayAd"
,
shouldDisplayAd
);
obj2
.
put
(
"shouldIncrementClickCount"
,
shouldIncrementClickCount
);
obj2
.
put
(
"ad_unit"
,
ad_unit
);
obj2
.
put
(
"ad_unit"
,
ad_unit
);
EventUtils
.
INSTANCE
.
event
(
"ad_show_error"
,
null
,
obj2
,
false
);
EventUtils
.
INSTANCE
.
event
(
"ad_show_error"
,
null
,
obj2
,
false
);
}
catch
(
JSONException
e
)
{
}
catch
(
JSONException
ignored
)
{
}
}
}
}
return
s
;
return
s
how
;
}
}
public
void
incrementAdDisplayCount
()
{
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
//region AdRequestCount
currentDate
=
getCurrentDate
();
private
int
maxAdRequestCount
=
0
;
// 最大广告请求次数
adDisplayCount
=
0
;
private
int
adRequestCount
=
0
;
// 当前广告请求次数
}
private
static
final
String
MAX_AD_REQUEST_COUNT_KEY
=
"max_ad_request_count"
;
// 广告请求次数限制的键
adDisplayCount
++;
private
static
final
String
AD_REQUEST_COUNT_KEY
=
"ad_request_count"
;
//广告请求次数
saveAdDisplayCount
();
private
void
saveMaxAdRequestCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
MAX_AD_REQUEST_COUNT_KEY
,
maxAdRequestCount
);
editor
.
apply
();
}
}
public
void
incrementAd
Click
Count
()
{
public
void
incrementAd
Request
Count
()
{
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
currentDate
=
getCurrentDate
();
currentDate
=
getCurrentDate
();
ad
Click
Count
=
0
;
ad
Request
Count
=
0
;
}
}
adClickCount
++;
adRequestCount
++;
saveAdClickCount
();
saveAdRequestCount
();
}
private
String
getAdRequestCountKey
()
{
return
AD_REQUEST_COUNT_KEY
+
"_"
+
currentDate
;
}
private
void
saveAdRequestCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
getAdRequestCountKey
(),
adRequestCount
);
editor
.
apply
();
}
//endregion
//region AdRequestFailCount
private
int
maxAdRequestFailCount
;
// 请求失败总
private
int
adRequestFailCount
=
0
;
// 请求失败当前
private
static
final
String
MAX_AD_REQUEST_FAIL_COUNT_KEY
=
"max_ad_request_fail_count"
;
// 单个广告点击次数限制的键
private
static
final
String
AD_REQUEST_FAIL_COUNT_KEY
=
"ad_request_fail_count"
;
// 单个广告点击次数限制的键
private
void
saveMaxAdRequestFailCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
MAX_AD_REQUEST_FAIL_COUNT_KEY
,
maxAdRequestFailCount
);
editor
.
apply
();
}
}
public
void
incrementAdRequestFailCount
()
{
public
void
incrementAdRequestFailCount
()
{
...
@@ -117,68 +179,60 @@ public class AdDisplayUtils {
...
@@ -117,68 +179,60 @@ public class AdDisplayUtils {
Log
.
d
(
"glc"
,
"广告请求失败:"
+
adRequestFailCount
);
Log
.
d
(
"glc"
,
"广告请求失败:"
+
adRequestFailCount
);
}
}
private
String
getAdRequestFailCountKey
()
{
public
void
setAdClickCount
(
int
s
)
{
return
AD_REQUEST_FAIL_COUNT_KEY
+
"_"
+
currentDate
;
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
currentDate
=
getCurrentDate
();
adClickCount
=
0
;
}
adClickCount
=
s
;
saveAdClickCount
();
}
public
String
getCurrentDate
()
{
SimpleDateFormat
dateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
,
Locale
.
getDefault
());
Date
currentDate
=
Calendar
.
getInstance
().
getTime
();
return
dateFormat
.
format
(
currentDate
);
}
private
String
getAdDisplayCountKey
()
{
return
AD_DISPLAY_COUNT_KEY
+
"_"
+
currentDate
;
}
private
String
getAdClickCountKey
()
{
return
AD_CLICK_COUNT_KEY
+
"_"
+
currentDate
;
}
}
private
void
saveAd
Display
Count
()
{
private
void
saveAd
RequestFail
Count
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
getAd
DisplayCountKey
(),
adDisplay
Count
);
editor
.
putInt
(
getAd
RequestFailCountKey
(),
adRequestFail
Count
);
editor
.
apply
();
editor
.
apply
();
}
}
//endregion
private
void
saveAdClickCount
()
{
//region AdDisplayCount
private
int
maxAdDisplayCount
;
// 总广告展示次数限制
private
int
adDisplayCount
=
0
;
// 当前广告展示次数
private
static
final
String
MAX_AD_DISPLAY_COUNT_KEY
=
"max_ad_display_count"
;
// 总广告展示次数限制的键
private
static
final
String
AD_DISPLAY_COUNT_KEY
=
"ad_display_count"
;
// 广告展示次数的键
private
void
saveMaxAdDisplayCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
getAdClickCountKey
(),
adClick
Count
);
editor
.
putInt
(
MAX_AD_DISPLAY_COUNT_KEY
,
maxAdDisplay
Count
);
editor
.
apply
();
editor
.
apply
();
}
}
p
rivate
int
getMax
AdDisplayCount
()
{
p
ublic
void
increment
AdDisplayCount
()
{
return
maxAdDisplayCount
;
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
}
currentDate
=
getCurrentDate
();
adDisplayCount
=
0
;
public
void
setMaxAdDisplayCount
(
int
maxAdDisplayCount
)
{
}
this
.
maxAdDisplayCount
=
maxAdDisplayCount
;
adDisplayCount
++
;
save
Max
AdDisplayCount
();
saveAdDisplayCount
();
}
}
public
int
getMaxAdClickCount
()
{
return
maxAdClickCount
;
}
public
void
setMaxAdClickCount
(
int
maxAdClickCount
)
{
private
String
getAdDisplayCountKey
()
{
this
.
maxAdClickCount
=
maxAdClickCount
;
return
AD_DISPLAY_COUNT_KEY
+
"_"
+
currentDate
;
saveMaxAdClickCount
();
}
}
private
void
save
Max
AdDisplayCount
()
{
private
void
saveAdDisplayCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
MAX_AD_DISPLAY_COUNT_KEY
,
maxA
dDisplayCount
);
editor
.
putInt
(
getAdDisplayCountKey
(),
a
dDisplayCount
);
editor
.
apply
();
editor
.
apply
();
}
}
//endregion
//region AdClickCount
public
int
maxAdClickCount
;
// 单个广告点击次数限制
private
int
adClickCount
=
0
;
// 当前广告点击次数
private
static
final
String
MAX_AD_CLICK_COUNT_KEY
=
"max_ad_click_count"
;
// 单个广告点击次数限制的键
private
static
final
String
AD_CLICK_COUNT_KEY
=
"ad_click_count"
;
// 广告点击次数的键
private
void
saveMaxAdClickCount
()
{
private
void
saveMaxAdClickCount
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
...
@@ -187,30 +241,43 @@ public class AdDisplayUtils {
...
@@ -187,30 +241,43 @@ public class AdDisplayUtils {
editor
.
apply
();
editor
.
apply
();
}
}
public
int
getMaxAdRequestFailCount
()
{
return
maxAdRequestFailCount
;
public
void
incrementAdClickCount
()
{
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
currentDate
=
getCurrentDate
();
adClickCount
=
0
;
}
adClickCount
++;
saveAdClickCount
();
}
}
public
void
setMaxAdRequestFailCount
(
int
maxAdRequestFailCount
)
{
private
String
getAdClickCountKey
()
{
this
.
maxAdRequestFailCount
=
maxAdRequestFailCount
;
return
AD_CLICK_COUNT_KEY
+
"_"
+
currentDate
;
saveMaxAdRequestFailCount
();
}
}
private
void
saveMaxAdRequestFailCount
()
{
public
void
setAdClickCount
(
int
s
)
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
if
(!
currentDate
.
equals
(
getCurrentDate
()))
{
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
currentDate
=
getCurrentDate
();
editor
.
putInt
(
MAX_AD_REQUEST_FAIL_COUNT_KEY
,
maxAdRequestFailCount
);
adClickCount
=
0
;
editor
.
apply
();
}
adClickCount
=
s
;
saveAdClickCount
();
}
}
private
void
saveAd
RequestFail
Count
()
{
private
void
saveAd
Click
Count
()
{
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
prefs
=
BaseApplication
.
context
.
getSharedPreferences
(
AD_PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
SharedPreferences
.
Editor
editor
=
prefs
.
edit
();
editor
.
putInt
(
getAd
RequestFailCountKey
(),
adRequestFail
Count
);
editor
.
putInt
(
getAd
ClickCountKey
(),
adClick
Count
);
editor
.
apply
();
editor
.
apply
();
}
}
//endregion
private
String
getAdRequestFailCountKey
()
{
return
AD_REQUEST_FAIL_COUNT_KEY
+
"_"
+
currentDate
;
public
String
getCurrentDate
()
{
SimpleDateFormat
dateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
,
Locale
.
getDefault
());
Date
currentDate
=
Calendar
.
getInstance
().
getTime
();
return
dateFormat
.
format
(
currentDate
);
}
}
}
}
app/src/main/java/com/base/filerecoveryrecyclebin/ads/AdmobMaxHelper.kt
View file @
83fae7df
...
@@ -21,6 +21,8 @@ object AdmobMaxHelper {
...
@@ -21,6 +21,8 @@ object AdmobMaxHelper {
private
val
TAG
=
"AdmobMaxHelper"
private
val
TAG
=
"AdmobMaxHelper"
var
isAdInit
=
AtomicBoolean
(
false
)
var
isAdInit
=
AtomicBoolean
(
false
)
//Begin
fun
initAdmobMaxAd
()
{
fun
initAdmobMaxAd
()
{
if
(
ConfigHelper
.
admobTrueMaxFlase
)
{
if
(
ConfigHelper
.
admobTrueMaxFlase
)
{
if
(!
isAdInit
.
get
())
{
if
(!
isAdInit
.
get
())
{
...
@@ -34,7 +36,7 @@ object AdmobMaxHelper {
...
@@ -34,7 +36,7 @@ object AdmobMaxHelper {
}
}
}
}
}
}
//End end
fun
isOpenAdLoaded
():
Boolean
{
fun
isOpenAdLoaded
():
Boolean
{
return
if
(
ConfigHelper
.
admobTrueMaxFlase
)
{
return
if
(
ConfigHelper
.
admobTrueMaxFlase
)
{
AdmobOpenUtils
.
isOpenAdLoaded
()
AdmobOpenUtils
.
isOpenAdLoaded
()
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/ads/max/AdMaxInterstitialUtils.kt
View file @
83fae7df
...
@@ -182,6 +182,7 @@ object AdMaxInterstitialUtils {
...
@@ -182,6 +182,7 @@ object AdMaxInterstitialUtils {
obj
.
put
(
"ad_type"
,
"interAd"
)
obj
.
put
(
"ad_type"
,
"interAd"
)
EventUtils
.
event
(
"ad_pull_start"
,
ext
=
obj
)
EventUtils
.
event
(
"ad_pull_start"
,
ext
=
obj
)
interstitialAd
?.
loadAd
()
interstitialAd
?.
loadAd
()
AdDisplayUtils
.
getInstance
().
incrementAdRequestCount
()
return
true
return
true
}
}
return
false
return
false
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/ads/max/AdMaxOpenUtils.kt
View file @
83fae7df
...
@@ -170,6 +170,7 @@ object AdMaxOpenUtils {
...
@@ -170,6 +170,7 @@ object AdMaxOpenUtils {
obj
.
put
(
"ad_type"
,
"openAd"
)
obj
.
put
(
"ad_type"
,
"openAd"
)
EventUtils
.
event
(
"ad_pull_start"
,
ext
=
obj
)
EventUtils
.
event
(
"ad_pull_start"
,
ext
=
obj
)
appOpenAd
?.
loadAd
()
appOpenAd
?.
loadAd
()
AdDisplayUtils
.
getInstance
().
incrementAdRequestCount
()
return
true
return
true
}
}
return
false
return
false
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/billing/BillingActivity.kt
View file @
83fae7df
package
com.base.filerecoveryrecyclebin.billing
//package com.base.filerecoveryrecyclebin.billing
//
import
com.base.filerecoveryrecyclebin.databinding.ActivityBillingBinding
//import com.base.filerecoveryrecyclebin.databinding.ActivityBillingBinding
import
com.base.filerecoveryrecyclebin.help.BaseActivity
//import com.base.filerecoveryrecyclebin.help.BaseActivity
//
class
BillingActivity
:
BaseActivity
<
ActivityBillingBinding
>()
{
//class BillingActivity : BaseActivity<ActivityBillingBinding>() {
//
override
val
binding
:
ActivityBillingBinding
by
lazy
{
// override val binding: ActivityBillingBinding by lazy {
ActivityBillingBinding
.
inflate
(
layoutInflater
)
// ActivityBillingBinding.inflate(layoutInflater)
}
// }
//
//
override
fun
initView
()
{
// override fun initView() {
//
}
// }
//
}
//}
\ No newline at end of file
\ No newline at end of file
app/src/main/java/com/base/filerecoveryrecyclebin/billing/BillingClientLifecycle.kt
View file @
83fae7df
package
com.base.filerecoveryrecyclebin.billing
//package com.base.filerecoveryrecyclebin.billing
//
import
android.content.Context
//import android.content.Context
import
android.util.Log
//import android.util.Log
import
androidx.lifecycle.DefaultLifecycleObserver
//import androidx.lifecycle.DefaultLifecycleObserver
import
androidx.lifecycle.LifecycleOwner
//import androidx.lifecycle.LifecycleOwner
import
androidx.lifecycle.MutableLiveData
//import androidx.lifecycle.MutableLiveData
import
com.android.billingclient.api.BillingClient
//import com.android.billingclient.api.BillingClient
import
com.android.billingclient.api.BillingClientStateListener
//import com.android.billingclient.api.BillingClientStateListener
import
com.android.billingclient.api.BillingResult
//import com.android.billingclient.api.BillingResult
import
com.android.billingclient.api.ProductDetails
//import com.android.billingclient.api.ProductDetails
import
com.android.billingclient.api.ProductDetailsResponseListener
//import com.android.billingclient.api.ProductDetailsResponseListener
import
com.android.billingclient.api.Purchase
//import com.android.billingclient.api.Purchase
import
com.android.billingclient.api.PurchasesResponseListener
//import com.android.billingclient.api.PurchasesResponseListener
import
com.android.billingclient.api.PurchasesUpdatedListener
//import com.android.billingclient.api.PurchasesUpdatedListener
import
com.android.billingclient.api.QueryPurchasesParams
//import com.android.billingclient.api.QueryPurchasesParams
import
com.base.filerecoveryrecyclebin.bean.BiliConstants
//import com.base.filerecoveryrecyclebin.bean.BiliConstants
import
com.base.filerecoveryrecyclebin.bean.BillingResponse
//import com.base.filerecoveryrecyclebin.bean.BillingResponse
import
com.base.filerecoveryrecyclebin.help.BaseApplication
//import com.base.filerecoveryrecyclebin.help.BaseApplication
import
kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
//import kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.SupervisorJob
//import kotlinx.coroutines.SupervisorJob
import
kotlinx.coroutines.flow.MutableStateFlow
//import kotlinx.coroutines.flow.MutableStateFlow
import
kotlinx.coroutines.flow.asStateFlow
//import kotlinx.coroutines.flow.asStateFlow
import
kotlinx.coroutines.launch
//import kotlinx.coroutines.launch
//
class
BillingClientLifecycle
(
//class BillingClientLifecycle(
private
val
applicationContext
:
Context
,
// private val applicationContext: Context,
private
val
coroutineScope
:
CoroutineScope
=
CoroutineScope
(
SupervisorJob
()
+
Dispatchers
.
Default
)
// private val coroutineScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
)
:
DefaultLifecycleObserver
,
//) : DefaultLifecycleObserver,
PurchasesUpdatedListener
,
// PurchasesUpdatedListener,
BillingClientStateListener
,
// BillingClientStateListener,
PurchasesResponseListener
,
// PurchasesResponseListener,
ProductDetailsResponseListener
{
// ProductDetailsResponseListener {
//
private
val
TAG
=
"BillingClientLifecycle"
// private val TAG = "BillingClientLifecycle"
//
/**
// /**
* Instantiate a new BillingClient instance.
// * Instantiate a new BillingClient instance.
*/
// */
private
lateinit
var
billingClient
:
BillingClient
// private lateinit var billingClient: BillingClient
//
//订阅价格
// //订阅价格
private
val
_subscriptionPurchases
=
MutableStateFlow
<
List
<
Purchase
>>(
emptyList
())
// private val _subscriptionPurchases = MutableStateFlow<List<Purchase>>(emptyList())
val
subscriptionPurchases
=
_subscriptionPurchases
.
asStateFlow
()
// val subscriptionPurchases = _subscriptionPurchases.asStateFlow()
//
//基础商品信息
// //基础商品信息
val
basicSubProductWithProductDetails
=
MutableLiveData
<
ProductDetails
?>()
// val basicSubProductWithProductDetails = MutableLiveData<ProductDetails?>()
//
//高级商品信息
// //高级商品信息
val
premiumSubProductWithProductDetails
=
MutableLiveData
<
ProductDetails
?>()
// val premiumSubProductWithProductDetails = MutableLiveData<ProductDetails?>()
//
//
override
fun
onCreate
(
owner
:
LifecycleOwner
)
{
// override fun onCreate(owner: LifecycleOwner) {
Log
.
d
(
TAG
,
"onCreate"
)
// Log.d(TAG, "onCreate")
billingClient
=
BillingClient
.
newBuilder
(
BaseApplication
.
context
)
// billingClient = BillingClient.newBuilder(BaseApplication.context)
.
setListener
(
this
)
// .setListener(this)
// .enablePendingPurchases() // Not used for subscriptions.
//// .enablePendingPurchases() // Not used for subscriptions.
.
build
()
// .build()
if
(!
billingClient
.
isReady
)
{
// if (!billingClient.isReady) {
Log
.
d
(
TAG
,
"BillingClient: Start connection..."
)
// Log.d(TAG, "BillingClient: Start connection...")
billingClient
.
startConnection
(
this
)
// billingClient.startConnection(this)
}
// }
}
// }
//
override
fun
onDestroy
(
owner
:
LifecycleOwner
)
{
// override fun onDestroy(owner: LifecycleOwner) {
Log
.
d
(
TAG
,
"onDestroy"
)
// Log.d(TAG, "onDestroy")
if
(
billingClient
.
isReady
)
{
// if (billingClient.isReady) {
Log
.
d
(
TAG
,
"BillingClient can only be used once -- closing connection"
)
// Log.d(TAG, "BillingClient can only be used once -- closing connection")
// BillingClient can only be used once.
// // BillingClient can only be used once.
// After calling endConnection(), we must create a new BillingClient.
// // After calling endConnection(), we must create a new BillingClient.
billingClient
.
endConnection
()
// billingClient.endConnection()
}
// }
}
// }
//
/**
// /**
* 更新价格监听
// * 更新价格监听
* PurchasesUpdatedListener
// * PurchasesUpdatedListener
*/
// */
override
fun
onPurchasesUpdated
(
billingResult
:
BillingResult
,
purchases
:
MutableList
<
Purchase
>?)
{
// override fun onPurchasesUpdated(billingResult: BillingResult, purchases: MutableList<Purchase>?) {
val
responseCode
=
billingResult
.
responseCode
// val responseCode = billingResult.responseCode
val
debugMessage
=
billingResult
.
debugMessage
// val debugMessage = billingResult.debugMessage
//
Log
.
d
(
TAG
,
"onPurchasesUpdated: $responseCode $debugMessage"
)
// Log.d(TAG, "onPurchasesUpdated: $responseCode $debugMessage")
when
(
responseCode
)
{
// when (responseCode) {
BillingClient
.
BillingResponseCode
.
OK
->
{
// BillingClient.BillingResponseCode.OK -> {
if
(
purchases
==
null
)
{
// if (purchases == null) {
Log
.
d
(
TAG
,
"onPurchasesUpdated: null purchase list"
)
// Log.d(TAG, "onPurchasesUpdated: null purchase list")
processPurchases
(
null
)
// processPurchases(null)
}
else
{
// } else {
processPurchases
(
purchases
)
// processPurchases(purchases)
}
// }
}
// }
//
BillingClient
.
BillingResponseCode
.
USER_CANCELED
->
{
// BillingClient.BillingResponseCode.USER_CANCELED -> {
Log
.
i
(
TAG
,
"onPurchasesUpdated: User canceled the purchase"
)
// Log.i(TAG, "onPurchasesUpdated: User canceled the purchase")
}
// }
//
BillingClient
.
BillingResponseCode
.
ITEM_ALREADY_OWNED
->
{
// BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> {
Log
.
i
(
TAG
,
"onPurchasesUpdated: The user already owns this item"
)
// Log.i(TAG, "onPurchasesUpdated: The user already owns this item")
}
// }
//
BillingClient
.
BillingResponseCode
.
DEVELOPER_ERROR
->
{
// BillingClient.BillingResponseCode.DEVELOPER_ERROR -> {
Log
.
e
(
// Log.e(
TAG
,
"onPurchasesUpdated: Developer error means that Google Play does "
+
// TAG, "onPurchasesUpdated: Developer error means that Google Play does " +
"not recognize the configuration. If you are just getting started, "
+
// "not recognize the configuration. If you are just getting started, " +
"make sure you have configured the application correctly in the "
+
// "make sure you have configured the application correctly in the " +
"Google Play Console. The product ID must match and the APK you "
+
// "Google Play Console. The product ID must match and the APK you " +
"are using must be signed with release keys."
// "are using must be signed with release keys."
)
// )
}
// }
}
// }
}
// }
//
private
var
cachedPurchasesList
:
List
<
Purchase
>?
=
null
// private var cachedPurchasesList: List<Purchase>? = null
//
/**
// /**
* 重新发布价格
// * 重新发布价格
*/
// */
private
fun
processPurchases
(
purchasesList
:
List
<
Purchase
>?)
{
// private fun processPurchases(purchasesList: List<Purchase>?) {
purchasesList
?.
let
{
list
->
// purchasesList?.let { list ->
if
(
isUnchangedPurchaseList
(
list
))
{
// if (isUnchangedPurchaseList(list)) {
Log
.
d
(
TAG
,
"processPurchases: Purchase list has not changed"
)
// Log.d(TAG, "processPurchases: Purchase list has not changed")
return
// return
}
// }
//
coroutineScope
.
launch
{
// coroutineScope.launch {
val
subscriptionPurchaseList
=
list
.
filter
{
purchase
->
// val subscriptionPurchaseList = list.filter { purchase ->
purchase
.
products
.
any
{
product
->
// purchase.products.any { product ->
product
in
listOf
(
BiliConstants
.
PREMIUM_PRODUCT
,
BiliConstants
.
BASIC_PRODUCT
)
// product in listOf(BiliConstants.PREMIUM_PRODUCT, BiliConstants.BASIC_PRODUCT)
}
// }
}
// }
//
_subscriptionPurchases
.
emit
(
subscriptionPurchaseList
)
// _subscriptionPurchases.emit(subscriptionPurchaseList)
}
// }
}
// }
}
// }
//
/**
// /**
* 对比旧的价格
// * 对比旧的价格
*/
// */
private
fun
isUnchangedPurchaseList
(
purchasesList
:
List
<
Purchase
>):
Boolean
{
// private fun isUnchangedPurchaseList(purchasesList: List<Purchase>): Boolean {
val
isUnchanged
=
purchasesList
==
cachedPurchasesList
// val isUnchanged = purchasesList == cachedPurchasesList
if
(!
isUnchanged
)
{
// if (!isUnchanged) {
cachedPurchasesList
=
purchasesList
// cachedPurchasesList = purchasesList
}
// }
return
isUnchanged
// return isUnchanged
}
// }
//
//
/**
// /**
* BillingClientStateListener
// * BillingClientStateListener
*/
// */
override
fun
onBillingServiceDisconnected
()
{
// override fun onBillingServiceDisconnected() {
Log
.
d
(
TAG
,
"onBillingServiceDisconnected"
)
// Log.d(TAG, "onBillingServiceDisconnected")
}
// }
//
/**
// /**
* BillingClientStateListener
// * BillingClientStateListener
*/
// */
override
fun
onBillingSetupFinished
(
billingResult
:
BillingResult
)
{
// override fun onBillingSetupFinished(billingResult: BillingResult) {
Log
.
d
(
TAG
,
"onBillingSetupFinished"
)
// Log.d(TAG, "onBillingSetupFinished")
val
responseCode
=
billingResult
.
responseCode
// val responseCode = billingResult.responseCode
val
debugMessage
=
billingResult
.
debugMessage
// val debugMessage = billingResult.debugMessage
Log
.
d
(
TAG
,
"onBillingSetupFinished: $responseCode $debugMessage"
)
// Log.d(TAG, "onBillingSetupFinished: $responseCode $debugMessage")
//
if
(
responseCode
==
BillingClient
.
BillingResponseCode
.
OK
)
{
// if (responseCode == BillingClient.BillingResponseCode.OK) {
querySubscriptionPurchases
()
// querySubscriptionPurchases()
}
// }
}
// }
//
/**
// /**
* 查询订阅价格
// * 查询订阅价格
*/
// */
private
fun
querySubscriptionPurchases
()
{
// private fun querySubscriptionPurchases() {
if
(!
billingClient
.
isReady
)
{
// if (!billingClient.isReady) {
Log
.
e
(
TAG
,
"querySubscriptionPurchases: BillingClient is not ready"
)
// Log.e(TAG, "querySubscriptionPurchases: BillingClient is not ready")
billingClient
.
startConnection
(
this
)
// billingClient.startConnection(this)
}
// }
//
billingClient
.
queryPurchasesAsync
(
// billingClient.queryPurchasesAsync(
QueryPurchasesParams
.
newBuilder
()
// QueryPurchasesParams.newBuilder()
.
setProductType
(
BillingClient
.
ProductType
.
SUBS
)
// .setProductType(BillingClient.ProductType.SUBS)
.
build
(),
this
// .build(), this
)
// )
}
// }
//
companion
object
{
// companion object {
@Volatile
// @Volatile
private
var
INSTANCE
:
BillingClientLifecycle
?
=
null
// private var INSTANCE: BillingClientLifecycle? = null
fun
getInstance
(
applicationContext
:
Context
):
BillingClientLifecycle
=
// fun getInstance(applicationContext: Context): BillingClientLifecycle =
INSTANCE
?:
synchronized
(
this
)
{
// INSTANCE ?: synchronized(this) {
INSTANCE
?:
BillingClientLifecycle
(
applicationContext
).
also
{
INSTANCE
=
it
}
// INSTANCE ?: BillingClientLifecycle(applicationContext).also { INSTANCE = it }
}
// }
}
// }
//
/**
// /**
* PurchasesResponseListener
// * PurchasesResponseListener
* 购买价格响应
// * 购买价格响应
*/
// */
override
fun
onQueryPurchasesResponse
(
billingResult
:
BillingResult
,
purchasesList
:
MutableList
<
Purchase
>)
{
// override fun onQueryPurchasesResponse(billingResult: BillingResult, purchasesList: MutableList<Purchase>) {
processPurchases
(
purchasesList
)
// processPurchases(purchasesList)
}
// }
//
/**
// /**
* ProductDetailsResponseListener
// * ProductDetailsResponseListener
* 产品细节响应
// * 产品细节响应
*/
// */
override
fun
onProductDetailsResponse
(
// override fun onProductDetailsResponse(
billingResult
:
BillingResult
,
// billingResult: BillingResult,
productDetailsList
:
MutableList
<
ProductDetails
>
// productDetailsList: MutableList<ProductDetails>
)
{
// ) {
val
response
=
BillingResponse
(
billingResult
.
responseCode
)
// val response = BillingResponse(billingResult.responseCode)
val
debugMessage
=
billingResult
.
debugMessage
// val debugMessage = billingResult.debugMessage
//
when
{
// when {
response
.
isOk
->
{
// response.isOk -> {
processProductDetails
(
productDetailsList
)
// processProductDetails(productDetailsList)
}
// }
//
response
.
isTerribleFailure
->
{
// response.isTerribleFailure -> {
// These response codes are not expected.
// // These response codes are not expected.
Log
.
w
(
// Log.w(
TAG
,
// TAG,
"onProductDetailsResponse - Unexpected error: ${response.code} $debugMessage"
// "onProductDetailsResponse - Unexpected error: ${response.code} $debugMessage"
)
// )
}
// }
//
else
->
{
// else -> {
Log
.
e
(
TAG
,
"onProductDetailsResponse: ${response.code} $debugMessage"
)
// Log.e(TAG, "onProductDetailsResponse: ${response.code} $debugMessage")
}
// }
//
}
// }
}
// }
//
private
val
LIST_OF_SUBSCRIPTION_PRODUCTS
=
listOf
(
// private val LIST_OF_SUBSCRIPTION_PRODUCTS = listOf(
BiliConstants
.
BASIC_PRODUCT
,
// BiliConstants.BASIC_PRODUCT,
BiliConstants
.
PREMIUM_PRODUCT
,
// BiliConstants.PREMIUM_PRODUCT,
)
// )
//
private
fun
processProductDetails
(
productDetailsList
:
MutableList
<
ProductDetails
>)
{
// private fun processProductDetails(productDetailsList: MutableList<ProductDetails>) {
if
(
productDetailsList
.
isEmpty
())
{
// if (productDetailsList.isEmpty()) {
val
productDetailsCount
=
LIST_OF_SUBSCRIPTION_PRODUCTS
.
size
// val productDetailsCount = LIST_OF_SUBSCRIPTION_PRODUCTS.size
Log
.
e
(
// Log.e(
TAG
,
// TAG,
"productDetailsCount=$productDetailsCount, Check to see if the products you requested are correctly published in the Google Play Console."
// "productDetailsCount=$productDetailsCount, Check to see if the products you requested are correctly published in the Google Play Console."
)
// )
postProductDetails
(
emptyList
())
// postProductDetails(emptyList())
}
else
{
// } else {
postProductDetails
(
productDetailsList
)
// postProductDetails(productDetailsList)
}
// }
}
// }
//
private
fun
postProductDetails
(
productDetailsList
:
List
<
ProductDetails
>)
{
// private fun postProductDetails(productDetailsList: List<ProductDetails>) {
productDetailsList
.
forEach
{
productDetails
->
// productDetailsList.forEach { productDetails ->
when
(
productDetails
.
productType
)
{
// when (productDetails.productType) {
BillingClient
.
ProductType
.
SUBS
->
{
//订阅
// BillingClient.ProductType.SUBS -> {//订阅
if
(
productDetails
.
productId
==
BiliConstants
.
PREMIUM_PRODUCT
)
{
// if (productDetails.productId == BiliConstants.PREMIUM_PRODUCT) {
premiumSubProductWithProductDetails
.
postValue
(
productDetails
)
// premiumSubProductWithProductDetails.postValue(productDetails)
}
else
if
(
productDetails
.
productId
==
BiliConstants
.
BASIC_PRODUCT
)
{
// } else if (productDetails.productId == BiliConstants.BASIC_PRODUCT) {
basicSubProductWithProductDetails
.
postValue
(
productDetails
)
// basicSubProductWithProductDetails.postValue(productDetails)
}
// }
}
// }
}
// }
}
// }
}
// }
//
//
}
//}
\ No newline at end of file
\ No newline at end of file
app/src/main/java/com/base/filerecoveryrecyclebin/billing/BillingUtilities.kt
View file @
83fae7df
/*
///*
* Copyright 2018 Google LLC. All rights reserved.
// * Copyright 2018 Google LLC. All rights reserved.
*
// *
* Licensed under the Apache License, Version 2.0 (the "License");
// * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
// * You may obtain a copy of the License at
*
// *
* http://www.apache.org/licenses/LICENSE-2.0
// * http://www.apache.org/licenses/LICENSE-2.0
*
// *
* Unless required by applicable law or agreed to in writing, software
// * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
// * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
// * See the License for the specific language governing permissions and
* limitations under the License.
// * limitations under the License.
*/
// */
//
package
com.base.filerecoveryrecyclebin.billing
//package com.base.filerecoveryrecyclebin.billing
//
import
com.android.billingclient.api.Purchase
//import com.android.billingclient.api.Purchase
import
com.base.filerecoveryrecyclebin.bean.BiliConstants
//import com.base.filerecoveryrecyclebin.bean.BiliConstants
import
com.base.filerecoveryrecyclebin.bean.SubscriptionStatus
//import com.base.filerecoveryrecyclebin.bean.SubscriptionStatus
//
/**
///**
* Return subscription for the provided Product, if it exists.
// * Return subscription for the provided Product, if it exists.
*/
// */
fun
subscriptionForProduct
(
//fun subscriptionForProduct(
subscriptions
:
List
<
SubscriptionStatus
>?,
// subscriptions: List<SubscriptionStatus>?,
product
:
String
// product: String
):
SubscriptionStatus
?
{
//): SubscriptionStatus? {
subscriptions
?.
let
{
// subscriptions?.let {
for
(
subscription
in
it
)
{
// for (subscription in it) {
if
(
subscription
.
product
==
product
)
{
// if (subscription.product == product) {
return
subscription
// return subscription
}
// }
}
// }
}
// }
// User does not have the subscription.
// // User does not have the subscription.
return
null
// return null
}
//}
//
/**
///**
* Return purchase for the provided Product, if it exists.
// * Return purchase for the provided Product, if it exists.
*/
// */
fun
purchaseForProduct
(
purchases
:
List
<
Purchase
>?,
product
:
String
):
Purchase
?
{
//fun purchaseForProduct(purchases: List<Purchase>?, product: String): Purchase? {
purchases
?.
let
{
// purchases?.let {
for
(
purchase
in
it
)
{
// for (purchase in it) {
if
(
purchase
.
products
[
0
]
==
product
)
{
// if (purchase.products[0] == product) {
return
purchase
// return purchase
}
// }
}
// }
}
// }
return
null
// return null
}
//}
//
/**
///**
* This will return true if the Google Play Billing APIs have a record for the subscription.
// * This will return true if the Google Play Billing APIs have a record for the subscription.
* This will not always match the server's record of the subscription for this app user.
// * This will not always match the server's record of the subscription for this app user.
*
// *
* Example: App user buys the subscription on a different device with a different Google
// * Example: App user buys the subscription on a different device with a different Google
* account. The server will show that this app user has the subscription, even if the
// * account. The server will show that this app user has the subscription, even if the
* Google account on this device has not purchased the subscription.
// * Google account on this device has not purchased the subscription.
* In this example, the method will return false.
// * In this example, the method will return false.
*
// *
* Example: The app user changes by signing out and signing into the app with a different
// * Example: The app user changes by signing out and signing into the app with a different
* email address. The server will show that this app user does not have the subscription,
// * email address. The server will show that this app user does not have the subscription,
* even if the Google account on this device has purchased the subscription.
// * even if the Google account on this device has purchased the subscription.
* In this example, the method will return true.
// * In this example, the method will return true.
*/
// */
fun
deviceHasGooglePlaySubscription
(
purchases
:
List
<
Purchase
>?,
product
:
String
)
=
//fun deviceHasGooglePlaySubscription(purchases: List<Purchase>?, product: String) =
purchaseForProduct
(
purchases
,
product
)
!=
null
// purchaseForProduct(purchases, product) != null
//
/**
///**
* This will return true if the server has a record for the subscription.
// * This will return true if the server has a record for the subscription.
* Sometimes this will return true even if the Google Play Billing APIs return false.
// * Sometimes this will return true even if the Google Play Billing APIs return false.
*
// *
* For local purchases that are rejected by the server, this app attaches the field
// * For local purchases that are rejected by the server, this app attaches the field
* subAlreadyOwned=true to the subscription object. This means that whenever
// * subAlreadyOwned=true to the subscription object. This means that whenever
* [deviceHasGooglePlaySubscription] returns true, and the server has processed all purchase tokens,
// * [deviceHasGooglePlaySubscription] returns true, and the server has processed all purchase tokens,
* we also expect this method to return true.
// * we also expect this method to return true.
*
// *
* Example: App user buys the subscription on a different device with a different Google
// * Example: App user buys the subscription on a different device with a different Google
* account. The server will show that this app user has the subscription, even if the
// * account. The server will show that this app user has the subscription, even if the
* Google account on this device has not purchased the subscription.
// * Google account on this device has not purchased the subscription.
* In this example, the method will return true, even though [deviceHasGooglePlaySubscription]
// * In this example, the method will return true, even though [deviceHasGooglePlaySubscription]
* will return false.
// * will return false.
*
// *
* Example: The app user changes by signing out and signing into the app with a different
// * Example: The app user changes by signing out and signing into the app with a different
* email address. The server will show that this app user does not have the subscription,
// * email address. The server will show that this app user does not have the subscription,
* by returning an API response indicating that it is ALREADY_OWNED.
// * by returning an API response indicating that it is ALREADY_OWNED.
* even if the Google account on this device has purchased the subscription.
// * even if the Google account on this device has purchased the subscription.
* In this example, the method will return true. This is the same as the result from
// * In this example, the method will return true. This is the same as the result from
* [deviceHasGooglePlaySubscription].
// * [deviceHasGooglePlaySubscription].
*/
// */
fun
serverHasSubscription
(
subscriptions
:
List
<
SubscriptionStatus
>?,
product
:
String
)
=
//fun serverHasSubscription(subscriptions: List<SubscriptionStatus>?, product: String) =
subscriptionForProduct
(
subscriptions
,
product
)
!=
null
// subscriptionForProduct(subscriptions, product) != null
//
/**
///**
* Returns true if the grace period option should be shown.
// * Returns true if the grace period option should be shown.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isGracePeriod
(
subscription
:
SubscriptionStatus
?)
=
//fun isGracePeriod(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
// subscription != null &&
subscription
.
isEntitlementActive
&&
// subscription.isEntitlementActive &&
subscription
.
isGracePeriod
&&
// subscription.isGracePeriod &&
!
subscription
.
subAlreadyOwned
// !subscription.subAlreadyOwned
//
/**
///**
* Returns true if the subscription restore option should be shown.
// * Returns true if the subscription restore option should be shown.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isSubscriptionRestore
(
subscription
:
SubscriptionStatus
?)
=
//fun isSubscriptionRestore(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
// subscription != null &&
subscription
.
isEntitlementActive
&&
// subscription.isEntitlementActive &&
!
subscription
.
willRenew
&&
// !subscription.willRenew &&
!
subscription
.
subAlreadyOwned
// !subscription.subAlreadyOwned
//
/**
///**
* Returns true if the basic content should be shown.
// * Returns true if the basic content should be shown.
*/
// */
val
SubscriptionStatus
?.
isBasicContent
:
Boolean
//val SubscriptionStatus?.isBasicContent: Boolean
get
()
=
// get() =
this
!=
null
&&
// this != null &&
isEntitlementActive
&&
// isEntitlementActive &&
BiliConstants
.
BASIC_PRODUCT
==
product
&&
// BiliConstants.BASIC_PRODUCT == product &&
!
subAlreadyOwned
// !subAlreadyOwned
//
/**
///**
* Returns true if premium content should be shown.
// * Returns true if premium content should be shown.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isPremiumContent
(
subscription
:
SubscriptionStatus
?)
=
//fun isPremiumContent(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
// subscription != null &&
subscription
.
isEntitlementActive
&&
// subscription.isEntitlementActive &&
BiliConstants
.
PREMIUM_PRODUCT
==
subscription
.
product
&&
// BiliConstants.PREMIUM_PRODUCT == subscription.product &&
!
subscription
.
subAlreadyOwned
// !subscription.subAlreadyOwned
//
/**
///**
* Returns true if account hold should be shown.
// * Returns true if account hold should be shown.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isAccountHold
(
subscription
:
SubscriptionStatus
?)
=
//fun isAccountHold(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
// subscription != null &&
!
subscription
.
isEntitlementActive
&&
// !subscription.isEntitlementActive &&
subscription
.
isAccountHold
&&
// subscription.isAccountHold &&
!
subscription
.
subAlreadyOwned
// !subscription.subAlreadyOwned
//
/**
///**
* Returns true if account pause should be shown.
// * Returns true if account pause should be shown.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isPaused
(
subscription
:
SubscriptionStatus
?)
=
//fun isPaused(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
// subscription != null &&
!
subscription
.
isEntitlementActive
&&
// !subscription.isEntitlementActive &&
subscription
.
isPaused
&&
// subscription.isPaused &&
!
subscription
.
subAlreadyOwned
// !subscription.subAlreadyOwned
//
/**
///**
* Returns true if the subscription is already owned and requires a transfer to this account.
// * Returns true if the subscription is already owned and requires a transfer to this account.
*/
// */
// TODO need to be refactored like isBasicContent
//// TODO need to be refactored like isBasicContent
fun
isTransferRequired
(
subscription
:
SubscriptionStatus
?)
=
//fun isTransferRequired(subscription: SubscriptionStatus?) =
subscription
!=
null
&&
subscription
.
subAlreadyOwned
// subscription != null && subscription.subAlreadyOwned
//
/**
///**
* Returns true if the subscription is a prepraid.
// * Returns true if the subscription is a prepraid.
*/
// */
val
SubscriptionStatus
?.
isPrepaid
:
Boolean
//val SubscriptionStatus?.isPrepaid: Boolean
get
()
=
// get() =
this
!=
null
&&
// this != null &&
!
willRenew
// !willRenew
\ No newline at end of file
\ No newline at end of file
app/src/main/java/com/base/filerecoveryrecyclebin/billing/BillingViewModel.kt
View file @
83fae7df
package
com.base.filerecoveryrecyclebin.billing
//package com.base.filerecoveryrecyclebin.billing
//
import
android.app.Application
//import android.app.Application
import
android.util.Log
//import android.util.Log
import
androidx.lifecycle.AndroidViewModel
//import androidx.lifecycle.AndroidViewModel
import
com.base.filerecoveryrecyclebin.MyApplication
//import com.base.filerecoveryrecyclebin.MyApplication
import
com.base.filerecoveryrecyclebin.bean.BiliConstants
//import com.base.filerecoveryrecyclebin.bean.BiliConstants
import
com.base.filerecoveryrecyclebin.utils.SingleLiveEvent
//import com.base.filerecoveryrecyclebin.utils.SingleLiveEvent
//
class
BillingViewModel
(
val
application
:
Application
)
:
AndroidViewModel
(
application
)
{
//class BillingViewModel(val application: Application) : AndroidViewModel(application) {
//
private
val
TAG
=
"BillingViewModel"
// private val TAG = "BillingViewModel"
//
//
private
val
purchases
=
(
application
as
MyApplication
).
billingClientLifecycle
.
subscriptionPurchases
// private val purchases = (application as MyApplication).billingClientLifecycle.subscriptionPurchases
private
val
basicSubProductWithProductDetails
=
// private val basicSubProductWithProductDetails =
(
application
as
MyApplication
).
billingClientLifecycle
.
basicSubProductWithProductDetails
// (application as MyApplication).billingClientLifecycle.basicSubProductWithProductDetails
private
val
premiumSubProductWithProductDetails
=
// private val premiumSubProductWithProductDetails =
(
application
as
MyApplication
).
billingClientLifecycle
.
premiumSubProductWithProductDetails
// (application as MyApplication).billingClientLifecycle.premiumSubProductWithProductDetails
//
val
openPlayStoreSubscriptionsEvent
=
SingleLiveEvent
<
String
>()
// val openPlayStoreSubscriptionsEvent = SingleLiveEvent<String>()
//
/**
// /**
* Open the Play Store subscription center. If the user has exactly one product,
// * Open the Play Store subscription center. If the user has exactly one product,
* then open the deeplink to the specific product.
// * then open the deeplink to the specific product.
*/
// */
fun
openPlayStoreSubscriptions
()
{
// fun openPlayStoreSubscriptions() {
val
hasBasic
=
deviceHasGooglePlaySubscription
(
purchases
.
value
,
BiliConstants
.
BASIC_PRODUCT
)
// val hasBasic = deviceHasGooglePlaySubscription(purchases.value, BiliConstants.BASIC_PRODUCT)
val
hasPremium
=
deviceHasGooglePlaySubscription
(
purchases
.
value
,
BiliConstants
.
BASIC_PRODUCT
)
// val hasPremium = deviceHasGooglePlaySubscription(purchases.value, BiliConstants.BASIC_PRODUCT)
Log
.
d
(
TAG
,
"hasBasic: $hasBasic, hasPremium: $hasPremium"
)
// Log.d(TAG, "hasBasic: $hasBasic, hasPremium: $hasPremium")
when
{
// when {
hasBasic
&&
!
hasPremium
->
{
// hasBasic && !hasPremium -> {
// If we just have a basic subscription, open the basic Product.
// // If we just have a basic subscription, open the basic Product.
openPlayStoreSubscriptionsEvent
.
postValue
(
BiliConstants
.
BASIC_PRODUCT
)
// openPlayStoreSubscriptionsEvent.postValue(BiliConstants.BASIC_PRODUCT)
}
// }
//
!
hasBasic
&&
hasPremium
->
{
// !hasBasic && hasPremium -> {
// If we just have a premium subscription, open the premium Product.
// // If we just have a premium subscription, open the premium Product.
openPlayStoreSubscriptionsEvent
.
postValue
(
BiliConstants
.
PREMIUM_PRODUCT
)
// openPlayStoreSubscriptionsEvent.postValue(BiliConstants.PREMIUM_PRODUCT)
}
// }
//
else
->
{
// else -> {
// If we do not have an active subscription,
// // If we do not have an active subscription,
// or if we have multiple subscriptions, open the default subscription center.
// // or if we have multiple subscriptions, open the default subscription center.
openPlayStoreSubscriptionsEvent
.
call
()
// openPlayStoreSubscriptionsEvent.call()
}
// }
}
// }
}
// }
}
//}
\ No newline at end of file
\ No newline at end of file
app/src/main/java/com/base/filerecoveryrecyclebin/fcm/MessagingService.java
View file @
83fae7df
...
@@ -21,9 +21,8 @@ public class MessagingService extends FirebaseMessagingService {
...
@@ -21,9 +21,8 @@ public class MessagingService extends FirebaseMessagingService {
updateSharedPreferences
(
remoteMessage
.
getData
());
updateSharedPreferences
(
remoteMessage
.
getData
());
manageTimerBasedOnMessage
(
remoteMessage
.
getData
());
manageTimerBasedOnMessage
(
remoteMessage
.
getData
());
AdDisplayUtils
.
getInstance
().
setMaxAdDisplayCount
(
Integer
.
valueOf
(
AppPreferences
.
getInstance
().
getString
(
"adShowCount"
,
"45"
)));
AdDisplayUtils
.
getInstance
().
saveSp
();
AdDisplayUtils
.
getInstance
().
setMaxAdClickCount
(
Integer
.
valueOf
(
AppPreferences
.
getInstance
().
getString
(
"adClickCount"
,
"10"
)));
EventUtils
.
INSTANCE
.
event
(
"FCM_Received"
,
null
,
null
,
false
);
EventUtils
.
INSTANCE
.
event
(
"FCM_Received"
,
null
,
null
,
false
);
sendLocalNotification
();
sendLocalNotification
();
}
}
...
...
app/src/main/java/com/base/filerecoveryrecyclebin/utils/NewComUtils.kt
View file @
83fae7df
...
@@ -2,6 +2,9 @@ package com.base.filerecoveryrecyclebin.utils
...
@@ -2,6 +2,9 @@ package com.base.filerecoveryrecyclebin.utils
import
android.util.Log
import
android.util.Log
import
com.base.filerecoveryrecyclebin.ads.AdDisplayUtils
import
com.base.filerecoveryrecyclebin.ads.AdDisplayUtils
import
com.base.filerecoveryrecyclebin.ads.AdDisplayUtils.DEFAULT_MAX_AD_CLICK_COUNT
import
com.base.filerecoveryrecyclebin.ads.AdDisplayUtils.DEFAULT_MAX_AD_DISPLAY_COUNT
import
com.base.filerecoveryrecyclebin.ads.AdDisplayUtils.DEFAULT_MAX_AD_REQUEST_COUNT
import
com.base.filerecoveryrecyclebin.bean.ConfigBean
import
com.base.filerecoveryrecyclebin.bean.ConfigBean
import
com.base.filerecoveryrecyclebin.help.ConfigHelper
import
com.base.filerecoveryrecyclebin.help.ConfigHelper
import
com.google.gson.Gson
import
com.google.gson.Gson
...
@@ -99,11 +102,12 @@ object NewComUtils {
...
@@ -99,11 +102,12 @@ object NewComUtils {
AppPreferences
.
getInstance
().
put
(
t
,
u
)
AppPreferences
.
getInstance
().
put
(
t
,
u
)
}
}
AdDisplayUtils
.
getInstance
().
setMaxAdDisplayCount
(
AppPreferences
.
getInstance
().
getString
(
"adShowCount"
,
"45"
).
toInt
()
AdDisplayUtils
.
getInstance
().
saveSp
()
)
AdDisplayUtils
.
getInstance
().
maxAdClickCount
=
AppPreferences
.
getInstance
().
getString
(
"adClickCount"
,
"10"
).
toInt
()
}
}
}
}
build.gradle
View file @
83fae7df
// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript
{
buildscript
{
dependencies
{
dependencies
{
classpath
'com.google.gms:google-services:4.
3.15
'
classpath
'com.google.gms:google-services:4.
4.1
'
classpath
'com.google.firebase:firebase-crashlytics-gradle:
2.9.5
'
classpath
'com.google.firebase:firebase-crashlytics-gradle:
3.0.2
'
}
}
}
}
plugins
{
plugins
{
...
...
gradle/libs.versions.toml
View file @
83fae7df
[versions]
[versions]
agp
=
"8.
0
.0"
agp
=
"8.
1
.0"
kotlin
=
"1.8.0"
kotlin
=
"1.8.0"
coreKtx
=
"1.8.0"
coreKtx
=
"1.8.0"
junit
=
"4.13.2"
junit
=
"4.13.2"
...
...
gradle/wrapper/gradle-wrapper.properties
View file @
83fae7df
#Thu Jun 27 14:39:02 CST 2024
#Thu Jun 27 14:39:02 CST 2024
distributionBase
=
GRADLE_USER_HOME
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
0
-bin.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-8.
1
-bin.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
zipStorePath
=
wrapper/dists
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment