mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
feat: add review Android
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
set(AMNEZIAVPN_VERSION 4.8.14.5)
|
||||
set(AMNEZIAVPN_VERSION 4.8.14.6)
|
||||
|
||||
project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
@@ -12,7 +12,8 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 2117)
|
||||
|
||||
set(APP_ANDROID_VERSION_CODE 2118)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
|
||||
@@ -122,4 +122,5 @@ dependencies {
|
||||
implementation(libs.google.mlkit)
|
||||
implementation(libs.androidx.datastore)
|
||||
implementation(libs.androidx.biometric)
|
||||
implementation(libs.google.play.review)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ androidx-datastore = "1.1.1"
|
||||
kotlinx-coroutines = "1.8.1"
|
||||
kotlinx-serialization = "1.6.3"
|
||||
google-mlkit = "17.3.0"
|
||||
google-play-review = "2.0.2"
|
||||
|
||||
[libraries]
|
||||
androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
|
||||
@@ -28,6 +29,7 @@ androidx-datastore = { module = "androidx.datastore:datastore-preferences", vers
|
||||
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinx-serialization" }
|
||||
google-mlkit = { module = "com.google.mlkit:barcode-scanning", version.ref = "google-mlkit" }
|
||||
google-play-review = { module = "com.google.android.play:review-ktx", version.ref = "google-play-review" }
|
||||
|
||||
[bundles]
|
||||
androidx-camera = [
|
||||
|
||||
@@ -297,7 +297,10 @@ class AmneziaActivity : QtActivity() {
|
||||
Log.d(TAG, "Window focus changed: hasFocus=$hasFocus")
|
||||
|
||||
// Cancel pending operations if window loses focus
|
||||
if (!hasFocus) {
|
||||
if (hasFocus) {
|
||||
ReviewManager.onWindowFocusGained(this, mainScope)
|
||||
} else {
|
||||
// Cancel pending operations if window loses focus
|
||||
resumeHandler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
}
|
||||
@@ -350,6 +353,8 @@ class AmneziaActivity : QtActivity() {
|
||||
isActivityResumed = true
|
||||
Log.d(TAG, "Resume Amnezia activity")
|
||||
|
||||
ReviewManager.onActivityResumed(mainScope)
|
||||
|
||||
if (pendingOpenFileUri != null && !openFileDeliveryScheduled) {
|
||||
val uri = pendingOpenFileUri!!
|
||||
openFileDeliveryScheduled = true
|
||||
|
||||
58
client/android/src/org/amnezia/vpn/ReviewManager.kt
Normal file
58
client/android/src/org/amnezia/vpn/ReviewManager.kt
Normal file
@@ -0,0 +1,58 @@
|
||||
package org.amnezia.vpn
|
||||
|
||||
import android.app.Activity
|
||||
import com.google.android.play.core.review.ReviewManagerFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.vpn.util.Log
|
||||
import org.amnezia.vpn.util.Prefs
|
||||
|
||||
private const val TAG = "ReviewManager"
|
||||
|
||||
private const val PREFS_REVIEW_OPEN_COUNT = "REVIEW_OPEN_COUNT"
|
||||
private const val REVIEW_REQUEST_OPEN_INTERVAL = 20
|
||||
|
||||
object ReviewManager {
|
||||
|
||||
@Volatile
|
||||
private var shouldRequestReviewOnFocus = false
|
||||
|
||||
/**
|
||||
* Call from onResume
|
||||
* Increments the open count and arms the flag if the interval is hit.
|
||||
* I/O runs on the IO dispatcher to avoid blocking the main thread.
|
||||
*/
|
||||
fun onActivityResumed(scope: CoroutineScope) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val openCount = Prefs.load<Int>(PREFS_REVIEW_OPEN_COUNT) + 1
|
||||
Prefs.save(PREFS_REVIEW_OPEN_COUNT, openCount)
|
||||
|
||||
shouldRequestReviewOnFocus = openCount > 0 && openCount % REVIEW_REQUEST_OPEN_INTERVAL == 0
|
||||
Log.i(TAG, "onActivityResumed: openCount=$openCount, shouldRequestReview=$shouldRequestReviewOnFocus")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call from onWindowFocusChanged (hasFocus=true)
|
||||
*/
|
||||
fun onWindowFocusGained(activity: Activity, scope: CoroutineScope) {
|
||||
if (!shouldRequestReviewOnFocus) return
|
||||
shouldRequestReviewOnFocus = false
|
||||
|
||||
scope.launch(Dispatchers.Main) {
|
||||
requestReviewFlow(activity)
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestReviewFlow(activity: Activity) {
|
||||
val reviewManager = ReviewManagerFactory.create(activity)
|
||||
reviewManager.requestReviewFlow().addOnCompleteListener { request ->
|
||||
if (request.isSuccessful) {
|
||||
reviewManager.launchReviewFlow(activity, request.result)
|
||||
} else {
|
||||
Log.w(TAG, "Review flow request failed: ${request.exception}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user