More permissions request improvements

This commit is contained in:
Juha Heinanen
2021-11-10 10:37:15 +02:00
parent 801c232793
commit 861693a197
7 changed files with 204 additions and 216 deletions

View File

@ -10,7 +10,6 @@
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<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" />

View File

@ -123,43 +123,45 @@ class ConfigActivity : AppCompatActivity() {
if (isChecked) { if (isChecked) {
if (Build.VERSION.SDK_INT < 29) { if (Build.VERSION.SDK_INT < 29) {
certificateFile.isChecked = false certificateFile.isChecked = false
if (ContextCompat.checkSelfPermission( when {
ContextCompat.checkSelfPermission(
this, this,
Manifest.permission.READ_EXTERNAL_STORAGE Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED ) == PackageManager.PERMISSION_GRANTED -> {
) { Log.d(TAG, "Read External Storage permission granted")
Log.d(TAG, "Read External Storage permission granted") val downloadsPath = Utils.downloadsPath("cert.pem")
val downloadsPath = Utils.downloadsPath("cert.pem") val content = Utils.getFileContents(downloadsPath)
val content = Utils.getFileContents(downloadsPath) if (content == null) {
if (content == null) { Utils.alertView(
Utils.alertView( this, getString(R.string.error),
this, getString(R.string.error), getString(R.string.read_cert_error)
getString(R.string.read_cert_error) )
) return@setOnCheckedChangeListener
return@setOnCheckedChangeListener }
val filesPath = BaresipService.filesPath + "/cert.pem"
Utils.putFileContents(filesPath, content)
Config.removeVariable("sip_certificate")
Config.addLine("sip_certificate $filesPath")
certificateFile.isChecked = true
save = true
restart = true
} }
val filesPath = BaresipService.filesPath + "/cert.pem" ActivityCompat.shouldShowRequestPermissionRationale(
Utils.putFileContents(filesPath, content)
Config.removeVariable("sip_certificate")
Config.addLine("sip_certificate $filesPath")
certificateFile.isChecked = true
save = true
restart = true
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
this, this,
Manifest.permission.READ_EXTERNAL_STORAGE Manifest.permission.READ_EXTERNAL_STORAGE
) ) -> {
) { layout.showSnackBar(
layout.showSnackBar( binding.root,
binding.root, getString(R.string.no_restore),
getString(R.string.no_restore), Snackbar.LENGTH_INDEFINITE,
Snackbar.LENGTH_INDEFINITE, getString(R.string.ok)
getString(R.string.ok) ) {
) { requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
}
}
else -> {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else { } else {
Utils.selectInputFile(certificateRequest) Utils.selectInputFile(certificateRequest)
@ -211,43 +213,45 @@ class ConfigActivity : AppCompatActivity() {
if (isChecked) { if (isChecked) {
if (Build.VERSION.SDK_INT < 29) { if (Build.VERSION.SDK_INT < 29) {
caFile.isChecked = false caFile.isChecked = false
if (ContextCompat.checkSelfPermission( when {
ContextCompat.checkSelfPermission(
this, this,
Manifest.permission.READ_EXTERNAL_STORAGE Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED ) == PackageManager.PERMISSION_GRANTED -> {
) { Log.d(TAG, "Read External Storage permission granted")
Log.d(TAG, "Read External Storage permission granted") val downloadsPath = Utils.downloadsPath("ca_certs.crt")
val downloadsPath = Utils.downloadsPath("ca_certs.crt") val content = Utils.getFileContents(downloadsPath)
val content = Utils.getFileContents(downloadsPath) if (content == null) {
if (content == null) { Utils.alertView(
Utils.alertView( this, getString(R.string.error),
this, getString(R.string.error), getString(R.string.read_ca_certs_error)
getString(R.string.read_ca_certs_error) )
) return@setOnCheckedChangeListener
return@setOnCheckedChangeListener }
val filesPath = BaresipService.filesPath + "/ca_certs.crt"
Utils.putFileContents(filesPath, content)
Config.removeVariable("sip_cafile")
Config.addLine("sip_cafile $filesPath")
caFile.isChecked = true
save = true
restart = true
} }
val filesPath = BaresipService.filesPath + "/ca_certs.crt" ActivityCompat.shouldShowRequestPermissionRationale(
Utils.putFileContents(filesPath, content) this,
Config.removeVariable("sip_cafile") Manifest.permission.READ_EXTERNAL_STORAGE
Config.addLine("sip_cafile $filesPath") ) -> {
caFile.isChecked = true layout.showSnackBar(
save = true binding.root,
restart = true getString(R.string.no_restore),
} else if (ActivityCompat.shouldShowRequestPermissionRationale( Snackbar.LENGTH_INDEFINITE,
this, getString(R.string.ok)
Manifest.permission.READ_EXTERNAL_STORAGE ) {
) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
) { }
layout.showSnackBar( }
binding.root, else -> {
getString(R.string.no_restore),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else { } else {
Utils.selectInputFile(certificatesRequest) Utils.selectInputFile(certificatesRequest)

View File

@ -5,13 +5,8 @@ const val TAG = "Baresip"
const val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default" const val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default"
const val HIGH_CHANNEL_ID = "com.tutpro.baresip.high" const val HIGH_CHANNEL_ID = "com.tutpro.baresip.high"
const val BACKUP_PERMISSION_REQUEST_CODE = 1 const val CALL_PERMISSION_REQUEST_CODE = 1
const val RESTORE_PERMISSION_REQUEST_CODE = 2 const val CONTACT_PERMISSION_REQUEST_CODE = 2
const val CALL_PERMISSION_REQUEST_CODE = 3
const val CONTACT_PERMISSION_REQUEST_CODE = 4
const val READ_CERT_PERMISSION_CODE = 5
const val READ_CA_PERMISSION_CODE = 6
const val REQUEST_PERMISSIONS_CODE = 7
const val STATUS_NOTIFICATION_ID = 101 const val STATUS_NOTIFICATION_ID = 101
const val CALL_NOTIFICATION_ID = 102 const val CALL_NOTIFICATION_ID = 102

View File

@ -207,39 +207,40 @@ class ContactActivity : AppCompatActivity() {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grandResults: IntArray) { grandResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grandResults) super.onRequestPermissionsResult(requestCode, permissions, grandResults)
var allowed = true
when (requestCode) { when (requestCode) {
CONTACT_PERMISSION_REQUEST_CODE -> CONTACT_PERMISSION_REQUEST_CODE -> {
var allowed = true
for (res in grandResults) for (res in grandResults)
allowed = allowed && res == PackageManager.PERMISSION_GRANTED allowed = allowed && res == PackageManager.PERMISSION_GRANTED
} if (!allowed) {
if (!allowed) { androidCheck.isChecked = oldAndroid
androidCheck.isChecked = oldAndroid when {
if (ActivityCompat.shouldShowRequestPermissionRationale( ActivityCompat.shouldShowRequestPermissionRationale(this,
this, Manifest.permission.READ_CONTACTS) -> {
Manifest.permission.READ_CONTACTS layout.showSnackBar(
)) binding.root,
{ getString(R.string.no_android_contacts),
layout.showSnackBar( Snackbar.LENGTH_INDEFINITE,
binding.root, getString(R.string.ok)
getString(R.string.no_android_contacts), ) {
Snackbar.LENGTH_INDEFINITE, requestPermissionsLauncher.launch(permissions)
getString(R.string.ok) }
) { }
requestPermissionsLauncher.launch(permissions) ActivityCompat.shouldShowRequestPermissionRationale(this,
} Manifest.permission.WRITE_CONTACTS) -> {
} else if (ActivityCompat.shouldShowRequestPermissionRationale( layout.showSnackBar(
this, binding.root,
Manifest.permission.WRITE_CONTACTS getString(R.string.no_android_contacts),
)) Snackbar.LENGTH_INDEFINITE,
{ getString(R.string.ok)
layout.showSnackBar( ) {
binding.root, requestPermissionsLauncher.launch(permissions)
getString(R.string.no_android_contacts), }
Snackbar.LENGTH_INDEFINITE, }
getString(R.string.ok) else -> {
) { requestPermissionsLauncher.launch(permissions)
requestPermissionsLauncher.launch(permissions) }
}
} }
} }
} }

View File

@ -310,10 +310,12 @@ class MainActivity : AppCompatActivity() {
callButton.setOnClickListener { callButton.setOnClickListener {
if (aorSpinner.selectedItemPosition == -1) if (aorSpinner.selectedItemPosition == -1)
return@setOnClickListener return@setOnClickListener
val permissions = arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE) val permissions = arrayOf(Manifest.permission.RECORD_AUDIO)
if (Build.VERSION.SDK_INT >= 23) if (Build.VERSION.SDK_INT < 23 || Utils.checkPermissions(this, permissions))
if (!Utils.checkPermissions(this, permissions)) makeCall()
requestPermissions(permissions, CALL_PERMISSION_REQUEST_CODE) else
ActivityCompat.requestPermissions(this, permissions,
CALL_PERMISSION_REQUEST_CODE)
} }
hangupButton.setOnClickListener { hangupButton.setOnClickListener {
@ -722,89 +724,6 @@ class MainActivity : AppCompatActivity() {
super.onDestroy() super.onDestroy()
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grandResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grandResults)
var allowed = true
when (requestCode) {
CALL_PERMISSION_REQUEST_CODE -> {
for (res in grandResults)
allowed = allowed && res == PackageManager.PERMISSION_GRANTED
if (allowed) {
callUri.setAdapter(null)
val ua = UserAgent.uas()[aorSpinner.selectedItemPosition]
val aor = ua.account.aor
if (Call.calls().isEmpty()) {
val uriText = callUri.text.toString().trim()
if (uriText.isNotEmpty()) {
val uri = Utils.uriComplete(
ContactsActivity.findContactURI(uriText)
.filterNot { it.isWhitespace() },
Utils.aorDomain(aor)
)
if (!Utils.checkSipUri(uri)) {
Utils.alertView(
this, getString(R.string.notice),
String.format(getString(R.string.invalid_sip_uri), uri)
)
} else {
callUri.isFocusable = false
if (!call(ua, uri)) {
callButton.visibility = View.VISIBLE
callButton.isEnabled = true
hangupButton.visibility = View.INVISIBLE
hangupButton.isEnabled = false
} else {
callButton.visibility = View.INVISIBLE
callButton.isEnabled = false
hangupButton.visibility = View.VISIBLE
hangupButton.isEnabled = true
}
}
} else {
val latest = CallHistory.aorLatestHistory(aor)
if (latest != null)
callUri.setText(
Utils.friendlyUri(
ContactsActivity.contactName(latest.peerUri),
Utils.aorDomain(ua.account.aor)
)
)
}
}
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.RECORD_AUDIO
)
) {
layout.showSnackBar(
binding.root,
getString(R.string.no_android_contacts),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionsLauncher.launch(permissions)
}
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.READ_PHONE_STATE
)
) {
layout.showSnackBar(
binding.root,
getString(R.string.no_android_contacts),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionsLauncher.launch(permissions)
}
}
}
}
}
}
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
// Called when MainActivity already exists at the top of current task // Called when MainActivity already exists at the top of current task
super.onNewIntent(intent) super.onNewIntent(intent)
@ -1264,20 +1183,20 @@ class MainActivity : AppCompatActivity() {
} }
R.id.backup -> { R.id.backup -> {
if (Build.VERSION.SDK_INT >= 29) { when {
pickupFileFromDownloads("backup") Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("backup")
} else { ContextCompat.checkSelfPermission(
if (ContextCompat.checkSelfPermission( this,
this, Manifest.permission.WRITE_EXTERNAL_STORAGE
Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED -> {
) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Write External Storage permission granted") Log.d(TAG, "Write External Storage permission granted")
val path = Utils.downloadsPath("baresip.bs") val path = Utils.downloadsPath("baresip.bs")
downloadsOutputStream = FileOutputStream(File(path)) downloadsOutputStream = FileOutputStream(File(path))
askPassword(getString(R.string.encrypt_password)) askPassword(getString(R.string.encrypt_password))
} else if (ActivityCompat.shouldShowRequestPermissionRationale( }
this, ActivityCompat.shouldShowRequestPermissionRationale(
Manifest.permission.WRITE_EXTERNAL_STORAGE)) { this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) -> {
layout.showSnackBar( layout.showSnackBar(
binding.root, binding.root,
getString(R.string.no_backup), getString(R.string.no_backup),
@ -1286,28 +1205,28 @@ class MainActivity : AppCompatActivity() {
) { ) {
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} }
} else { }
else -> {
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} }
} }
} }
R.id.restore -> { R.id.restore -> {
if (Build.VERSION.SDK_INT >= 29) { when {
pickupFileFromDownloads("restore") Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("restore")
} else { ContextCompat.checkSelfPermission(
if (ContextCompat.checkSelfPermission( this,
this, Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED -> {
) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Read External Storage permission granted") Log.d(TAG, "Read External Storage permission granted")
val path = Utils.downloadsPath("baresip.bs") val path = Utils.downloadsPath("baresip.bs")
downloadsInputStream = FileInputStream(File(path)) downloadsInputStream = FileInputStream(File(path))
askPassword(getString(R.string.decrypt_password)) askPassword(getString(R.string.decrypt_password))
} else if (ActivityCompat.shouldShowRequestPermissionRationale( }
this, ActivityCompat.shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) { this,
Manifest.permission.READ_EXTERNAL_STORAGE) -> {
layout.showSnackBar( layout.showSnackBar(
binding.root, binding.root,
getString(R.string.no_restore), getString(R.string.no_restore),
@ -1316,7 +1235,8 @@ class MainActivity : AppCompatActivity() {
) { ) {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} else { }
else -> {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
} }
} }
@ -1333,6 +1253,31 @@ class MainActivity : AppCompatActivity() {
return true return true
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,
grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
CALL_PERMISSION_REQUEST_CODE -> {
if ((grantResults.isNotEmpty()) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
makeCall()
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.RECORD_AUDIO)) {
layout.showSnackBar(
binding.root,
getString(R.string.no_calls),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
}
} else {
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
}
}
}
}
@RequiresApi(29) @RequiresApi(29)
private fun pickupFileFromDownloads(action: String) { private fun pickupFileFromDownloads(action: String) {
when (action) { when (action) {
@ -1666,6 +1611,50 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun makeCall() {
callUri.setAdapter(null)
val ua = UserAgent.uas()[aorSpinner.selectedItemPosition]
val aor = ua.account.aor
if (Call.calls().isEmpty()) {
val uriText = callUri.text.toString().trim()
if (uriText.isNotEmpty()) {
val uri = Utils.uriComplete(
ContactsActivity.findContactURI(uriText)
.filterNot { it.isWhitespace() },
Utils.aorDomain(aor)
)
if (!Utils.checkSipUri(uri)) {
Utils.alertView(
this, getString(R.string.notice),
String.format(getString(R.string.invalid_sip_uri), uri)
)
} else {
callUri.isFocusable = false
if (!call(ua, uri)) {
callButton.visibility = View.VISIBLE
callButton.isEnabled = true
hangupButton.visibility = View.INVISIBLE
hangupButton.isEnabled = false
} else {
callButton.visibility = View.INVISIBLE
callButton.isEnabled = false
hangupButton.visibility = View.VISIBLE
hangupButton.isEnabled = true
}
}
} else {
val latest = CallHistory.aorLatestHistory(aor)
if (latest != null)
callUri.setText(
Utils.friendlyUri(
ContactsActivity.contactName(latest.peerUri),
Utils.aorDomain(ua.account.aor)
)
)
}
}
}
private fun showCall(ua: UserAgent) { private fun showCall(ua: UserAgent) {
if (Call.uaCalls(ua, "").size == 0) { if (Call.uaCalls(ua, "").size == 0) {
swipeRefresh.isEnabled = true swipeRefresh.isEnabled = true

View File

@ -359,7 +359,7 @@ object Utils {
fun checkPermissions(ctx: Context, permissions: Array<String>) : Boolean { fun checkPermissions(ctx: Context, permissions: Array<String>) : Boolean {
for (p in permissions) { for (p in permissions) {
if (ContextCompat.checkSelfPermission(ctx, p) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(ctx, p) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Permission $p is not granted") Log.d(TAG, "Permission $p is denied")
return false return false
} else { } else {
Log.d(TAG, "Permission $p is granted") Log.d(TAG, "Permission $p is granted")

View File

@ -447,12 +447,12 @@
<string name="restore_failed">Failed to restore application data. Check that you gave correct <string name="restore_failed">Failed to restore application data. Check that you gave correct
password. In Android versions 9 and below, also check Apps → baresip → Permissions → Storage password. In Android versions 9 and below, also check Apps → baresip → Permissions → Storage
and that file \'%1$s\' exists in Download folder.</string> and that file \'%1$s\' exists in Download folder.</string>
<string name="no_calls">You are not able to make or answer calls without Microphone and <string name="no_calls">You are not able to make or answer calls without Microphone
Telephone permissions.</string> permission.</string>
<string name="no_backup">You are not able create backup without Storage permission.</string> <string name="no_backup">You are not able create backup without \"Storage\" permission.</string>
<string name="no_android_contacts">You are not able add or remove Android contacts without <string name="no_android_contacts">You are not able add or remove Android contacts without
Contacts permission.</string> \"Contacts\" permission.</string>
<string name="no_restore">You are not able restore backup without Storage permission.</string> <string name="no_restore">You are not able restore backup without \"Storage\" permission.</string>
<string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string> <string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string>
<string name="no_cameras">You don\'t have any supported video cameras.</string> <string name="no_cameras">You don\'t have any supported video cameras.</string>
<string name="show_password">Show Password</string> <string name="show_password">Show Password</string>