Android 6.0权限动态申请

从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。

系统权限分为两类:正常权限 和 危险权限:

正常权限不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。
危险权限会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。

以下为9组危险权限

权限组权限
CALENDAR
  • READ_CALENDAR
  • WRITE_CALENDAR
CAMERA
  • CAMERA
CONTACTS
  • READ_CONTACTS
  • WRITE_CONTACTS
  • GET_ACCOUNTS
LOCATION
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION
MICROPHONE
  • RECORD_AUDIO
PHONE
  • READ_PHONE_STATE
  • CALL_PHONE
  • READ_CALL_LOG
  • WRITE_CALL_LOG
  • ADD_VOICEMAIL
  • USE_SIP
  • PROCESS_OUTGOING_CALLS
SENSORS
  • BODY_SENSORS
SMS
  • SEND_SMS
  • RECEIVE_SMS
  • READ_SMS
  • RECEIVE_WAP_PUSH
  • RECEIVE_MMS
STORAGE
  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_STORAGE

在Android6.0之前,我们只需要通过下面的代码将这些权限写在Mainfest.xml文件即可。

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

而在Android6.0以上的系统版本中,如果只是在Mainfest.xml文件里面申请是会被默认拒绝该权限的。比如你没有申请拨打电话的权限,进行拨号操作,这个时候是会报异常的。

下面我们来看一下Android6.0运行时权限的申请,话不多说,直接上代码看注释。

package com.example.permissionsapply;

import android.Manifest;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class Main2Activity extends AppCompatActivity {

    public static final int request_Permissions_Request_Code = 88;
    private static final String TAG = "Main2Activity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        findViewById(R.id.btn2_call_phone).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                applyPermission();
            }
        });
    }

    /**
     * 申请权限
     */
    private void applyPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /**
             *  @see #requestPermissions(String[], int)
             *  第一个参数是需要申请的权限,需要请求几个权限就在数组里面添加几个
             *  第二个参数是请求回调的标示码,通过onRequestPermissionsResult(int requestCode, @NonNull
             *      String[] permissions, @NonNull int[] grantResults)的requestCode参数返回
             */
            requestPermissions(new String[]{Manifest.permission.CALL_PHONE,Manifest.permission.ACCESS_FINE_LOCATION},request_Permissions_Request_Code);
        }
    }

    /**
     * 当申请权限的时候回调该方法。(给用户弹出对话框提示用户是否通过权限,当用户点击拒绝或同意的时候就回调该方法。
     *                              如果用户已经 同意/拒绝 该权限则不会弹出对话框,这个时候会直接回调该方法。)
     * @param requestCode  通过 requestPermissions(String[], int)方法请求权限的时候传入的requestCode
     * @param permissions  请求的权限
     * @param grantResults  请求的权限所对应的返回结果,同意=0 拒绝=-1 参考{@link android.content.pm.PackageManager#PERMISSION_GRANTED}
     *                       和 {@link android.content.pm.PackageManager#PERMISSION_DENIED}.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        Log.i(TAG,"requestCode = " +requestCode);
        for (int i = 0; i < permissions.length; i++) {
            Log.i(TAG,"权限:" + permissions[i] + " ,grantResults = " +grantResults[i]);
        }

    }
}

当然,在Mainfest.xml里面还是需要加上下面的代码,否则是无法弹出权限申请对话框的,会直接回调onRequestPermissionsResult(…)方法,并返回拒绝的状态。

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

这里写图片描述

上面的方法就可以完成对权限的申请,如果我们的权限已经被同意,那么我们就没有必要每次都去申请了。所以在申请权限之前,我们做一下判断。

public class Main2Activity extends AppCompatActivity {

    public static final int request_Permissions_Request_Code = 88;
    private static final String TAG = "Main2Activity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        findViewById(R.id.btn2_call_phone).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //通过该方法检测某个权限是否被用户同意
                if (ActivityCompat.checkSelfPermission(Main2Activity.this, Manifest.permission.CALL_PHONE)
                        != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(Main2Activity.this,
                        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    applyPermission();
                    return ;
                }

            }
        });
    }

    /**
     * 申请权限
     */
    private void applyPermission() {
        ......
    }

经常看到群里有同学问怎么我返回的一直是0呢。事情是这样样子的,你肯定用的是6.0以下的系统,而且已经在mainfest文件里面已经申请权限了。如果你用的是6.0以上的系统,那你就是点击允许该权限了。

如果嫌上面Activity里面的代码写的多,没有关系,我们可以通过几行代码就可以完成上述操作。只是需要进行封装(网上找的封装,时间长了忘记作者了,所以在这里就没写作者)。

package com.example.permissionsapply;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.permissionsapply.permissions.PermissionResultAdapter;
import com.example.permissionsapply.permissions.PermissionUtil;

public class MainActivity extends AppCompatActivity {
    private final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_call_phone).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                applyCallPhonePermission();
            }
        });
    }

    /**
     * 申请拨打电话的权限
     */
    private void applyCallPhonePermission() {
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            //申请拨打电话的权限
            PermissionUtil.getInstance().request(this, new String[]{Manifest.permission.CALL_PHONE}, new PermissionResultAdapter() {
                @Override
                public void onPermissionGranted() {
                    callPhone("10086");
                    Log.d(TAG,"权限通过");
                }
            });
        } else {
            callPhone("10086");
        }
    }

    /**
     * 拨打电话
     */
    private void callPhone(String phone) {
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "请打开拨打电话权限", Toast.LENGTH_SHORT).show();
            return;
        }
        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone));
        MainActivity.this.startActivity(intent);
    }

}

是不是变的简单多了,封装的代码比较多,我就不再这里贴出来了。需要的朋友可以在下面的地址下载

Git地址: https://code.csdn.net/chengliang0315/permissionsapply.git
资源包 : http://download.csdn.net/detail/chengliang0315/9751451

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值