Android08--Android权限系统

标签: Android
更新时间:2017-12-17 15:12:37


undefined

声明需要的权限 #

有时候我们需要给APP添加相应的权限,如webview需要有访问网络的权限:

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

通讯录需要有访问联系人的权限:

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

自定义权限 #

使用permission标签自定义权限:

<permission android:name="com.a52fhy.learnpemission.permission.RECEIVE_MSG"></permission>

命名规则:包名 + .permission + .权限名大写

为代码添加权限检查 #

使用context.checkCallingOrSelfPermission()检查是否拥有某个权限,然后与常量PackageManager.PERMISSION_GRANTED进行比较,不匹配则提示没有权限。

下面是一个发送广播的示例,自定义了权限com.a52fhy.learnpemission.permission.RECEIVE_MSG,并在接收广播的时候进行判断:

MyReceiver.java

package com.a52fhy.learnpermission;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

    public final static String PERMISSION_RECEIVE_MSG = "com.a52fhy.learnpemission.permission.RECEIVE_MSG";

    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        int checkResult = context.checkCallingOrSelfPermission(PERMISSION_RECEIVE_MSG);
        if(checkResult != PackageManager.PERMISSION_GRANTED){
            //throw  new SecurityException("没有权限:" + PERMISSION_RECEIVE_MSG);
            Toast.makeText(context, "没有权限:" + PERMISSION_RECEIVE_MSG, Toast.LENGTH_LONG).show();
        }else{
            Log.i("MyReceiver", "接收到了消息!");
        }
    }
}

PackageManager.PERMISSION_GRANTED对应的值是0。其它常量:

public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;

我们运行APP,点击发送广播,会提示没有权限。

现在我们添加上这个权限:

<uses-permission android:name="com.a52fhy.learnpemission.permission.RECEIVE_MSG"></uses-permission>

运行就没有问题了。

为基本组件添加权限检查 #

我们可以为一个应用的某个Activity添加权限,这样其它app访问的时候需要申明权限,否则无法访问。但这个权限对于应用本身无效。

现在新建个Activity,名称是PermissionActivity。

自定义权限:

<permission android:name="com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY" />

activity标签里申明权限:

<activity
    android:name=".PermissionActivity"
    android:permission="com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT"></category>
        <action android:name="com.a52fhy.learnpemission.intent.action.PermissionActivity"></action>
    </intent-filter>
</activity>

以上通过android:permission申明了权限。

直接在该应用的MainActivity里打开PermissionActivity是无需权限的:

startActivity(new Intent("com.a52fhy.learnpemission.intent.action.PermissionActivity"));

我们新建个应用AnotherApp,添加个按钮打开另一个有权限的Activity,然后MainActivity里:

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        startActivity(new Intent("com.a52fhy.learnpemission.intent.action.PermissionActivity"));
    }
});

启动应用后点击按钮,发现崩溃了,log里提示没有访问权限:

 requires com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY

我们在新建应用AnotherApp的AndroidManifest.xml里添加权限:

<uses-permission android:name="com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY"></uses-permission>

再访问就可以了。

AndroidManifest.xml完整示例:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.a52fhy.learnpermission">

    <permission android:name="com.a52fhy.learnpemission.permission.RECEIVE_MSG" />
    <permission android:name="com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY" />

    <uses-permission android:name="com.a52fhy.learnpemission.permission.RECEIVE_MSG" />

    <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>

        <receiver
            android:name=".MyReceiver"
            android:enabled="true" />

        <activity
            android:name=".PermissionActivity"
            android:permission="com.a52fhy.learnpemission.permission.ACCESS_ACTIVITY">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"></category>
                <action android:name="com.a52fhy.learnpemission.intent.action.PermissionActivity"></action>
            </intent-filter>
        </activity>
    </application>

</manifest>

常见权限 #

ACCESS_NETWORK_STATE  网络状态权限    
ACCESS_WIFI_STATE  WIFI网络状态信息权限    
BATTERY_STATE  电池状态权限    
BLUETOOTH 连接匹配的蓝牙设备权限    
BLUETOOTH_ADMIN 发现匹配的蓝牙设备权限    
BROADCAST_SMS 广播收到短信提醒的权限    
CALL_PHONE 拨打电话的权限    
CAMERA 使用相机的权限    
CHANGE_NETWORK_STATE 改变网络状态权限    
CHANGE_WIFI_STATE 改变wifi网络状态权限    
DELETE_CACHE_FILES 允许删除缓存文件权限    
DELETE_PACKAGES 允许删除安装包的权限    
FLASHLIGHT 访问闪光灯的权限    
INTERNET 允许访问网络的权限    
MODIFY_AUDIO_SETTINGS 允许修改全局声音的权限    
PROCESS_OUTGOING_CALLS 允许监听、控制、取消呼出电话的权限    
READ_CONTACTS 允许读取电话薄的权限    
READ_HISTORY_BOOKMARKS 读取浏览器收藏夹和历史记录的权限    
READ_OWNER_DATA 允许读取用户数据的权限    
READ_PHONE_STATE 允许读取手机状态的权限   
READ_PHONE_SMS 允许读取短信息的权限    
REBOOT 允许重启系统的权限    
RECEIVE_MMS 允许处理、监控、接受彩信的权限    
RECEIVE_SMS 允许处理、监控、接受短信的权限    
RECORD_AUDIO 允许录音的权限    
SEND_SMS 允许发送短信的权限    
SET_ORIENTATION 设置屏幕方向权限    
SET_TIME 设置时间权限    
SET_TIME_ZONE 允许设置时区的权限    
SET_WALLPAPER 设置桌面壁纸权限    
VIBRATE 允许控制振动器的权限    
WRITE_CONTACTS 允许写用户联系人的权限    
WRITE_HISTORY_BOOKMARKS 允许应用程序写历史记录和书签的全新    
WRITE_OWNER_DATA 允许应用程序写用户数据的权限    
WRITE_SMS 允许写短信的权限    

运行时权限 #

运行时权限是Android6.0加入的新特性。

对于6.0以下的权限及在安装的时候,根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装,造成了我们想要使用某个app,就要默默忍受其一些不必要的权限(比如是个app都要访问通讯录、短信等)。而在6.0以后,我们可以直接安装,当app需要我们授予不恰当的权限的时候,我们可以予以拒绝(比如:单机的象棋对战,请求访问任何权限,我都是不同意的)。当然你也可以在设置界面对每个app的权限进行查看,以及对单个权限进行授权或者解除授权。

新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。

Build by Loppo 0.6.6