新手开局,查看一些旧资料,从打电话、发短信的小应用开始。代码很简单,主要是学习了:

  • 用StartActivity()激活一个Activity组件。这里是激活了系统原生的打电话和发短信Activity。
  • Intent意图对象的使用,包括设置其动作和数据。
  • 在Manifest.xml清单文件中添加所需的权限。

做个笔记,主要代码如下:

public class MainActivity extends Activity {

    private Button btn_dial;
private EditText et_number; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找到控件
et_number = (EditText) findViewById(R.id.et_number);
btn_dial = (Button) findViewById(R.id.btn_dial); // 给按钮设置监听(点击事件)
btn_dial.setOnClickListener(new View.OnClickListener() { // 匿名内部类
// 按钮点击时回调
@Override
public void onClick(View view) {
// 获取号码
String number = et_number.getText().toString();
if (TextUtils.isEmpty(number)){
// 提醒用户
// 注意:在这个匿名内部类中如果用this则表示是View.OnClickListener类的对象,
// 所以必须用MainActivity.this来指定上下文环境。
Toast.makeText(MainActivity.this, "号码不能为空!", Toast.LENGTH_SHORT).show();
}else{
// 拨号:激活系统的拨号组件
Intent intent = new Intent(); // 意图对象:动作 + 数据
intent.setAction(Intent.ACTION_CALL); // 设置动作
Uri data = Uri.parse("tel:" + number); // 设置数据
intent.setData(data);
startActivity(intent); // 激活Activity组件
}
}
});
}
}

在Manifest清单中也配置了所需的拨号权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.guxin.a01_helloworld"> <!-- 拨号权限 -->
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

然后遇到的问题是,在Android6.0目标平台下,即便已经添加了打电话的权限,运行时依然会报错安全异常:权限被拒绝。

在Stack Overflow上搜到了一个很靠谱的答案:
添加了权限依然报错权限拒绝

根据老外的提示,原来从Android6.0开始使用了新的运行时权限,权限种类被分为了【普通权限】和【危险权限】,顺藤摸瓜在官方文档学到了很有价值的东西,罗列一下以后在更新:

https://developer.android.com/training/permissions/index.html
学习关于系统权限

https://developer.android.com/training/permissions/declaring.html
如何申明权限

https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
权限被分为了普通和危险两种

https://developer.android.com/training/permissions/requesting.html#perm-check
【重要】如何在运行时检查并申请权限!!!!


推荐博文:

http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/
http://blog.csdn.net/lmj623565791/article/details/50709663
http://www.cnblogs.com/mengdd/p/4892856.html
http://www.cnblogs.com/mengdd/p/4892856.html
http://www.2cto.com/kf/201512/455888.html

重要参考:http://stackoverflow.com/questions/30719047/android-m-check-runtime-permission-how-to-determine-if-the-user-checked-nev

根据以上资料,再次整理出打电话的Demo如下:

package com.demo.guxin.a01_helloworld;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity { private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;
private Button btn_dial;
private EditText et_number; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找到控件
et_number = (EditText) findViewById(R.id.et_number);
btn_dial = (Button) findViewById(R.id.btn_dial); // 给按钮设置监听(点击事件)
btn_dial.setOnClickListener(new View.OnClickListener() { // 匿名内部类
// 按钮点击时回调
@Override
public void onClick(View view) {
// 检查是否获得了权限(Android6.0运行时权限)
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){
// 没有获得授权,申请授权
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.CALL_PHONE)) {
// 返回值:
// 如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
// 如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
// 如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
// 弹窗需要解释为何需要该权限,再次请求授权
Toast.makeText(MainActivity.this, "请授权!", Toast.LENGTH_LONG).show(); // 帮跳转到该应用的设置界面,让用户手动授权
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}else{
// 不需要解释为何需要该权限,直接请求授权
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
}
}else {
// 已经获得授权,可以打电话
CallPhone();
}
}
});
} private void CallPhone() {
String number = et_number.getText().toString();
if (TextUtils.isEmpty(number)) {
// 提醒用户
// 注意:在这个匿名内部类中如果用this则表示是View.OnClickListener类的对象,
// 所以必须用MainActivity.this来指定上下文环境。
Toast.makeText(MainActivity.this, "号码不能为空!", Toast.LENGTH_SHORT).show();
} else {
// 拨号:激活系统的拨号组件
Intent intent = new Intent(); // 意图对象:动作 + 数据
intent.setAction(Intent.ACTION_CALL); // 设置动作
Uri data = Uri.parse("tel:" + number); // 设置数据
intent.setData(data);
startActivity(intent); // 激活Activity组件
}
} // 处理权限申请的回调
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case MY_PERMISSIONS_REQUEST_CALL_PHONE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 授权成功,继续打电话
CallPhone();
} else {
// 授权失败!
Toast.makeText(this, "授权失败!", Toast.LENGTH_LONG).show();
}
break;
}
} }
}

【Android】打电话Demo及Android6.0的运行时权限的更多相关文章

  1. Android6.0获取运行时权限

    照着<第一行代码>打代码,然并卵,感叹技术进步的神速.最后提醒一点:IT类的书籍一定要注意出版时间!出版时间!出版时间!重要的事情说三遍 问题出在android6.0的权限获取问题上,以前 ...

  2. Android 6.0的运行时权限

    原文  http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/ 主题 安卓开发   Andr ...

  3. 聊一聊 Android 6.0 的运行时权限

    权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权 ...

  4. 聊一聊Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  5. 安卓从业者应该关注:Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

  6. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  7. Android6.0运行时权限(基于RxPermission开源库)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了. And ...

  8. 一行代码解决Android M新的运行时权限问题

    Android M运行时权限是个啥东西 啥是运行时权限呢?Android M对权限管理系统进行了改版,之前我们的App需要权限,只需在manifest中申明即可,用户安装后,一切申明的权限都可来去自如 ...

  9. Android开发学习之路-Android6.0运行时权限

    在Android6.0以后开始,对于部分敏感的“危险”权限,需要在应用运行时向用户申请,只有用户允许的情况下这个权限才会被授予给应用.这对于用户来说,无疑是一个提升安全性的做法.那么对于开发者,应该怎 ...

随机推荐

  1. ldd 的一个安全问题

    我们知道“ldd”这个命令主要是被程序员或是管理员用来查看可执行文件所依赖的动态链接库的.是的,这就是这个命令的用处.可是,这个命令比你想像的要危险得多,也许很多黑客通过ldd的安全问题来攻击你的服务 ...

  2. Java Nashorn--Part 1

    伴随 Java 8 的发布,Oracle 也一同发布了 Nashorn,它是在 Java 虚拟机上运行 Javascript 语言的一个引擎.Nashorn 的设计是为了替换最初的运行在 JVM 上的 ...

  3. nginx根据http_user_agent防DDOS

    前端squid反向代理到nginx nginx根据http_user_agent防DDOS 首先查看访问日志,找出可疑访问 找到http_user_agent 的特征,然后再作过滤 "Moz ...

  4. logrotate日志管理工具

    一.概述 logrotate是一个Linux系统默认安装了的日志文件管理工具,用来把旧文件轮转.压缩.删除,并且创建新的日志文件.我们可以根据日志文件的大小.天数等来转储,便于对日志文件管理. log ...

  5. 第2章 Python基础-字符编码&数据类型 购物车&多级菜单 作业

    作业 一.三级菜单 数据结构: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, ...

  6. Hive实现从表中随机抽样得到一个不重复的数据样本

    select a.* from ( select a.*,rand(12345) as random from tripdata a ) a where random between 0 and 0. ...

  7. Android SDK Manager详解

    Android基础知识——Android SDK Manager详解   做Android开发时,免不了使用Android SDK Manager,安装需要的sdk版本.buildTools版本等等. ...

  8. mysql在插入或更新的时候对一个字段赋递增值

    在我们有一个需求是更新某个表里面的某个字段,让这个字段变成一个递增的值,或者插入某个表中使得某些字段的值是递增的.下面我们来看看具体的操作: 更改表字段为递增 首先设置一个变量,初始值为任意数值,这里 ...

  9. kail-linux下安装pycharm

    1.下载pycharm pycharm官网下载链接:https://www.jetbrains.com/pycharm/download/#section=linux 请注意下载对应系统的profes ...

  10. sudo 的介绍

    http://chenfage.blog.51cto.com/8804946/1830424