More permissions request improvements
This commit is contained in:
@ -10,7 +10,6 @@
|
||||
<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_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.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
@ -123,43 +123,45 @@ class ConfigActivity : AppCompatActivity() {
|
||||
if (isChecked) {
|
||||
if (Build.VERSION.SDK_INT < 29) {
|
||||
certificateFile.isChecked = false
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
Log.d(TAG, "Read External Storage permission granted")
|
||||
val downloadsPath = Utils.downloadsPath("cert.pem")
|
||||
val content = Utils.getFileContents(downloadsPath)
|
||||
if (content == null) {
|
||||
Utils.alertView(
|
||||
this, getString(R.string.error),
|
||||
getString(R.string.read_cert_error)
|
||||
)
|
||||
return@setOnCheckedChangeListener
|
||||
) == PackageManager.PERMISSION_GRANTED -> {
|
||||
Log.d(TAG, "Read External Storage permission granted")
|
||||
val downloadsPath = Utils.downloadsPath("cert.pem")
|
||||
val content = Utils.getFileContents(downloadsPath)
|
||||
if (content == null) {
|
||||
Utils.alertView(
|
||||
this, getString(R.string.error),
|
||||
getString(R.string.read_cert_error)
|
||||
)
|
||||
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"
|
||||
Utils.putFileContents(filesPath, content)
|
||||
Config.removeVariable("sip_certificate")
|
||||
Config.addLine("sip_certificate $filesPath")
|
||||
certificateFile.isChecked = true
|
||||
save = true
|
||||
restart = true
|
||||
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
) {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_restore),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_restore),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
Utils.selectInputFile(certificateRequest)
|
||||
@ -211,43 +213,45 @@ class ConfigActivity : AppCompatActivity() {
|
||||
if (isChecked) {
|
||||
if (Build.VERSION.SDK_INT < 29) {
|
||||
caFile.isChecked = false
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
Log.d(TAG, "Read External Storage permission granted")
|
||||
val downloadsPath = Utils.downloadsPath("ca_certs.crt")
|
||||
val content = Utils.getFileContents(downloadsPath)
|
||||
if (content == null) {
|
||||
Utils.alertView(
|
||||
this, getString(R.string.error),
|
||||
getString(R.string.read_ca_certs_error)
|
||||
)
|
||||
return@setOnCheckedChangeListener
|
||||
) == PackageManager.PERMISSION_GRANTED -> {
|
||||
Log.d(TAG, "Read External Storage permission granted")
|
||||
val downloadsPath = Utils.downloadsPath("ca_certs.crt")
|
||||
val content = Utils.getFileContents(downloadsPath)
|
||||
if (content == null) {
|
||||
Utils.alertView(
|
||||
this, getString(R.string.error),
|
||||
getString(R.string.read_ca_certs_error)
|
||||
)
|
||||
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"
|
||||
Utils.putFileContents(filesPath, content)
|
||||
Config.removeVariable("sip_cafile")
|
||||
Config.addLine("sip_cafile $filesPath")
|
||||
caFile.isChecked = true
|
||||
save = true
|
||||
restart = true
|
||||
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
)
|
||||
) {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_restore),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_restore),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
Utils.selectInputFile(certificatesRequest)
|
||||
|
||||
@ -5,13 +5,8 @@ const val TAG = "Baresip"
|
||||
const val DEFAULT_CHANNEL_ID = "com.tutpro.baresip.default"
|
||||
const val HIGH_CHANNEL_ID = "com.tutpro.baresip.high"
|
||||
|
||||
const val BACKUP_PERMISSION_REQUEST_CODE = 1
|
||||
const val RESTORE_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 CALL_PERMISSION_REQUEST_CODE = 1
|
||||
const val CONTACT_PERMISSION_REQUEST_CODE = 2
|
||||
|
||||
const val STATUS_NOTIFICATION_ID = 101
|
||||
const val CALL_NOTIFICATION_ID = 102
|
||||
|
||||
@ -207,39 +207,40 @@ class ContactActivity : AppCompatActivity() {
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
||||
grandResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grandResults)
|
||||
var allowed = true
|
||||
when (requestCode) {
|
||||
CONTACT_PERMISSION_REQUEST_CODE ->
|
||||
CONTACT_PERMISSION_REQUEST_CODE -> {
|
||||
var allowed = true
|
||||
for (res in grandResults)
|
||||
allowed = allowed && res == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
if (!allowed) {
|
||||
androidCheck.isChecked = oldAndroid
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_CONTACTS
|
||||
))
|
||||
{
|
||||
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.WRITE_CONTACTS
|
||||
))
|
||||
{
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_android_contacts),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
requestPermissionsLauncher.launch(permissions)
|
||||
if (!allowed) {
|
||||
androidCheck.isChecked = oldAndroid
|
||||
when {
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||
Manifest.permission.READ_CONTACTS) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_android_contacts),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
requestPermissionsLauncher.launch(permissions)
|
||||
}
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||
Manifest.permission.WRITE_CONTACTS) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_android_contacts),
|
||||
Snackbar.LENGTH_INDEFINITE,
|
||||
getString(R.string.ok)
|
||||
) {
|
||||
requestPermissionsLauncher.launch(permissions)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
requestPermissionsLauncher.launch(permissions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,10 +310,12 @@ class MainActivity : AppCompatActivity() {
|
||||
callButton.setOnClickListener {
|
||||
if (aorSpinner.selectedItemPosition == -1)
|
||||
return@setOnClickListener
|
||||
val permissions = arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE)
|
||||
if (Build.VERSION.SDK_INT >= 23)
|
||||
if (!Utils.checkPermissions(this, permissions))
|
||||
requestPermissions(permissions, CALL_PERMISSION_REQUEST_CODE)
|
||||
val permissions = arrayOf(Manifest.permission.RECORD_AUDIO)
|
||||
if (Build.VERSION.SDK_INT < 23 || Utils.checkPermissions(this, permissions))
|
||||
makeCall()
|
||||
else
|
||||
ActivityCompat.requestPermissions(this, permissions,
|
||||
CALL_PERMISSION_REQUEST_CODE)
|
||||
}
|
||||
|
||||
hangupButton.setOnClickListener {
|
||||
@ -722,89 +724,6 @@ class MainActivity : AppCompatActivity() {
|
||||
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) {
|
||||
// Called when MainActivity already exists at the top of current task
|
||||
super.onNewIntent(intent)
|
||||
@ -1264,20 +1183,20 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
R.id.backup -> {
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
pickupFileFromDownloads("backup")
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED) {
|
||||
when {
|
||||
Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("backup")
|
||||
ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED -> {
|
||||
Log.d(TAG, "Write External Storage permission granted")
|
||||
val path = Utils.downloadsPath("baresip.bs")
|
||||
downloadsOutputStream = FileOutputStream(File(path))
|
||||
askPassword(getString(R.string.encrypt_password))
|
||||
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_backup),
|
||||
@ -1286,28 +1205,28 @@ class MainActivity : AppCompatActivity() {
|
||||
) {
|
||||
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
R.id.restore -> {
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
pickupFileFromDownloads("restore")
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED) {
|
||||
when {
|
||||
Build.VERSION.SDK_INT >= 29 -> pickupFileFromDownloads("restore")
|
||||
ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED -> {
|
||||
Log.d(TAG, "Read External Storage permission granted")
|
||||
val path = Utils.downloadsPath("baresip.bs")
|
||||
downloadsInputStream = FileInputStream(File(path))
|
||||
askPassword(getString(R.string.decrypt_password))
|
||||
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
this,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE) -> {
|
||||
layout.showSnackBar(
|
||||
binding.root,
|
||||
getString(R.string.no_restore),
|
||||
@ -1316,7 +1235,8 @@ class MainActivity : AppCompatActivity() {
|
||||
) {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else -> {
|
||||
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
}
|
||||
}
|
||||
@ -1333,6 +1253,31 @@ class MainActivity : AppCompatActivity() {
|
||||
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)
|
||||
private fun pickupFileFromDownloads(action: String) {
|
||||
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) {
|
||||
if (Call.uaCalls(ua, "").size == 0) {
|
||||
swipeRefresh.isEnabled = true
|
||||
|
||||
@ -359,7 +359,7 @@ object Utils {
|
||||
fun checkPermissions(ctx: Context, permissions: Array<String>) : Boolean {
|
||||
for (p in permissions) {
|
||||
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
|
||||
} else {
|
||||
Log.d(TAG, "Permission $p is granted")
|
||||
|
||||
@ -447,12 +447,12 @@
|
||||
<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
|
||||
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
|
||||
Telephone permissions.</string>
|
||||
<string name="no_backup">You are not able create backup without Storage permission.</string>
|
||||
<string name="no_calls">You are not able to make or answer calls without Microphone
|
||||
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
|
||||
Contacts permission.</string>
|
||||
<string name="no_restore">You are not able restore backup without Storage permission.</string>
|
||||
\"Contacts\" 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_cameras">You don\'t have any supported video cameras.</string>
|
||||
<string name="show_password">Show Password</string>
|
||||
|
||||
Reference in New Issue
Block a user