需求原因,需要在APP中加一个通话功能。想着功能应该不难,遂网上随便抄了一份,打算交作业,但居然还crash了。没办法,去官网查阅资料。其中细节还是有必要记录下来,以资来者。
非敏感使用
近期APP应用用户隐私保护的管理力度日益增长,所以尽可能少在AndroidManifest.xml
权限吧,少一些解释麻烦,所以可以采用Google提供的跳转到Android系统指定的通话的拨号盘方式处理。顺带将号码传递过去,用户需要在通话APP上点击拨号按钮以完成通话任务。这种方式的好处在于显式跳转了系统APP,通话行为要求用户在系统APP上进行,所以免去了敏感权限的申请,也就无需在APP上架时,解释获取android.permission.CALL_PHONE
权限意欲何为了。
调用代码十分简单,如下:
public void dialPhoneNumber(String phoneNumber) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + phoneNumber));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
丝滑流畅使用
虽然不用权限直接跳转的方式对于开发者而言,即安全又省力,但是对于产品来说,这个交互体验略为粗糙,这种断裂的交互中还有流失用户的可能。所以,我们又试验了Google的另一种拨号方式,由APP直接拨打电话。由于该行为会产生通讯资费,且拨打行为属于高危权限,所以该操作需要进行动态权限获取,实现上略微复杂,如下。
@SuppressLint("WrongConstant")
public void callPhoneNumberWithPermissionCheck(String phoneNumber) {
if (PermissionUtils.isGranted(Manifest.permission.CALL_PHONE)) {
callPhoneNumber(phoneNumber);
} else {
PermissionUtils.permission(Manifest.permission.CALL_PHONE).callback(new PermissionUtils.SimpleCallback() {
@Override
public void onGranted() {
callPhoneNumber(phoneNumber);
}
@Override
public void onDenied() {
Toast.makeText(MainActivity.this, "电话权限被拒绝", Toast.LENGTH_SHORT).show();
PermissionUtils.openAppSettings();
}
}).request();
}
}
public void callPhoneNumber(String phoneNumber) {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phoneNumber));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
AndroidManifest.xml
中增加权限声明
<uses-permission android:name="android.permission.CALL_PHONE"/>
build.gradle
中增加AndroidUtilCode
依赖
implementation 'com.blankj:utilcode:1.12.5'
关于动态申请权限,Google提供了一套成熟的方案,但是实现起来略为复杂,本次使用三方库(AndroidUtilCode)完成权限动态申请,想要了解原生实现方式的可以跳转至Android原生动态权限申请方法