popup window preview
This commit is contained in:
parent
f7bed719e3
commit
2ff2448739
16 changed files with 111 additions and 59 deletions
10
.github/workflows/gradle-wrapper-validation.yml
vendored
Normal file
10
.github/workflows/gradle-wrapper-validation.yml
vendored
Normal file
|
@ -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
|
11
README.md
11
README.md
|
@ -2,13 +2,10 @@
|
||||||
|
|
||||||
Redirect outgoing calls to Signal/Telegram/Threema.
|
Redirect outgoing calls to Signal/Telegram/Threema.
|
||||||
|
|
||||||
[comment]: <> ([<img)
|
[<img
|
||||||
|
src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
[comment]: <> ( src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png")
|
alt="Get it on F-Droid"
|
||||||
|
height="80">](https://f-droid.org/packages/me.lucky.red/)
|
||||||
[comment]: <> ( alt="Get it on F-Droid")
|
|
||||||
|
|
||||||
[comment]: <> ( height="80">](https://f-droid.org/packages/me.lucky.red/))
|
|
||||||
[<img
|
[<img
|
||||||
src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
|
src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
|
||||||
alt="Get it on Google Play"
|
alt="Get it on Google Play"
|
||||||
|
|
|
@ -10,8 +10,8 @@ android {
|
||||||
applicationId "me.lucky.red"
|
applicationId "me.lucky.red"
|
||||||
minSdk 29
|
minSdk 29
|
||||||
targetSdk 32
|
targetSdk 32
|
||||||
versionCode 8
|
versionCode 9
|
||||||
versionName "1.0.7"
|
versionName "1.0.8"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,10 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.core:core-ktx:1.8.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||||
implementation 'com.google.android.material:material:1.5.0'
|
implementation 'com.google.android.material:material:1.6.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.provider.ContactsContract
|
||||||
import android.telecom.CallRedirectionService
|
import android.telecom.CallRedirectionService
|
||||||
import android.telecom.PhoneAccountHandle
|
import android.telecom.PhoneAccountHandle
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
class CallRedirectionService : CallRedirectionService() {
|
class CallRedirectionService : CallRedirectionService() {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -16,7 +17,7 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
private const val TELEGRAM_MIMETYPE = "$PREFIX/vnd.org.telegram.messenger.android.call"
|
private const val TELEGRAM_MIMETYPE = "$PREFIX/vnd.org.telegram.messenger.android.call"
|
||||||
private const val THREEMA_MIMETYPE = "$PREFIX/vnd.ch.threema.app.call"
|
private const val THREEMA_MIMETYPE = "$PREFIX/vnd.ch.threema.app.call"
|
||||||
private const val WHATSAPP_MIMETYPE = "$PREFIX/vnd.com.whatsapp.voip.call"
|
private const val WHATSAPP_MIMETYPE = "$PREFIX/vnd.com.whatsapp.voip.call"
|
||||||
private val MIMETYPES = mapOf(
|
private val MIMETYPE_TO_WEIGHT = mapOf(
|
||||||
SIGNAL_MIMETYPE to 0,
|
SIGNAL_MIMETYPE to 0,
|
||||||
TELEGRAM_MIMETYPE to 1,
|
TELEGRAM_MIMETYPE to 1,
|
||||||
THREEMA_MIMETYPE to 2,
|
THREEMA_MIMETYPE to 2,
|
||||||
|
@ -25,9 +26,15 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
private val FALLBACK_MIMETYPES = arrayOf(
|
private val FALLBACK_MIMETYPES = arrayOf(
|
||||||
WHATSAPP_MIMETYPE,
|
WHATSAPP_MIMETYPE,
|
||||||
)
|
)
|
||||||
|
private val MIMETYPE_TO_DST_NAME = mapOf(
|
||||||
|
SIGNAL_MIMETYPE to R.string.destination_signal,
|
||||||
|
TELEGRAM_MIMETYPE to R.string.destination_telegram,
|
||||||
|
THREEMA_MIMETYPE to R.string.destination_threema,
|
||||||
|
WHATSAPP_MIMETYPE to R.string.fallback_destination_whatsapp,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var prefs: Preferences
|
private lateinit var prefs: Preferences
|
||||||
private lateinit var window: PopupWindow
|
private lateinit var window: PopupWindow
|
||||||
private var connectivityManager: ConnectivityManager? = null
|
private var connectivityManager: ConnectivityManager? = null
|
||||||
|
|
||||||
|
@ -43,7 +50,7 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
|
|
||||||
private fun init() {
|
private fun init() {
|
||||||
prefs = Preferences(this)
|
prefs = Preferences(this)
|
||||||
window = PopupWindow(this)
|
window = PopupWindow(this, WeakReference(this))
|
||||||
connectivityManager = getSystemService(ConnectivityManager::class.java)
|
connectivityManager = getSystemService(ConnectivityManager::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +59,7 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
initialPhoneAccount: PhoneAccountHandle,
|
initialPhoneAccount: PhoneAccountHandle,
|
||||||
allowInteractiveResponse: Boolean,
|
allowInteractiveResponse: Boolean,
|
||||||
) {
|
) {
|
||||||
if (!prefs.isServiceEnabled || !hasInternet() || !allowInteractiveResponse) {
|
if (!prefs.isEnabled || !hasInternet() || !allowInteractiveResponse) {
|
||||||
placeCallUnmodified()
|
placeCallUnmodified()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -63,18 +70,12 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
placeCallUnmodified()
|
placeCallUnmodified()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val record = records.minByOrNull { MIMETYPES[it.mimetype] ?: 0 }
|
val record = records.minByOrNull { MIMETYPE_TO_WEIGHT[it.mimetype] ?: 0 }
|
||||||
if (record == null || (record.mimetype in FALLBACK_MIMETYPES && !prefs.isFallbackChecked)) {
|
if (record == null || (record.mimetype in FALLBACK_MIMETYPES && !prefs.isFallbackChecked)) {
|
||||||
placeCallUnmodified()
|
placeCallUnmodified()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
window.show(record.uri, when (record.mimetype) {
|
window.show(record.uri, MIMETYPE_TO_DST_NAME[record.mimetype] ?: return)
|
||||||
SIGNAL_MIMETYPE -> 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
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.READ_CONTACTS)
|
@RequiresPermission(Manifest.permission.READ_CONTACTS)
|
||||||
|
@ -83,7 +84,7 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
val cursor = contentResolver.query(
|
val cursor = contentResolver.query(
|
||||||
Uri.withAppendedPath(
|
Uri.withAppendedPath(
|
||||||
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
|
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
|
||||||
Uri.encode(phoneNumber)
|
Uri.encode(phoneNumber),
|
||||||
),
|
),
|
||||||
arrayOf(ContactsContract.PhoneLookup._ID),
|
arrayOf(ContactsContract.PhoneLookup._ID),
|
||||||
null,
|
null,
|
||||||
|
@ -109,8 +110,8 @@ class CallRedirectionService : CallRedirectionService() {
|
||||||
arrayOf(ContactsContract.Data._ID, ContactsContract.Data.MIMETYPE),
|
arrayOf(ContactsContract.Data._ID, ContactsContract.Data.MIMETYPE),
|
||||||
"${ContactsContract.Data.CONTACT_ID} = ? AND " +
|
"${ContactsContract.Data.CONTACT_ID} = ? AND " +
|
||||||
"${ContactsContract.Data.MIMETYPE} IN " +
|
"${ContactsContract.Data.MIMETYPE} IN " +
|
||||||
"(${MIMETYPES.keys.joinToString(",") { "?" }})",
|
"(${MIMETYPE_TO_WEIGHT.keys.joinToString(",") { "?" }})",
|
||||||
arrayOf(contactId, *MIMETYPES.keys.toTypedArray()),
|
arrayOf(contactId, *MIMETYPE_TO_WEIGHT.keys.toTypedArray()),
|
||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
cursor?.apply {
|
cursor?.apply {
|
||||||
|
|
|
@ -23,6 +23,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
private lateinit var prefs: Preferences
|
private lateinit var prefs: Preferences
|
||||||
|
private lateinit var window: PopupWindow
|
||||||
private var roleManager: RoleManager? = null
|
private var roleManager: RoleManager? = null
|
||||||
|
|
||||||
private val registerForCallRedirectionRole =
|
private val registerForCallRedirectionRole =
|
||||||
|
@ -42,14 +43,20 @@ class MainActivity : AppCompatActivity() {
|
||||||
setup()
|
setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
window.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
private fun init() {
|
private fun init() {
|
||||||
prefs = Preferences(this)
|
prefs = Preferences(this)
|
||||||
|
window = PopupWindow(this, null)
|
||||||
roleManager = getSystemService(RoleManager::class.java)
|
roleManager = getSystemService(RoleManager::class.java)
|
||||||
binding.apply {
|
binding.apply {
|
||||||
redirectionDelay.value = (prefs.redirectionDelay / 1000).toFloat()
|
redirectionDelay.value = (prefs.redirectionDelay / 1000).toFloat()
|
||||||
popupPosition.editText?.setText(prefs.popupPosition.toString())
|
popupPosition.editText?.setText(prefs.popupPosition.toString())
|
||||||
fallback.isChecked = prefs.isFallbackChecked
|
fallback.isChecked = prefs.isFallbackChecked
|
||||||
toggle.isChecked = prefs.isServiceEnabled
|
toggle.isChecked = prefs.isEnabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +68,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
redirectionDelay.addOnChangeListener { _, value, _ ->
|
redirectionDelay.addOnChangeListener { _, value, _ ->
|
||||||
prefs.redirectionDelay = (value * 1000).toLong()
|
prefs.redirectionDelay = (value * 1000).toLong()
|
||||||
}
|
}
|
||||||
|
popupPosition.setEndIconOnClickListener {
|
||||||
|
window.preview()
|
||||||
|
}
|
||||||
popupPosition.editText?.doAfterTextChanged {
|
popupPosition.editText?.doAfterTextChanged {
|
||||||
try {
|
try {
|
||||||
prefs.popupPosition = it?.toString()?.toInt() ?: return@doAfterTextChanged
|
prefs.popupPosition = it?.toString()?.toInt() ?: return@doAfterTextChanged
|
||||||
|
@ -75,7 +85,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
requestPermissions()
|
requestPermissions()
|
||||||
return@setOnCheckedChangeListener
|
return@setOnCheckedChangeListener
|
||||||
}
|
}
|
||||||
prefs.isServiceEnabled = isChecked
|
prefs.isEnabled = isChecked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package me.lucky.red
|
package me.lucky.red
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
|
@ -10,20 +11,19 @@ import android.view.LayoutInflater
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.concurrent.timerTask
|
import kotlin.concurrent.timerTask
|
||||||
|
|
||||||
class PopupWindow(private val service: CallRedirectionService) {
|
class PopupWindow(
|
||||||
private val windowManager = service
|
private val ctx: Context,
|
||||||
.applicationContext
|
private val service: WeakReference<CallRedirectionService>?,
|
||||||
.getSystemService(WindowManager::class.java)
|
) {
|
||||||
private val audioManager = service
|
private val prefs = Preferences(ctx)
|
||||||
.applicationContext
|
private val windowManager = ctx.getSystemService(WindowManager::class.java)
|
||||||
.getSystemService(AudioManager::class.java)
|
private val audioManager = ctx.getSystemService(AudioManager::class.java)
|
||||||
@Suppress("InflateParams")
|
@Suppress("InflateParams")
|
||||||
private val view = LayoutInflater
|
private val view = LayoutInflater.from(ctx).inflate(R.layout.popup, null)
|
||||||
.from(service.applicationContext)
|
|
||||||
.inflate(R.layout.popup, null)
|
|
||||||
private val layoutParams = WindowManager.LayoutParams().apply {
|
private val layoutParams = WindowManager.LayoutParams().apply {
|
||||||
format = PixelFormat.TRANSLUCENT
|
format = PixelFormat.TRANSLUCENT
|
||||||
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
@ -31,18 +31,32 @@ class PopupWindow(private val service: CallRedirectionService) {
|
||||||
gravity = Gravity.BOTTOM
|
gravity = Gravity.BOTTOM
|
||||||
width = WindowManager.LayoutParams.WRAP_CONTENT
|
width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
height = WindowManager.LayoutParams.WRAP_CONTENT
|
height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
y = service.prefs.popupPosition
|
y = prefs.popupPosition
|
||||||
}
|
}
|
||||||
private var timer: Timer? = null
|
private var timer: Timer? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
view.setOnClickListener {
|
view.setOnClickListener {
|
||||||
cancel()
|
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) {
|
fun show(uri: Uri, destinationId: Int) {
|
||||||
|
val service = service?.get() ?: return
|
||||||
if (!remove()) {
|
if (!remove()) {
|
||||||
service.placeCallUnmodified()
|
service.placeCallUnmodified()
|
||||||
return
|
return
|
||||||
|
@ -65,23 +79,27 @@ class PopupWindow(private val service: CallRedirectionService) {
|
||||||
return@timerTask
|
return@timerTask
|
||||||
}
|
}
|
||||||
service.cancelCall()
|
service.cancelCall()
|
||||||
}, service.prefs.redirectionDelay)
|
}, prefs.redirectionDelay)
|
||||||
view.findViewById<TextView>(R.id.description).text = String.format(
|
setDescription(destinationId)
|
||||||
service.getString(R.string.popup),
|
|
||||||
service.getString(destinationId),
|
|
||||||
)
|
|
||||||
if (!add()) {
|
if (!add()) {
|
||||||
timer?.cancel()
|
timer?.cancel()
|
||||||
service.placeCallUnmodified()
|
service.placeCallUnmodified()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setDescription(id: Int) {
|
||||||
|
view.findViewById<TextView>(R.id.description).text = ctx.getString(
|
||||||
|
R.string.popup,
|
||||||
|
ctx.getString(id),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.CALL_PHONE)
|
@RequiresPermission(Manifest.permission.CALL_PHONE)
|
||||||
private fun call(data: Uri) {
|
private fun call(data: Uri) {
|
||||||
Intent(Intent.ACTION_VIEW).let {
|
Intent(Intent.ACTION_VIEW).let {
|
||||||
it.data = data
|
it.data = data
|
||||||
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
service.startActivity(it)
|
ctx.startActivity(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,23 @@ import androidx.preference.PreferenceManager
|
||||||
|
|
||||||
class Preferences(ctx: Context) {
|
class Preferences(ctx: Context) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val SERVICE_ENABLED = "service_enabled"
|
private const val ENABLED = "enabled"
|
||||||
private const val REDIRECTION_DELAY = "redirection_delay"
|
private const val REDIRECTION_DELAY = "redirection_delay"
|
||||||
private const val POPUP_POSITION = "popup_position_y"
|
private const val POPUP_POSITION = "popup_position_y"
|
||||||
private const val FALLBACK_CHECKED = "fallback_checked"
|
private const val FALLBACK_CHECKED = "fallback_checked"
|
||||||
|
|
||||||
private const val DEFAULT_REDIRECTION_DELAY = 2000L
|
private const val DEFAULT_REDIRECTION_DELAY = 2000L
|
||||||
private const val DEFAULT_POPUP_POSITION = 333
|
private const val DEFAULT_POPUP_POSITION = 333
|
||||||
|
|
||||||
|
// migration
|
||||||
|
private const val SERVICE_ENABLED = "service_enabled"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val prefs = PreferenceManager.getDefaultSharedPreferences(ctx)
|
private val prefs = PreferenceManager.getDefaultSharedPreferences(ctx)
|
||||||
|
|
||||||
var isServiceEnabled: Boolean
|
var isEnabled: Boolean
|
||||||
get() = prefs.getBoolean(SERVICE_ENABLED, false)
|
get() = prefs.getBoolean(ENABLED, prefs.getBoolean(SERVICE_ENABLED, false))
|
||||||
set(value) = prefs.edit { putBoolean(SERVICE_ENABLED, value) }
|
set(value) = prefs.edit { putBoolean(ENABLED, value) }
|
||||||
|
|
||||||
var redirectionDelay: Long
|
var redirectionDelay: Long
|
||||||
get() = prefs.getLong(REDIRECTION_DELAY, DEFAULT_REDIRECTION_DELAY)
|
get() = prefs.getLong(REDIRECTION_DELAY, DEFAULT_REDIRECTION_DELAY)
|
||||||
|
|
10
app/src/main/res/drawable/ic_baseline_check_circle_24.xml
Normal file
10
app/src/main/res/drawable/ic_baseline_check_circle_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
|
||||||
|
</vector>
|
|
@ -55,6 +55,8 @@
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/popupPosition"
|
android:id="@+id/popupPosition"
|
||||||
|
app:endIconMode="custom"
|
||||||
|
app:endIconDrawable="@drawable/ic_baseline_check_circle_24"
|
||||||
android:hint="@string/popup_position"
|
android:hint="@string/popup_position"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<string name="destination_signal">Signal</string>
|
<string name="destination_signal">Signal</string>
|
||||||
<string name="destination_telegram">Telegram</string>
|
<string name="destination_telegram">Telegram</string>
|
||||||
<string name="destination_threema">Threema</string>
|
<string name="destination_threema">Threema</string>
|
||||||
<string name="redirection_delay_description">Delay before a call will be redirected.</string>
|
<string name="redirection_delay_description">The delay before a call will be redirected.</string>
|
||||||
<string name="popup_position">Popup position</string>
|
<string name="popup_position">Popup position</string>
|
||||||
<string name="fallback">Fallback</string>
|
<string name="fallback">Fallback</string>
|
||||||
<string name="fallback_description">Redirect to WhatsApp if no other available.</string>
|
<string name="fallback_description">Redirect to WhatsApp if no other available.</string>
|
||||||
|
|
|
@ -5,8 +5,8 @@ buildscript {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
classpath 'com.android.tools.build:gradle:7.2.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
1
fastlane/metadata/android/en-US/changelogs/9.txt
Normal file
1
fastlane/metadata/android/en-US/changelogs/9.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
popup window preview
|
Binary file not shown.
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 92 KiB |
|
@ -1,4 +1,4 @@
|
||||||
Минимальное приложение для перенаправления исходящих вызовов в Signal/Telegram/Threema.
|
Мини приложение для перенаправления исходящих вызовов в Signal/Telegram/Threema.
|
||||||
|
|
||||||
Вы можете отменить перенаправление, кликнув на всплывающее сообщение "Перенаправление в..".
|
Вы можете отменить перенаправление, кликнув на всплывающее сообщение "Перенаправление в..".
|
||||||
|
|
||||||
|
|
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
|
#Tue Jun 14 23:11:06 MSK 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=f581709a9c35e9cb92e16f585d2c4bc99b2b1a5f85d2badbd3dc6bff59e1e6dd
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue