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);// ...}

更多相关文章

  1. Android动态获取权限,多组权限
  2. Android之动态申请存储权限
  3. 录音权限(Android(安卓)8.0)
  4. 用户界面View之ImageView控件
  5. Android_MediaPlayer:java.io.IOException: setDataSource failed
  6. Android开发者文档笔记(一)
  7. android 中如何在androidmanifest.xml设置权限请求
  8. android SDK/APP 涉及用户隐私需要关注的点
  9. Android的跨进程通信

随机推荐

  1. Android(安卓)动态设置控件高度
  2. Android(安卓)Studio 使用技巧(2)
  3. Android(安卓)应用程序主动请求Vsync
  4. android 震动
  5. Android的GridView控件点击图片变暗效果
  6. Android菜鸟笔记-获取设备信息
  7. Android应用程序线程消息循环模型分析(4)
  8. java.lang.ClassCastException: android.
  9. android中SOAP的anytype问题
  10. Android(安卓)图片资源的异步加载2