Android定义了一种权限方案来保护设备上的资源和功能。例如,在默认情况下,应用程序无法访问联系人列表、拨打电话等。下面就以拨打电话为例介绍一下系统对权限的要求。一般在我们的应用中,如果要用到拨打电话的功能,我们会这样编码:

  1. Uri uri = Uri.parse("tel:12345678");
  2. Intent intent = new Intent(Intent.ACTION_CALL, uri);
  3. startActivity(intent);

默认情况下,我们无权访问拨打电话的Activity,控制台将会报以下异常信息:

  1. ERROR/AndroidRuntime: java.lang.SecurityException: Permission Denial:
  2. starting Intent { act=android.intent.action.CALL dat=tel:12345678 cmp=com.android.phone/.OutgoingCallBroadcaster }
  3. ......
  4. requires android.permission.CALL_PHONE

看来,我们是缺少了CALL_PHONE这个权限,这个权限是Android系统自带的phone应用里定义的权限:

  1. ......
  2. <uses-permission android:name="android.permission.CALL_PHONE" />
  3. ......
  4. <activity android:name="OutgoingCallBroadcaster"
  5. android:permission="android.permission.CALL_PHONE"
  6. android:theme="@android:style/Theme.NoDisplay"
  7. android:configChanges="orientation|keyboardHidden">
  8. <!-- CALL action intent filters, for the various ways
  9. of initiating an outgoing call. -->
  10. <intent-filter>
  11. <action android:name="android.intent.action.CALL" />
  12. <category android:name="android.intent.category.DEFAULT" />
  13. <data android:scheme="tel" />
  14. </intent-filter>
  15. <intent-filter>
  16. <action android:name="android.intent.action.CALL" />
  17. <category android:name="android.intent.category.DEFAULT" />
  18. <data android:scheme="voicemail" />
  19. </intent-filter>
  20. <intent-filter>
  21. <action android:name="android.intent.action.CALL" />
  22. <category android:name="android.intent.category.DEFAULT" />
  23. <data android:mimeType="vnd.android.cursor.item/phone" />
  24. <data android:mimeType="vnd.android.cursor.item/phone_v2" />
  25. <data android:mimeType="vnd.android.cursor.item/person" />
  26. </intent-filter>
  27. </activity>
  28. ......

想要使用此功能,必须在我们的AndroidManifest.xml文件中声明使用此权限:

  1. <application ...>
  2. ...
  3. </application>
  4. <uses-permission android:name="android.permission.CALL_PHONE"/>

这告诉系统,我们的应用使用了此权限,我们有权访问拨打电话的Activity。

我们不仅要问,为什么系统会这样设计呢?答案是为了保护用户资源的安全。要想使用此功能,必须在应用中声明权限信息,这样一来,在用户安装此应用时系统会从应用中提取出权限信息,告诉用户该应用使用到了哪些功能,由用户判断该应用是否损害自己的安全。

接下来由我来演示一下权限的定义和使用,我们建立一个phone项目,项目结构如下:

我们设计的流程是在MainActivity中点击按钮,然后跳转到PhoneActivity中,我们会为PhoneActiivty定义相应的权限。

我们先看一下MainActivity和PhoneActivity的代码:

MainActivity.java如下:

  1. package com.scott.phone;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. public class MainActivity extends Activity {
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.main);
  12. Button btn = (Button) findViewById(R.id.btn);
  13. btn.setOnClickListener(new View.OnClickListener() {
  14. @Override
  15. public void onClick(View v) {
  16. startActivity(new Intent(MainActivity.this, PhoneActivity.class));
  17. }
  18. });
  19. }
  20. }

PhoneActivity.java如下:

  1. package com.scott.phone;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.widget.TextView;
  5. public class PhoneActivity extends Activity {
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. TextView tv = new TextView(this);
  10. tv.setText("Yes! It works.");
  11. setContentView(tv);
  12. }
  13. }

最重要的是AndroidManifest.xml文件,我们所有的权限声明配置都在此文件中完成:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.scott.phone"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <!-- 声明一个权限  -->
  7. <permission android:protectionLevel="normal"
  8. android:name="scott.permission.MY_CALL_PHONE"/>
  9. <application android:icon="@drawable/icon" android:label="@string/app_name">
  10. <activity android:name=".MainActivity"
  11. android:label="@string/app_name">
  12. <intent-filter>
  13. <action android:name="android.intent.action.MAIN" />
  14. <category android:name="android.intent.category.LAUNCHER" />
  15. </intent-filter>
  16. </activity>
  17. <!-- 为Activity应用已定义的权限 -->
  18. <activity android:name=".PhoneActivity"
  19. android:permission="scott.permission.MY_CALL_PHONE">
  20. <intent-filter>
  21. <!-- 注意这个action 在其他应用中可使用此action访问此Activity -->
  22. <action android:name="scott.intent.action.MY_CALL"/>
  23. <category android:name="android.intent.category.DEFAULT" />
  24. </intent-filter>
  25. </activity>
  26. </application>
  27. <!-- 在同一应用中访问PhoneActivity也需要加上权限 -->
  28. <uses-permission android:name="scott.permission.MY_CALL_PHONE"/>
  29. <uses-sdk android:minSdkVersion="8" />
  30. </manifest>

需要注意的是,在声明权限时需要一个android:protectionLevel的属性,它代表“风险级别”。必须是以下值之一:

normal、dangerous、signature、signatureOrSystem。

normal表示权限是低风险的,不会对系统、用户或其他应用程序造成危害。

dangerous表示权限是高风险的,系统将可能要求用户输入相关信息,才会授予此权限。

signature告诉Android,只有当应用程序所用数字签名与声明此权限的应用程序所有数字签名相同时,才能将权限授给它。

signatureOrSystem告诉Android,将权限授给具有相同数字签名的应用程序或Android包类,这一级别适用于非常特殊的情况,比如多个供应商需要通过系统影像共享功能时。

另外一个是android:permissionGroup属性,表示一个权限组。可以将权限放在一个组中,但对于自定义权限,应该避免设置此属性。如果确实希望设置此属性,可以使用以下属性代替:android.permission-group.SYSTEM_TOOLS。

下面是两个活动的截图:

以上过程都是在一个内部完成的,现在假如我们的这个phone应用作为系统内置的应用,做为开发者,我们新建一个app,然后访问phone应用里的PhoneActivity。app的结构图如下:

我们在MainActivity里放置一个按钮,点击之后跳转到phone应用的PhoneActivity中。MainActivity.java代码如下:

  1. package com.scott.app;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. public class MainActivity extends Activity {
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.main);
  12. Button btn = (Button) findViewById(R.id.btn);
  13. btn.setOnClickListener(new View.OnClickListener() {
  14. @Override
  15. public void onClick(View v) {
  16. Intent intent = new Intent("scott.intent.action.MY_CALL");
  17. startActivity(intent);
  18. }
  19. });
  20. }
  21. }

然后我们需要在AndroidManifest.xml文件中配置相应的权限:

  1. <application ...>
  2. ...
  3. </application>
  4. <uses-permission android:name="scott.permission.MY_CALL_PHONE"/>

点击按钮,就可以顺利地跳转到PhoneActivity了。截图如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android声明和使用权限的更多相关文章

  1. Android 开发技巧 - Android 6.0 以上权限大坑和权限检查基类封装

    简单介绍 关于运行时权限的说法,早在Google发布android 6.0的时候,大家也听得蛮多的.从用户的角度来讲,用户是受益方,更好的保护用户的意思,而对于开发者来说,无疑增加了工作量. 对于6. ...

  2. Delphi编写的Android程序获取Root权限实现(2015.4.15更新,支持Android 4.4)

    借助谷歌,并经过本大侠施展坑.蒙.拐.骗.偷五大绝技,终于成功实现在Delphi下获取Root权限并将其扩展为一个完整功能更加完整的TQAndroidShell记录,在华为荣耀2(Android 4. ...

  3. Android开发之深入理解Android 7.0系统权限更改相关文档

    http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...

  4. Android : 添加apk私有权限

    一.Android的系统权限: apk在安装时,Android 为每个软件包提供唯一的 Linux 用户 ID.此 ID 在软件包在该设备上的使用寿命期间保持不变.在不同设备上,相同软件包可能有不同的 ...

  5. Android 6.0 动态权限申请

    1. 概述 Android 6.0 (API 23) 之前应用的权限在安装时全部授予,运行时应用不再需要询问用户.在 Android 6.0 或更高版本对权限进行了分类,对某些涉及到用户隐私的权限可在 ...

  6. Android适配API23之后权限的动态申请

    一.权限介绍 对于6.0以下的权限及在安装的时候,根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装,造成了我们想要使用某个app,就要默默忍受其一些不必要的权限(比如是个app都要 ...

  7. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  8. 【转】Android M(6.0) 权限爬坑之旅

    原文网址:https://yanlu.me/android-m6-0-permission-chasm/ 有一篇全面介绍Android M 运行时权限文章写的非常全面:Android M 新的运行时权 ...

  9. android中获取root权限的方法以及原理(转)

    一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. 二. Root 的介绍 1. Root 的目的 可以让我们拥有 ...

随机推荐

  1. 企业生产环境中linux系统分区的几种方案

    方案1:针对网站集群架构中的某个节点服务器分区 该服务器上的数据有多份(其他节点也有)且数据不太重要,建议分区方案如下: /boot: 200MB swap: 物理内存的1.5倍,当内存大于或等于8G ...

  2. Hive集成HBase详解

    摘要 Hive提供了与HBase的集成,使得能够在HBase表上使用HQL语句进行查询 插入操作以及进行Join和Union等复杂查询   应用场景 1. 将ETL操作的数据存入HBase 2. HB ...

  3. [原创作品]手把手教你怎么写jQuery插件

    这次随笔,向大家介绍如何编写jQuery插件.啰嗦一下,很希望各位IT界的‘攻城狮’们能和大家一起分享,一起成长.点击左边我头像下边的“加入qq群”,一起分享,一起交流,当然,可以一起吹水.哈,不废话 ...

  4. mysql 1449 : The user specified as a definer (&#39;root&#39;@&#39;%&#39;) does not exist 解决方法

    权限问题,授权 给 root  全部sql 权限 mysql> grant all privileges on *.* to root@"%" identified by & ...

  5. Fragment的简单使用

    最近一直有点忙,刚刚看到一个朋友的留言提到Fragment中加载ListView的问题,这里写了一个非常简单的测试,至于对Fragment的增.删.改实现动态布局构建灵活的UI,以后有时间在讨论: M ...

  6. Hibernate入门之关系篇:多对一和一对多映射

    关联关系映射,是对象映射关系中相对复杂的一种,但也是用处最多的一种,因为数据中的表不可能都是单独存在,彼此之间必定存在千丝万缕的联系,这也是关系型数据库的特征所在.同样关联关系的映射,也是对象关系映射 ...

  7. hdu 3917 最大重量封闭图

    /*最大重量封闭图: 意甲冠军:一些城市要建路需要负责一些公司,每家公司都需要缴纳个税.该公司将需要花费每路,另一个限制条件,如果那家公司a既定a-b.公司b既定b-c然后选择 公司a 你必须选择一个 ...

  8. ListVeiw新增记录及 滚动条移动到指定位置

    C# 自带的ListView控件的滚动条移动到指定位置. lvwList为ListView控件 lvwList.EnsureVisible(lvwList.Items.Count - 1); 新增记录 ...

  9. (转)SQL Server2005 异常处理机制(Begin try Begin Catch)

    begin try --SQL  end trybegin catch --sql (处理出错动作) end catch我们将可能会出错的sql 写在begin try...end try 之间,若出 ...

  10. 今天上传公司服务器出现的.net framework版本错误问题

    今天做好一个网站(.net4.0),里面有静态页面也有aspx页面,发布后,满心欢喜的上传到服务器,运行后,静态页没有问题,可是通过导航栏一旦点击进入aspx页面,就会出现错误 ,提示web.conf ...