diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
new file mode 100644
index 0000000..405a2b3
--- /dev/null
+++ b/.github/workflows/gradle-wrapper-validation.yml
@@ -0,0 +1,10 @@
+name: "Validate Gradle Wrapper"
+on: [push, pull_request]
+
+jobs:
+ validation:
+ name: "Validation"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: gradle/wrapper-validation-action@v1
diff --git a/README.md b/README.md
index 0f756fe..1620cc5 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,10 @@
Redirect outgoing calls to Signal/Telegram/Threema.
-[comment]: <> ([
( src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png")
-
-[comment]: <> ( alt="Get it on F-Droid")
-
-[comment]: <> ( height="80">](https://f-droid.org/packages/me.lucky.red/))
+[
](https://f-droid.org/packages/me.lucky.red/)
[
R.string.destination_signal
- TELEGRAM_MIMETYPE -> R.string.destination_telegram
- THREEMA_MIMETYPE -> R.string.destination_threema
- WHATSAPP_MIMETYPE -> R.string.fallback_destination_whatsapp
- else -> return
- })
+ window.show(record.uri, MIMETYPE_TO_DST_NAME[record.mimetype] ?: return)
}
@RequiresPermission(Manifest.permission.READ_CONTACTS)
@@ -83,7 +84,7 @@ class CallRedirectionService : CallRedirectionService() {
val cursor = contentResolver.query(
Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
- Uri.encode(phoneNumber)
+ Uri.encode(phoneNumber),
),
arrayOf(ContactsContract.PhoneLookup._ID),
null,
@@ -109,8 +110,8 @@ class CallRedirectionService : CallRedirectionService() {
arrayOf(ContactsContract.Data._ID, ContactsContract.Data.MIMETYPE),
"${ContactsContract.Data.CONTACT_ID} = ? AND " +
"${ContactsContract.Data.MIMETYPE} IN " +
- "(${MIMETYPES.keys.joinToString(",") { "?" }})",
- arrayOf(contactId, *MIMETYPES.keys.toTypedArray()),
+ "(${MIMETYPE_TO_WEIGHT.keys.joinToString(",") { "?" }})",
+ arrayOf(contactId, *MIMETYPE_TO_WEIGHT.keys.toTypedArray()),
null,
)
cursor?.apply {
diff --git a/app/src/main/java/me/lucky/red/MainActivity.kt b/app/src/main/java/me/lucky/red/MainActivity.kt
index c9e3fd3..4861f27 100644
--- a/app/src/main/java/me/lucky/red/MainActivity.kt
+++ b/app/src/main/java/me/lucky/red/MainActivity.kt
@@ -23,6 +23,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var prefs: Preferences
+ private lateinit var window: PopupWindow
private var roleManager: RoleManager? = null
private val registerForCallRedirectionRole =
@@ -42,14 +43,20 @@ class MainActivity : AppCompatActivity() {
setup()
}
+ override fun onDestroy() {
+ super.onDestroy()
+ window.cancel()
+ }
+
private fun init() {
prefs = Preferences(this)
+ window = PopupWindow(this, null)
roleManager = getSystemService(RoleManager::class.java)
binding.apply {
redirectionDelay.value = (prefs.redirectionDelay / 1000).toFloat()
popupPosition.editText?.setText(prefs.popupPosition.toString())
fallback.isChecked = prefs.isFallbackChecked
- toggle.isChecked = prefs.isServiceEnabled
+ toggle.isChecked = prefs.isEnabled
}
}
@@ -61,6 +68,9 @@ class MainActivity : AppCompatActivity() {
redirectionDelay.addOnChangeListener { _, value, _ ->
prefs.redirectionDelay = (value * 1000).toLong()
}
+ popupPosition.setEndIconOnClickListener {
+ window.preview()
+ }
popupPosition.editText?.doAfterTextChanged {
try {
prefs.popupPosition = it?.toString()?.toInt() ?: return@doAfterTextChanged
@@ -75,7 +85,7 @@ class MainActivity : AppCompatActivity() {
requestPermissions()
return@setOnCheckedChangeListener
}
- prefs.isServiceEnabled = isChecked
+ prefs.isEnabled = isChecked
}
}
}
diff --git a/app/src/main/java/me/lucky/red/PopupWindow.kt b/app/src/main/java/me/lucky/red/PopupWindow.kt
index 7bfafe0..9476c39 100644
--- a/app/src/main/java/me/lucky/red/PopupWindow.kt
+++ b/app/src/main/java/me/lucky/red/PopupWindow.kt
@@ -1,6 +1,7 @@
package me.lucky.red
import android.Manifest
+import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.media.AudioManager
@@ -10,20 +11,19 @@ import android.view.LayoutInflater
import android.view.WindowManager
import android.widget.TextView
import androidx.annotation.RequiresPermission
+import java.lang.ref.WeakReference
import java.util.*
import kotlin.concurrent.timerTask
-class PopupWindow(private val service: CallRedirectionService) {
- private val windowManager = service
- .applicationContext
- .getSystemService(WindowManager::class.java)
- private val audioManager = service
- .applicationContext
- .getSystemService(AudioManager::class.java)
+class PopupWindow(
+ private val ctx: Context,
+ private val service: WeakReference?,
+) {
+ private val prefs = Preferences(ctx)
+ private val windowManager = ctx.getSystemService(WindowManager::class.java)
+ private val audioManager = ctx.getSystemService(AudioManager::class.java)
@Suppress("InflateParams")
- private val view = LayoutInflater
- .from(service.applicationContext)
- .inflate(R.layout.popup, null)
+ private val view = LayoutInflater.from(ctx).inflate(R.layout.popup, null)
private val layoutParams = WindowManager.LayoutParams().apply {
format = PixelFormat.TRANSLUCENT
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
@@ -31,18 +31,32 @@ class PopupWindow(private val service: CallRedirectionService) {
gravity = Gravity.BOTTOM
width = WindowManager.LayoutParams.WRAP_CONTENT
height = WindowManager.LayoutParams.WRAP_CONTENT
- y = service.prefs.popupPosition
+ y = prefs.popupPosition
}
private var timer: Timer? = null
init {
view.setOnClickListener {
cancel()
- service.placeCallUnmodified()
+ service?.get()?.placeCallUnmodified()
}
}
+ fun preview() {
+ remove()
+ layoutParams.y = prefs.popupPosition
+ val destinations = mutableListOf(
+ R.string.destination_signal,
+ R.string.destination_telegram,
+ R.string.destination_threema,
+ )
+ if (prefs.isFallbackChecked) destinations.add(R.string.fallback_destination_whatsapp)
+ setDescription(destinations.random())
+ add()
+ }
+
fun show(uri: Uri, destinationId: Int) {
+ val service = service?.get() ?: return
if (!remove()) {
service.placeCallUnmodified()
return
@@ -65,23 +79,27 @@ class PopupWindow(private val service: CallRedirectionService) {
return@timerTask
}
service.cancelCall()
- }, service.prefs.redirectionDelay)
- view.findViewById(R.id.description).text = String.format(
- service.getString(R.string.popup),
- service.getString(destinationId),
- )
+ }, prefs.redirectionDelay)
+ setDescription(destinationId)
if (!add()) {
timer?.cancel()
service.placeCallUnmodified()
}
}
+ private fun setDescription(id: Int) {
+ view.findViewById(R.id.description).text = ctx.getString(
+ R.string.popup,
+ ctx.getString(id),
+ )
+ }
+
@RequiresPermission(Manifest.permission.CALL_PHONE)
private fun call(data: Uri) {
Intent(Intent.ACTION_VIEW).let {
it.data = data
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK
- service.startActivity(it)
+ ctx.startActivity(it)
}
}
diff --git a/app/src/main/java/me/lucky/red/Preferences.kt b/app/src/main/java/me/lucky/red/Preferences.kt
index 33b11b1..7948d8a 100644
--- a/app/src/main/java/me/lucky/red/Preferences.kt
+++ b/app/src/main/java/me/lucky/red/Preferences.kt
@@ -6,20 +6,23 @@ import androidx.preference.PreferenceManager
class Preferences(ctx: Context) {
companion object {
- private const val SERVICE_ENABLED = "service_enabled"
+ private const val ENABLED = "enabled"
private const val REDIRECTION_DELAY = "redirection_delay"
private const val POPUP_POSITION = "popup_position_y"
private const val FALLBACK_CHECKED = "fallback_checked"
private const val DEFAULT_REDIRECTION_DELAY = 2000L
private const val DEFAULT_POPUP_POSITION = 333
+
+ // migration
+ private const val SERVICE_ENABLED = "service_enabled"
}
private val prefs = PreferenceManager.getDefaultSharedPreferences(ctx)
- var isServiceEnabled: Boolean
- get() = prefs.getBoolean(SERVICE_ENABLED, false)
- set(value) = prefs.edit { putBoolean(SERVICE_ENABLED, value) }
+ var isEnabled: Boolean
+ get() = prefs.getBoolean(ENABLED, prefs.getBoolean(SERVICE_ENABLED, false))
+ set(value) = prefs.edit { putBoolean(ENABLED, value) }
var redirectionDelay: Long
get() = prefs.getLong(REDIRECTION_DELAY, DEFAULT_REDIRECTION_DELAY)
diff --git a/app/src/main/res/drawable/ic_baseline_check_circle_24.xml b/app/src/main/res/drawable/ic_baseline_check_circle_24.xml
new file mode 100644
index 0000000..5e111ca
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_check_circle_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 3753d2f..97ae04d 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -55,6 +55,8 @@
diff --git a/app/src/main/res/values-fr/string.xml b/app/src/main/res/values-fr/strings.xml
similarity index 100%
rename from app/src/main/res/values-fr/string.xml
rename to app/src/main/res/values-fr/strings.xml
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 88442f2..dd378e5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -6,7 +6,7 @@
Signal
Telegram
Threema
- Delay before a call will be redirected.
+ The delay before a call will be redirected.
Popup position
Fallback
Redirect to WhatsApp if no other available.
diff --git a/build.gradle b/build.gradle
index 9262dea..9d1ce67 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.1.1'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
+ classpath 'com.android.tools.build:gradle:7.2.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/fastlane/metadata/android/en-US/changelogs/9.txt b/fastlane/metadata/android/en-US/changelogs/9.txt
new file mode 100644
index 0000000..135fd01
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/9.txt
@@ -0,0 +1 @@
+popup window preview
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
index 1c4e57e..8b9cbff 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ
diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt
index 3004d7f..933fa76 100644
--- a/fastlane/metadata/android/ru-RU/full_description.txt
+++ b/fastlane/metadata/android/ru-RU/full_description.txt
@@ -1,4 +1,4 @@
-Минимальное приложение для перенаправления исходящих вызовов в Signal/Telegram/Threema.
+Мини приложение для перенаправления исходящих вызовов в Signal/Telegram/Threema.
Вы можете отменить перенаправление, кликнув на всплывающее сообщение "Перенаправление в..".
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index a2e01c0..4a48a57 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
+#Tue Jun 14 23:11:06 MSK 2022
distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionPath=wrapper/dists
-distributionSha256Sum=f581709a9c35e9cb92e16f585d2c4bc99b2b1a5f85d2badbd3dc6bff59e1e6dd
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME