Allow selecting baresip as the default Phone app

This commit is contained in:
Juha Heinanen
2023-05-07 14:17:23 +03:00
parent 35222b0a5d
commit 91b04ef221
5 changed files with 156 additions and 45 deletions
+41 -5
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools" >
<uses-permission android:name="android.permission.BLUETOOTH" <uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" /> android:maxSdkVersion="30" />
@@ -15,8 +15,7 @@
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" /> android:maxSdkVersion="32" />
<uses-permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" android:maxSdkVersion="28"
tools:ignore="ScopedStorage" /> tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />
@@ -44,6 +43,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:remove="android:appComponentFactory" > tools:remove="android:appComponentFactory" >
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
@@ -55,6 +55,11 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" /> <action android:name="android.intent.action.DIAL" />
@@ -63,26 +68,29 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" /> <data android:scheme="tel" />
<data android:scheme="sip" /> <data android:scheme="sip" />
<data android:scheme="sips" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".AccountsActivity" android:name=".AccountsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/accounts" android:label="@string/accounts"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<activity <activity
android:name=".AccountActivity" android:name=".AccountActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/account" > android:label="@string/account" >
</activity> </activity>
<activity <activity
android:name=".CodecsActivity" android:name=".CodecsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/codecs" android:label="@string/codecs"
android:parentActivityName=".AccountActivity" > android:parentActivityName=".AccountActivity" >
</activity> </activity>
<activity <activity
android:name=".ContactsActivity" android:name=".ContactsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
@@ -90,59 +98,69 @@
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:windowSoftInputMode="adjustPan" > android:windowSoftInputMode="adjustPan" >
</activity> </activity>
<activity <activity
android:name=".ContactActivity" android:name=".ContactActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/contact" android:label="@string/contact"
android:parentActivityName=".ContactsActivity" > android:parentActivityName=".ContactsActivity" >
</activity> </activity>
<activity <activity
android:name=".AndroidContactActivity" android:name=".AndroidContactActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/contact" android:label="@string/contact"
android:parentActivityName=".ContactsActivity" > android:parentActivityName=".ContactsActivity" >
</activity> </activity>
<activity <activity
android:name=".ConfigActivity" android:name=".ConfigActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/configuration" android:label="@string/configuration"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<activity <activity
android:name=".AudioActivity" android:name=".AudioActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/audio_settings" android:label="@string/audio_settings"
android:parentActivityName=".ConfigActivity" > android:parentActivityName=".ConfigActivity" >
</activity> </activity>
<activity <activity
android:name=".CallsActivity" android:name=".CallsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/call_history" android:label="@string/call_history"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<activity <activity
android:name=".CallDetailsActivity" android:name=".CallDetailsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/call_details" android:label="@string/call_details"
android:parentActivityName=".CallsActivity" > android:parentActivityName=".CallsActivity" >
</activity> </activity>
<activity <activity
android:name=".ChatsActivity" android:name=".ChatsActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/chats" android:label="@string/chats"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<activity <activity
android:name=".ChatActivity" android:name=".ChatActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/chat" > android:label="@string/chat" >
</activity> </activity>
<activity <activity
android:name=".AboutActivity" android:name=".AboutActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/about_title" android:label="@string/about_title"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<service <service
android:name=".BaresipService" android:name=".BaresipService"
android:enabled="true" android:enabled="true"
@@ -150,6 +168,23 @@
android:permission="android.permission.FOREGROUND_SERVICE" android:permission="android.permission.FOREGROUND_SERVICE"
android:stopWithTask="false" > android:stopWithTask="false" >
</service> </service>
<service
android:name=".InCallService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_INCALL_SERVICE" >
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
android:value="false" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
<receiver <receiver
android:name=".BootCompletedReceiver" android:name=".BootCompletedReceiver"
android:enabled="true" android:enabled="true"
@@ -160,11 +195,12 @@
<action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver <receiver
android:name=".TaskReceiver" android:name=".TaskReceiver"
android:enabled="true" android:enabled="true"
android:exported="true" android:exported="true"
tools:ignore="ExportedReceiver"> tools:ignore="ExportedReceiver" >
<intent-filter> <intent-filter>
<action android:name="com.tutpro.baresip.REGISTER" /> <action android:name="com.tutpro.baresip.REGISTER" />
<action android:name="com.tutpro.baresip.UNREGISTER" /> <action android:name="com.tutpro.baresip.UNREGISTER" />
@@ -2,6 +2,7 @@ package com.tutpro.baresip
import android.Manifest import android.Manifest
import android.app.Activity import android.app.Activity
import android.app.role.RoleManager
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -21,6 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.transition.Visibility
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.tutpro.baresip.Utils.copyInputStreamToFile import com.tutpro.baresip.Utils.copyInputStreamToFile
@@ -36,7 +38,6 @@ class ConfigActivity : AppCompatActivity() {
private lateinit var layout: ScrollView private lateinit var layout: ScrollView
private lateinit var baresipService: Intent private lateinit var baresipService: Intent
private lateinit var autoStart: CheckBox private lateinit var autoStart: CheckBox
private lateinit var batteryOptimizations: CheckBox
private lateinit var listenAddr: EditText private lateinit var listenAddr: EditText
private lateinit var netAfSpinner: Spinner private lateinit var netAfSpinner: Spinner
private lateinit var netAf: String private lateinit var netAf: String
@@ -49,6 +50,8 @@ class ConfigActivity : AppCompatActivity() {
private lateinit var contactsSpinner: Spinner private lateinit var contactsSpinner: Spinner
private lateinit var contactsMode: String private lateinit var contactsMode: String
private lateinit var contactsModeKeys: ArrayList<String> private lateinit var contactsModeKeys: ArrayList<String>
private lateinit var batteryOptimizations: CheckBox
private lateinit var defaultDialer: CheckBox
private lateinit var debug: CheckBox private lateinit var debug: CheckBox
private lateinit var sipTrace: CheckBox private lateinit var sipTrace: CheckBox
private lateinit var reset: CheckBox private lateinit var reset: CheckBox
@@ -74,6 +77,7 @@ class ConfigActivity : AppCompatActivity() {
goBack() goBack()
} }
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -109,6 +113,37 @@ class ConfigActivity : AppCompatActivity() {
} }
} }
if (Build.VERSION.SDK_INT >= 29) {
val roleManager = getSystemService(ROLE_SERVICE) as RoleManager
defaultDialer = binding.DefaultPhoneApp
defaultDialer.isChecked = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
val dialerRoleRequest = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
Log.d(TAG, "dialerRoleRequest succeeded: ${it.resultCode == Activity.RESULT_OK}")
defaultDialer.isChecked = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
}
defaultDialer.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER))
Utils.alertView(this, getString(R.string.notice),
getString(R.string.dialer_role_not_available))
else
if (!roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))
} else {
try {
dialerRoleRequest.launch(Intent("android.settings.MANAGE_DEFAULT_APPS_SETTINGS"))
} catch (e: ActivityNotFoundException) {
Log.e(TAG, "ActivityNotFound exception: $e")
}
}
}
} else {
binding.PhoneApp.visibility = View.GONE
}
listenAddr = binding.ListenAddress listenAddr = binding.ListenAddress
val laCv = Config.variable("sip_listen") val laCv = Config.variable("sip_listen")
oldListenAddr = if (laCv.size == 0) "" else laCv[0] oldListenAddr = if (laCv.size == 0) "" else laCv[0]
@@ -642,10 +677,6 @@ class ConfigActivity : AppCompatActivity() {
Utils.alertView(this, getString(R.string.start_automatically), Utils.alertView(this, getString(R.string.start_automatically),
getString(R.string.start_automatically_help)) getString(R.string.start_automatically_help))
} }
binding.BatteryOptimizationsTitle.setOnClickListener {
Utils.alertView(this, getString(R.string.battery_optimizations),
getString(R.string.battery_optimizations_help))
}
binding.ListenAddressTitle.setOnClickListener { binding.ListenAddressTitle.setOnClickListener {
Utils.alertView(this, getString(R.string.listen_address), Utils.alertView(this, getString(R.string.listen_address),
getString(R.string.listen_address_help)) getString(R.string.listen_address_help))
@@ -681,6 +712,14 @@ class ConfigActivity : AppCompatActivity() {
Utils.alertView(this, getString(R.string.contacts), Utils.alertView(this, getString(R.string.contacts),
getString(R.string.contacts_help)) getString(R.string.contacts_help))
} }
binding.BatteryOptimizationsTitle.setOnClickListener {
Utils.alertView(this, getString(R.string.battery_optimizations),
getString(R.string.battery_optimizations_help))
}
binding.DefaultPhoneAppTitle.setOnClickListener {
Utils.alertView(this, getString(R.string.default_phone_app),
getString(R.string.default_phone_app_help))
}
binding.DebugTitle.setOnClickListener { binding.DebugTitle.setOnClickListener {
Utils.alertView(this, getString(R.string.debug), getString(R.string.debug_help)) Utils.alertView(this, getString(R.string.debug), getString(R.string.debug_help))
} }
@@ -9,6 +9,7 @@ import android.app.NotificationManager
import android.content.* import android.content.*
import android.content.Intent.ACTION_CALL import android.content.Intent.ACTION_CALL
import android.content.Intent.ACTION_DIAL import android.content.Intent.ACTION_DIAL
import android.content.Intent.ACTION_VIEW
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration.ORIENTATION_PORTRAIT import android.content.res.Configuration.ORIENTATION_PORTRAIT
import android.media.AudioManager import android.media.AudioManager
@@ -40,6 +41,7 @@ import java.io.File
import java.net.URLDecoder import java.net.URLDecoder
import kotlin.system.exitProcess import kotlin.system.exitProcess
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
@@ -653,11 +655,14 @@ class MainActivity : AppCompatActivity() {
atStartup = intent.hasExtra("onStartup") atStartup = intent.hasExtra("onStartup")
if (intent?.action == ACTION_CALL || intent?.action == ACTION_DIAL) { when (intent?.action) {
if (BaresipService.isServiceRunning) ACTION_DIAL, ACTION_CALL, ACTION_VIEW ->
callAction(intent) if (BaresipService.isServiceRunning)
else callAction(intent)
BaresipService.callActionUri = URLDecoder.decode(intent.data.toString(), "UTF-8") else
BaresipService.callActionUri = URLDecoder.decode(intent.data.toString(), "UTF-8")
else ->
Log.d(TAG, "Unknown startup action ${intent?.action}")
} }
permissions = if (Build.VERSION.SDK_INT >= 33) permissions = if (Build.VERSION.SDK_INT >= 33)
@@ -824,10 +829,10 @@ class MainActivity : AppCompatActivity() {
resumeAction = "" resumeAction = ""
resumeUri = "" resumeUri = ""
Log.d(TAG, "onNewIntent with intent.action '${intent.action}'") Log.d(TAG, "onNewIntent with action/data '${intent.action}/${intent.data}'")
when (intent.action) { when (intent.action) {
ACTION_DIAL, ACTION_CALL -> { ACTION_DIAL, ACTION_CALL, ACTION_VIEW -> {
callAction(intent) callAction(intent)
} }
else -> { else -> {
+54 -27
View File
@@ -41,33 +41,6 @@
</CheckBox> </CheckBox>
</RelativeLayout> </RelativeLayout>
<RelativeLayout
android:id="@+id/Battery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/BatteryOptimizationsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/BatteryOptimizations"
android:textSize="18sp"
android:text="@string/battery_optimizations" >
</TextView>
<CheckBox
android:id="@+id/BatteryOptimizations"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
<TextView <TextView
android:id="@+id/ListenAddressTitle" android:id="@+id/ListenAddressTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -254,6 +227,60 @@
android:paddingTop="8dp" > android:paddingTop="8dp" >
</Spinner> </Spinner>
<RelativeLayout
android:id="@+id/Battery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/BatteryOptimizationsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/BatteryOptimizations"
android:textSize="18sp"
android:text="@string/battery_optimizations" >
</TextView>
<CheckBox
android:id="@+id/BatteryOptimizations"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
<RelativeLayout
android:id="@+id/PhoneApp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/DefaultPhoneAppTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_toStartOf="@id/DefaultPhoneApp"
android:textSize="18sp"
android:text="@string/default_phone_app" >
</TextView>
<CheckBox
android:id="@+id/DefaultPhoneApp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
+4
View File
@@ -297,6 +297,10 @@
<string name="battery_optimizations_help">Disable battery optimizations (recommended) if you want <string name="battery_optimizations_help">Disable battery optimizations (recommended) if you want
to reduce likelihood that Android restricts baresip\'s access to network or enters baresip to reduce likelihood that Android restricts baresip\'s access to network or enters baresip
to standby state.</string> to standby state.</string>
<string name="default_phone_app">Default Phone App</string>
<string name="dialer_role_not_available">Dialer role is not available</string>
<string name="default_phone_app_help">If checked, baresip is the default phone app. Only choose
if your device never makes or receives calls or messages from telecom (cellular) network.</string>
<string name="listen_address">Listen Address</string> <string name="listen_address">Listen Address</string>
<string name="listen_address_help">IP address and port of form \'address:port\' at which baresip listens <string name="listen_address_help">IP address and port of form \'address:port\' at which baresip listens
for incoming SIP requests. If IP address is an IPv6 address, it must be written inside for incoming SIP requests. If IP address is an IPv6 address, it must be written inside