feat: add review Android

This commit is contained in:
NickVs2015
2026-02-27 14:55:12 +03:00
parent 477afb9d85
commit d77e71d7cd
5 changed files with 70 additions and 3 deletions

View File

@@ -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")

View File

@@ -122,4 +122,5 @@ dependencies {
implementation(libs.google.mlkit)
implementation(libs.androidx.datastore)
implementation(libs.androidx.biometric)
implementation(libs.google.play.review)
}

View File

@@ -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 = [

View File

@@ -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

View 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}")
}
}
}
}