New Welcome screen
This commit is contained in:
parent
794fe46b45
commit
cba93c6069
7 changed files with 221 additions and 18 deletions
|
@ -69,4 +69,5 @@ dependencies {
|
|||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'nl.dionsegijn:konfetti-xml:2.0.2' // This library holds the fabric of reality together please dont remove it at any costs >:3
|
||||
}
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
android:theme="@style/Theme.Pulse">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".WelcomeActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".MainActivity" />
|
||||
|
||||
<service
|
||||
android:name=".CallRedirectionService"
|
||||
|
|
|
@ -22,14 +22,10 @@ import partisan.weforge.xyz.pulse.setServicePriority
|
|||
import partisan.weforge.xyz.pulse.isServiceEnabled
|
||||
import partisan.weforge.xyz.pulse.setServiceEnabled
|
||||
import partisan.weforge.xyz.pulse.databinding.ActivityMainBinding
|
||||
import partisan.weforge.xyz.pulse.REQUIRED_PERMISSIONS
|
||||
import partisan.weforge.xyz.pulse.hasGeneralPermissions
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
companion object {
|
||||
private val PERMISSIONS = arrayOf(
|
||||
Manifest.permission.READ_CONTACTS,
|
||||
Manifest.permission.CALL_PHONE,
|
||||
)
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private lateinit var prefs: Preferences
|
||||
|
@ -156,28 +152,22 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
private fun requestPermissions() {
|
||||
when {
|
||||
!hasGeneralPermissions() -> requestGeneralPermissions()
|
||||
!hasGeneralPermissions(this) -> registerForGeneralPermissions.launch(REQUIRED_PERMISSIONS)
|
||||
!hasDrawOverlays() -> requestDrawOverlays()
|
||||
!hasCallRedirectionRole() -> requestCallRedirectionRole()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasPermissions(): Boolean {
|
||||
return hasGeneralPermissions() && hasDrawOverlays() && hasCallRedirectionRole()
|
||||
return hasGeneralPermissions(this) &&
|
||||
hasDrawOverlays(this) &&
|
||||
hasCallRedirectionRole(this)
|
||||
}
|
||||
|
||||
private fun requestDrawOverlays() {
|
||||
registerForDrawOverlays.launch(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION))
|
||||
}
|
||||
|
||||
private fun requestGeneralPermissions() {
|
||||
registerForGeneralPermissions.launch(PERMISSIONS)
|
||||
}
|
||||
|
||||
private fun hasGeneralPermissions(): Boolean {
|
||||
return !PERMISSIONS.any { checkSelfPermission(it) != PackageManager.PERMISSION_GRANTED }
|
||||
}
|
||||
|
||||
private fun hasDrawOverlays(): Boolean {
|
||||
return Settings.canDrawOverlays(this)
|
||||
}
|
||||
|
|
28
app/src/main/java/partisan/weforge/xyz/pulse/Permissions.kt
Normal file
28
app/src/main/java/partisan/weforge/xyz/pulse/Permissions.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
package partisan.weforge.xyz.pulse
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.provider.Settings
|
||||
import android.app.role.RoleManager
|
||||
|
||||
val REQUIRED_PERMISSIONS = arrayOf(
|
||||
Manifest.permission.READ_CONTACTS,
|
||||
Manifest.permission.CALL_PHONE,
|
||||
)
|
||||
|
||||
fun hasGeneralPermissions(context: Context): Boolean {
|
||||
return REQUIRED_PERMISSIONS.all {
|
||||
context.checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
fun hasDrawOverlays(context: Context): Boolean {
|
||||
return Settings.canDrawOverlays(context)
|
||||
}
|
||||
|
||||
fun hasCallRedirectionRole(context: Context): Boolean {
|
||||
val roleManager = context.getSystemService(RoleManager::class.java)
|
||||
return roleManager?.isRoleHeld(RoleManager.ROLE_CALL_REDIRECTION) ?: false
|
||||
}
|
107
app/src/main/java/partisan/weforge/xyz/pulse/WelcomeActivity.kt
Normal file
107
app/src/main/java/partisan/weforge/xyz/pulse/WelcomeActivity.kt
Normal file
|
@ -0,0 +1,107 @@
|
|||
package partisan.weforge.xyz.pulse
|
||||
|
||||
import android.Manifest
|
||||
import android.app.role.RoleManager
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import nl.dionsegijn.konfetti.core.Party
|
||||
import nl.dionsegijn.konfetti.core.Position
|
||||
import nl.dionsegijn.konfetti.core.emitter.Emitter
|
||||
import nl.dionsegijn.konfetti.xml.KonfettiView
|
||||
import partisan.weforge.xyz.pulse.databinding.ActivityWelcomeBinding
|
||||
import java.util.concurrent.TimeUnit
|
||||
import partisan.weforge.xyz.pulse.hasGeneralPermissions
|
||||
import partisan.weforge.xyz.pulse.hasDrawOverlays
|
||||
import partisan.weforge.xyz.pulse.hasCallRedirectionRole
|
||||
import partisan.weforge.xyz.pulse.REQUIRED_PERMISSIONS
|
||||
|
||||
class WelcomeActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityWelcomeBinding
|
||||
private lateinit var prefs: Preferences
|
||||
private var roleManager: RoleManager? = null
|
||||
|
||||
private val requestPermissionsLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
) {}
|
||||
|
||||
private val requestOverlayLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {}
|
||||
|
||||
private val requestRoleLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (hasGeneralPermissions(this) && hasDrawOverlays(this) && hasCallRedirectionRole(this)) {
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
binding = ActivityWelcomeBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
prefs = Preferences(this)
|
||||
roleManager = getSystemService(RoleManager::class.java)
|
||||
|
||||
binding.activateButton.setOnClickListener {
|
||||
when {
|
||||
!hasGeneralPermissions(this) -> {
|
||||
requestPermissionsLauncher.launch(REQUIRED_PERMISSIONS)
|
||||
}
|
||||
!hasDrawOverlays(this) -> {
|
||||
requestOverlayLauncher.launch(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION))
|
||||
}
|
||||
!hasCallRedirectionRole(this) -> {
|
||||
requestRoleLauncher.launch(roleManager?.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION))
|
||||
}
|
||||
else -> {
|
||||
prefs.isEnabled = true
|
||||
showConfettiAndContinue()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showConfettiAndContinue() {
|
||||
binding.appIcon.post {
|
||||
val iconLocation = IntArray(2)
|
||||
binding.appIcon.getLocationOnScreen(iconLocation)
|
||||
|
||||
val iconCenterX = iconLocation[0] + binding.appIcon.width / 2f
|
||||
val iconCenterY = iconLocation[1] + binding.appIcon.height / 2f
|
||||
|
||||
val rootWidth = binding.root.width.toFloat()
|
||||
val rootHeight = binding.root.height.toFloat()
|
||||
|
||||
val relativeX = (iconCenterX / rootWidth).toDouble()
|
||||
val relativeY = (iconCenterY / rootHeight).toDouble()
|
||||
|
||||
binding.konfettiView.visibility = View.VISIBLE
|
||||
binding.konfettiView.start(
|
||||
Party(
|
||||
speed = 30f,
|
||||
maxSpeed = 50f,
|
||||
damping = 0.9f,
|
||||
spread = 360,
|
||||
colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
|
||||
position = Position.Relative(relativeX, relativeY),
|
||||
emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(100)
|
||||
)
|
||||
)
|
||||
|
||||
binding.konfettiView.postDelayed({
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
}
|
74
app/src/main/res/layout/activity_welcome.xml
Normal file
74
app/src/main/res/layout/activity_welcome.xml
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="32dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/contentWrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/appIcon"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="96dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/appDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/description"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/activateButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/activate"
|
||||
android:layout_marginTop="32dp"
|
||||
app:cornerRadius="24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activateDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/activate_description"
|
||||
android:textAlignment="center"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="16dp" />
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<nl.dionsegijn.konfetti.xml.KonfettiView
|
||||
android:id="@+id/konfettiView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Pulse</string>
|
||||
<string name="description">The app will try to redirect outgoing calls to Signal/Telegram/Threema/WhatsApp if available. For work it requires many permissions. Click on the toggle and grant permissions until it turns ON.</string>
|
||||
<string name="description">App will try to redirect outgoing calls to E2EE apps if available.</string>
|
||||
<string name="popup">Redirecting to %1$s</string>
|
||||
<string name="destination_signal">Signal</string>
|
||||
<string name="destination_telegram">Telegram</string>
|
||||
|
@ -10,4 +10,6 @@
|
|||
<string name="redirection_delay_description">The delay before a call will be redirected.</string>
|
||||
<string name="popup_position">Popup position</string>
|
||||
<string name="fallback">Fallback</string>
|
||||
<string name="activate_description">To start, grant the required permissions and tap the Activate button.</string>
|
||||
<string name="activate">Activate</string>
|
||||
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue