如何在Kotlin中正确调用电话Intent?Android 6权限问题求解
解决Android 6上调用CALL_PHONE权限抛出SecurityException的问题
你遇到的问题核心在于Android 6(API 23)引入的运行时权限机制——CALL_PHONE属于危险权限,仅仅在AndroidManifest.xml里声明权限是不够的,必须在代码中主动向用户申请授权,而你之前的代码只做了权限检查,却没有触发实际的授权请求流程。
下面是完整的解决步骤:
1. 确保Manifest中已声明权限(你已经做了,这里再确认下)
在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.CALL_PHONE" />
2. 实现完整的运行时权限请求流程
你需要在代码中完成「检查权限→请求权限→处理授权结果」的完整逻辑,替换你之前的权限检查代码:
class ProfileActivity : AppCompatActivity() { // 自定义权限请求码,用来区分不同的权限请求 private val REQUEST_CALL_PERMISSION = 100 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_profile) // 给电话图标设置点击事件 imgPhone.setOnClickListener { attemptPhoneCall() } } private fun attemptPhoneCall() { val targetNumber = "1122334455" // 检查当前是否已获得拨打电话权限 val hasPermission = ContextCompat.checkSelfPermission( this, Manifest.permission.CALL_PHONE ) == PackageManager.PERMISSION_GRANTED if (hasPermission) { // 权限已授予,直接启动拨打电话的Intent val callIntent = Intent(Intent.ACTION_CALL, Uri.parse("tel:$targetNumber")) startActivity(callIntent) } else { // 权限未授予,向用户发起权限请求 ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.CALL_PHONE), REQUEST_CALL_PERMISSION ) } } // 处理用户对权限请求的响应 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_CALL_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意授权,再次尝试拨打电话 attemptPhoneCall() } else { // 用户拒绝授权,提示用户需要权限才能执行操作 Toast.makeText(this, "需要授予拨打电话权限才能完成此操作", Toast.LENGTH_SHORT).show() } } } }
为什么你之前的方案无效?
- 你之前的
setupPermissions()方法仅仅检查了权限状态并打印日志,但没有主动发起授权请求,所以系统仍然会阻止你的Intent调用 android:exported="true"是用来控制组件是否允许被其他应用调用的,和权限问题完全无关,这个设置对你的场景没有帮助
额外提示
如果用户拒绝权限并勾选了「不再询问」,后续的权限请求会直接被拒绝。这种情况下,你可以引导用户到应用的设置页面手动开启权限:
// 当权限被拒绝且无法再次请求时,跳转到应用设置 val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package", packageName, null) intent.data = uri startActivity(intent)
另外,如果你不需要直接拨打电话,只是想打开拨号界面让用户手动确认,可以使用Intent.ACTION_DIAL,这个Intent不需要任何权限:
val dialIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$targetNumber")) startActivity(dialIntent)
内容的提问来源于stack exchange,提问作者anta40
相关产品推荐
相关产品推荐

