1、添加权限

在AndroidManifest.xml 添加打电话权限

<uses-permission android:name="android.permission.CALL_PHONE"/>

2、自动布局设置页面

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"> <TextView
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:text="@string/textPhone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> <EditText
android:id="@+id/et_phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:hint="@string/textPhoneHint"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_phone" /> <Button
android:id="@+id/btn_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="16dp"
android:text="@string/textPhoneButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_phone" /> </androidx.constraintlayout.widget.ConstraintLayout>

页面效果

3、给Activity添加拔打代码

public class MainActivity extends  BaseActivity {

    private Button eBtCall;
private EditText mEtPhone; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); eBtCall = findViewById(R.id.btn_call);
mEtPhone = findViewById(R.id.et_phone);
eBtCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
performCodeWithPermission("拔打电话权限", new PermissionCallback() {
@Override
public void hasPermission() {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + mEtPhone.getText()));
startActivity(intent);
} @Override
public void noPermission() { }
}, Manifest.permission.CALL_PHONE);
}
});
}
}

4、这里要注意,安卓在6.0之后是动态申请系统权限,因而封装一个权限的BaseActivity类,专门用于处理权限相关的。

package com.jiangys.telephonedial;

import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.Toast; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; /**
* @author Admin
* @version $Rev$
* @des ${TODO}
* @updateAuthor $Author$
* @updateDes ${TODO}
*/
public class BaseActivity extends AppCompatActivity {
//**************** Android M Permission (Android 6.0权限控制代码封装)
private int permissionRequestCode = 88;
private PermissionCallback permissionRunnable; public interface PermissionCallback {
void hasPermission(); void noPermission();
} /**
* Android M运行时权限请求封装
*
* @param permissionDes 权限描述
* @param runnable 请求权限回调
* @param permissions 请求的权限(数组类型),直接从Manifest中读取相应的值,比如Manifest.permission.WRITE_CONTACTS
*/
public void performCodeWithPermission(@NonNull String permissionDes, PermissionCallback runnable, @NonNull String... permissions) {
if (permissions == null || permissions.length == 0)
return;
// this.permissionrequestCode = requestCode;
this.permissionRunnable = runnable;
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || checkPermissionGranted(permissions)) {
if (permissionRunnable != null) {
permissionRunnable.hasPermission();
permissionRunnable = null;
}
} else {
//permission has not been granted.
requestPermission(permissionDes, permissionRequestCode, permissions);
} } private boolean checkPermissionGranted(String[] permissions) {
boolean flag = true;
for (String p : permissions) {
if (ActivityCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) {
flag = false;
break;
}
}
return flag;
} private void requestPermission(String permissionDes, final int requestCode, final String[] permissions) {
if (shouldShowRequestPermissionRationale(permissions)) {
/*1. 第一次请求权限时,用户拒绝了,下一次:shouldShowRequestPermissionRationale() 返回 true,应该显示一些为什么需要这个权限的说明
2.第二次请求权限时,用户拒绝了,并选择了“不在提醒”的选项时:shouldShowRequestPermissionRationale() 返回 false
3. 设备的策略禁止当前应用获取这个权限的授权:shouldShowRequestPermissionRationale() 返回 false*/
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example, if the request has been denied previously. // Snackbar.make(getWindow().getDecorView(), requestName,
// Snackbar.LENGTH_INDEFINITE)
// .setAction(R.string.common_ok, new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// ActivityCompat.requestPermissions(BaseAppCompatActivity.this,
// permissions,
// requestCode);
// }
// })
// .show();
//如果用户之前拒绝过此权限,再提示一次准备授权相关权限
new AlertDialog.Builder(this)
.setTitle("提示")
.setMessage(permissionDes)
.setPositiveButton("授权", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);
}
}).show(); } else {
// Contact permissions have not been granted yet. Request them directly.
ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);
}
} private boolean shouldShowRequestPermissionRationale(String[] permissions) {
boolean flag = false;
for (String p : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, p)) {
flag = true;
break;
}
}
return flag;
} /**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == permissionRequestCode) {
if (verifyPermissions(grantResults)) {
if (permissionRunnable != null) {
permissionRunnable.hasPermission();
permissionRunnable = null;
}
} else {
Toast.makeText(this, "暂无权限执行相关操作!", Toast.LENGTH_SHORT).show();
if (permissionRunnable != null) {
permissionRunnable.noPermission();
permissionRunnable = null;
}
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
} } public boolean verifyPermissions(int[] grantResults) {
// At least one result must be checked.
if (grantResults.length < 1) {
return false;
} // Verify that each required permission has been granted, otherwise return false.
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
//********************** END Android M Permission ****************************************
}

Android 基础-2.0 拔打电话号码的更多相关文章

  1. Android 基础-3.0 数据存储方式

    Android几种数据存储方式 文件存储 SharedPreference存储 Json解析 SQLite数据库存储 文件存储 文件存储是Android中最基本的一种存储方式,和Java中实现I/O的 ...

  2. Android 基础-1.0 按钮4种点击事件

    第一种 测试使用 直接xml添加,平时在自己的测试demo中使用比较多. 1.直接在xml里给按钮添加点击事件 android:onClick="btn_click" 2.按住op ...

  3. Android程序开发0基础教程(一)

    程序猿学英语就上视觉英语网 Android程序开发0基础教程(一)   平台简单介绍   令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...

  4. [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图

    关于如何移植在android上使用SDL,可以参考[原]零基础学习SDL开发之移植SDL2.0到Android 和 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 . 在一篇 ...

  5. 1.0 Android基础入门教程

    1.0 Android基础入门教程 分类 Android 基础入门教程 本教程于2015年7月开始撰写,耗时半年,总共148节,涵盖了Android基础入门的大部分知识,由于当时能力局限,虽已竭尽全力 ...

  6. [原]零基础学习SDL开发之在Android使用SDL2.0渲染PNG图片

    在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张bmp图,但是如果是一张png或者一张jpg的图,那么还能显示成功么?答案是否定的 我们需要移植SDL_image库来支持除bm ...

  7. [原]零基础学习SDL开发之在Android使用SDL2.0加载字体

    在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张png图,而且在上上一篇我们知道如何使用sdl来渲染输出bmp图,那么sdl是否可以渲染输出自己喜爱的字体库的字体呢?答案是当然 ...

  8. Android基础——项目的文件结构(二)

    Android基础--项目的文件结构(二) AndroidManifest.xml文件分析 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目 ...

  9. Android基础新手教程——4.4.1 ContentProvider初探

    Android基础新手教程--4.4.1 ContentProvider初探 标签(空格分隔): Android基础新手教程 本节引言: 本节给大家带来的是Android四大组件中的最后一个--Con ...

随机推荐

  1. 不可忽略的apache 的 Keep Alive

    转载链接:http://hi.baidu.com/jx_iben/item/d5fe91feed74495ec9f337f1 在网页开发过程中,Keep-Alive是HTTP协议中非常重要的一个属性. ...

  2. C# 中安全代码与不安全代码

    C# 中安全代码与不安全代码 P/Invoke 非托管代码需要在unsafe块中书写. using System; using System.Collections.Generic; using Sy ...

  3. ASP.NET动态网站制作(22)-- ADO.NET(1)

    前言:这节课开始真正地学习WEB开发,ADO.NET就是一组允许.NET开发人员使用标准的.机构化的,甚至无连接的方式与数据交互的技术.所属的类库为:System.Data.dll. 内容: 1.AD ...

  4. iOS开发---业务逻辑

    iOS开发---业务逻辑   1. 业务逻辑 iOS的app开发的最终目的是要让用户使用, 用户使用app完成自己的事就是业务逻辑, 业务逻辑的是最显眼开发工作.但是业务逻辑对于开发任务来说, 只是露 ...

  5. html5-框架网站

    1.html5+:http://www.html5plus.org/ 2.hbuilder:http://www.dcloud.io/ 3.mui:http://dev.dcloud.net.cn/m ...

  6. POJ 1860

    须要推断是否有正权环存在,Bellman-Ford算法就能够辣~ AC代码: #include <iostream> #include <cstdio> #include &l ...

  7. 使用UIImageView展现来自网络的图片

    本文转载至 http://www.cnblogs.com/chivas/archive/2012/05/21/2512324.html UIImageView:可以通过UIImage加载图片赋给UII ...

  8. 【BZOJ4769】超级贞鱼 归并排序求逆序对

    [BZOJ4769]超级贞鱼 Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的左脚和右脚上各有一个数.有一天,K只贞鱼兴致来潮,排成一列,从左到右第i ...

  9. java拾遗2----XML解析(二) SAX解析

    XML解析之SAX解析: SAX解析器:SAXParser类同DOM一样也在javax.xml.parsers包下,此类的实例可以从 SAXParserFactory.newSAXParser() 方 ...

  10. plsql 详细安装及汉化步骤

    方法/步骤   双击运行plsqldev715 安装完成后我们装中文补丁: 双击运行‘Chinese’应用程序 找到PLSQL的安装目录添加进来 中文补丁安装完成后我们需要进行orcl的配置,配置好才 ...