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

  • 用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. rhel7 ifconfig command not found

    同事扔过来一个rhel7.2的系统,登录后发现没有安装ifconfig命令: # ifconfig -bash: ifconfig: command not found 先看看环境变量: # echo ...

  2. Android基础之——CountDownTimer类,轻松实现倒计时功能

    在发现这个类之前,一直是用的handler,子线程发消息,UI线程进行倒计时的显示工作.前几天在做一个倒计时显示的时候发现了这个类,用起来非常方便 翻看了下源代码.内部已经帮我们实现了handler的 ...

  3. python selenium 常见问题列表

    python selenium webdriver 常见问题FAQ 另一个FAQ: https://code.google.com/p/selenium/wiki/FrequentlyAskedQue ...

  4. Android基本功:异步任务(AsyncTask)

    一.解决新线程无法更新UI组建问题的方案 为了解决新线程不能更新UI组建的问题,Andorid提供了如下几种解决方案: 使用Handler实现线程之间的通信. Activity.runOnUiThre ...

  5. Java Date and Calendar examples

    Java Date and Calendar examples This tutorial shows you how to work with java.util.Date and java.uti ...

  6. springboot 中使用Druid 数据源提供数据库监控

    一.springboot 中注册 Servlet/Filter/Listener 的方式有两种,1 通过代码注册 ServletRegistrationBean. FilterRegistration ...

  7. java和js实现电话号码部分隐藏

    有时候我们不需要将电话号码全部展现在页面上,那么我们可能要对电话号码进行相应的处理,js代码如下: alert("13456789012".replace(/(\d{3})(\d{ ...

  8. logstash匹配多行日志

    在工作中,遇到一个问题就是日志的处理,首选的方案就是ELFK(filebeat+logstash+es+kibana) 因为之前使用过logstash采集日志的时候,非常的消耗系统的资源,所以这里我选 ...

  9. [nginx]盗链和防盗链场景模拟实现

    盗链环境模拟 http://www.daolian.com/index.html 这个页面盗用http://www.maotai.com/qq.jpg这个站点页面的图. <!doctype ht ...

  10. 菜鸟学Java(九)——Servlet的基本配置

    学习JavaWeb的人没有不知道Servlet的吧,而要用Servlet就需要在web.xml中进行配置.相信有很多初学者跟我当初一样,对于一些配置参数不是很理解,今天就说说Servlet最基本的配置 ...