Android(安卓)动态申请权限
Android 动态申请权限
本文转自:https://blog.csdn.net/losingcarryjie/article/details/80889154,https://blog.csdn.net/htwhtw123/article/details/76032997,有个人轻微修改,请点击链接查看原文,尊重楼主版权。
应用宝,新浪微博,高德地图,等App,请求的方式也都是第一次打开就开始申请全部权限,用户一次性点个够。
这种做法不能说是流氓,因为比如高德地图最重要的就是获取地理位置功能,你直接关掉了这个权限自然App就无法正常使用了,强制你同意无可厚非;其次是每个页面都做权限处理真的太恶心了,程序员也不愿意干;再其次作为一个用户,我希望App能一次性把要的权限都让我批准一下,不要点一个页面弹出一个框,难受,我想享受酣畅淋漓的体验。
说了那么多,接下来进入正文,先看下高德地图的权限处理逻辑
再次亮出我的观点
如果必须的权限就必须要用户授予,如果不必须的权限就不要申请。
高德这个逻辑就是如此
下面看实现
代码:
清单文件中添加
MainActivity:
package com.collas.permission;import android.Manifest;import android.app.Dialog;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.provider.Settings;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.widget.Toast;import com.collas.R;import static android.content.pm.PackageManager.PERMISSION_GRANTED;public class PermissionActivity extends AppCompatActivity { private static final int NOT_NOTICE = 2;//如果勾选了不再询问 private AlertDialog alertDialog; private AlertDialog mDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_permission); myRequetPermission(); } private void myRequetPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); }else { Toast.makeText(this,"您已经申请了权限!",Toast.LENGTH_SHORT).show(); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1) { for (int i = 0; i < permissions.length; i++) { if (grantResults[i] == PERMISSION_GRANTED) {//选择了“始终允许” Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show(); } else { if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){//用户选择了禁止不再询问 AlertDialog.Builder builder = new AlertDialog.Builder(PermissionActivity.this); builder.setTitle("permission") .setMessage("点击允许才可以使用我们的app哦") .setPositiveButton("去允许", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null);//注意就是"package",不用改成自己的包名 intent.setData(uri); startActivityForResult(intent, NOT_NOTICE); } }); mDialog = builder.create(); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); }else {//选择禁止 AlertDialog.Builder builder = new AlertDialog.Builder(PermissionActivity.this); builder.setTitle("permission") .setMessage("点击允许才可以使用我们的app哦") .setPositiveButton("去允许", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { if (alertDialog != null && alertDialog.isShowing()) { alertDialog.dismiss(); } ActivityCompat.requestPermissions(PermissionActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } }); alertDialog = builder.create(); alertDialog.setCanceledOnTouchOutside(false); alertDialog.show(); } } } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==NOT_NOTICE){ myRequetPermission();//由于不知道是否选择了允许所以需要再次判断 } }}
补充:
1.Android所有权限:
- 需要用户手动赋予的权限( Dangerous Permissions)
所属权限组 | 权限 |
---|---|
日历 | READ_CALENDAR |
日历 | WRITE_CALENDAR |
相机 | CAMERA |
联系人 | READ_CONTACTS |
联系人 | WRITE_CONTACTS |
联系人 | GET_ACCOUNTS |
位置 | ACCESS_FINE_LOCATION |
位置 | ACCESS_COARSE_LOCATION |
麦克风 | RECORD_AUDIO |
电话 | READ_PHONE_STATE |
电话 | CALL_PHONE |
电话 | READ_CALL_LOG |
电话 | WRITE_CALL_LOG |
电话 | ADD_VOICEMAIL |
电话 | USE_SIP |
电话 | PROCESS_OUTGOING_CALLS |
传感器 | BODY_SENSORS |
短信 | SEND_SMS |
短信 | RECEIVE_SMS |
短信 | READ_SMS |
短信 | RECEIVE_WAP_PUSH |
短信 | RECEIVE_MMS |
存储 | READ_EXTERNAL_STORAGE |
存储 | WRITE_EXTERNAL_STORAGE |
注意:如果应用程序请求在AndroidManifest中列出的危险权限,并且应用程序已经在同一权限组中具有另一个危险权限,系统会立即授予权限,而不会与用户进行任何交互,。例如,如果一个应用程序先前已经请求并被授予READ_CONTACTS权限,然后它请求WRITE_CONTACTS(同属于联系人一组),系统会立即授予该权限,不会再弹出权限授予询问的对话框。
2.动态申请权限的方法:
首先,需要在AndroidManifest.xml静态申请权限,否则无法动态申请权限,以下代码位置不能放错(在application之外):
然后,在java代码中写动态申请权限的逻辑(这是官网的写法)
public void requestPower() {//判断是否已经赋予权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.上表权限字符) != PackageManager.PERMISSION_GRANTED) { //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.上表权限字符)) {//这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false } else { //申请权限,字符串数组内是一个或多个要申请的权限,1是申请权限结果的返回参数,在onRequestPermissionsResult可以得知申请结果 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.上表权限字符,}, 1); } }}
MainActivity中:
判断当前是否已经有某个权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
请求一个权限:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
用户操作后的回调:
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);// ...}
更多相关文章
- Android动态获取权限,多组权限
- Android之动态申请存储权限
- 录音权限(Android(安卓)8.0)
- 用户界面View之ImageView控件
- Android_MediaPlayer:java.io.IOException: setDataSource failed
- Android开发者文档笔记(一)
- android 中如何在androidmanifest.xml设置权限请求
- android SDK/APP 涉及用户隐私需要关注的点
- Android的跨进程通信