标签:开发者 verify 窗口 列表 请求 repo table extern layout
adb shell pm list permissions -d -g
C:\Users\Administrator>adb shell pm list permissions -d -g* daemon not running. starting it now at tcp:5037 ** daemon started successfully *Dangerous Permissions:group:com.google.android.gms.permission.CAR_INFORMATION 汽车资料permission:com.google.android.gms.permission.CAR_VENDOR_EXTENSION 供应商permission:com.google.android.gms.permission.CAR_MILEAGE 里程permission:com.google.android.gms.permission.CAR_FUEL 燃料group:android.permission-group.CONTACTS 联系人permission:android.permission.WRITE_CONTACTSpermission:android.permission.GET_ACCOUNTSpermission:android.permission.READ_CONTACTSgroup:android.permission-group.PHONE 手机permission:android.permission.READ_CALL_LOGpermission:android.permission.READ_PHONE_STATEpermission:android.permission.CALL_PHONEpermission:android.permission.WRITE_CALL_LOGpermission:android.permission.USE_SIPpermission:android.permission.PROCESS_OUTGOING_CALLSpermission:com.android.voicemail.permission.ADD_VOICEMAILgroup:com.kingroot.kinguser.permission-group.SUPERUSER 超级管理员group:android.permission-group.CALENDAR 日历permission:android.permission.READ_CALENDARpermission:android.permission.WRITE_CALENDARgroup:android.permission-group.CAMERA 相机permission:android.permission.CAMERAgroup:android.permission-group.SENSORS 传感器permission:android.permission.BODY_SENSORSgroup:android.permission-group.LOCATION 位置permission:android.permission.ACCESS_FINE_LOCATIONpermission:com.google.android.gms.permission.CAR_SPEEDpermission:android.permission.ACCESS_COARSE_LOCATIONgroup:android.permission-group.STORAGE 存储卡permission:android.permission.READ_EXTERNAL_STORAGEpermission:android.permission.WRITE_EXTERNAL_STORAGEgroup:com.sina.weibo.permission-grouppermission:com.sina.weibo.permission.USERgroup:android.permission-group.MICROPHONE 麦克风permission:android.permission.RECORD_AUDIOgroup:android.permission-group.SMS 短信permission:android.permission.READ_SMSpermission:android.permission.RECEIVE_WAP_PUSHpermission:android.permission.RECEIVE_MMSpermission:android.permission.RECEIVE_SMSpermission:android.permission.SEND_SMSpermission:android.permission.READ_CELL_BROADCASTSungrouped:未分组的permission:com.huawei.pushagent.permission.RICHMEDIA_PROVIDERpermission:com.huawei.contacts.permission.HW_NUMBER_MARKpermission:com.huawei.motion.permission.MOTION_EXpermission:com.huawei.contacts.permission.CHOOSE_SUBSCRIPTION
public class MainActivity extends ListActivity {private static final int REQUESTCODE = 20094;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);String[] array = {"在没有申请权限的情况下在SD卡创建文件会失败","完整的授权过程演示","演示PermissionsDispatcher",};setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));}@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {switch (position) {case 0:createFileWithoutRequestPermission(this);break;case 1:requestPermissionBeforeCreateFile();break;case 2:startActivity(new Intent(this, Activity1.class));break;}}/*** 如果将targetSdkVersion改为22或以下,可以成功创建文件* 相反,如果改为23或以上,则失败*/public static void createFileWithoutRequestPermission(Context context) {String fileName = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss", Locale.getDefault()).format(new Date());File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), fileName + ".txt");boolean createFile = false;try {createFile = file.createNewFile();//没有申请权限时就在SD卡创建文件会失败(当然,如果文件已经存在,返回值也是false)} catch (IOException e) {e.printStackTrace();} finally {Toast.makeText(context, "创建文件结果:" + createFile, Toast.LENGTH_SHORT).show();}}private void requestPermissionBeforeCreateFile() {//检查权限。结果:PERMISSION_GRANTED=0,有权限;PERMISSION_DENIED=-1,没有权限int state = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);Toast.makeText(this, "写SD卡权限状态:" + state, Toast.LENGTH_SHORT).show();if (state != PackageManager.PERMISSION_GRANTED) {// 没有权限,申请权限//是否应该显示请求权限的说明。//加这个提醒的好处在于:第一次申请权限时不需要麻烦用户,但如果用户拒绝过一次权限后我们再次申请时//可以提醒用户授予该权限的必要性,免得再次申请时用户勾选"不再提醒"并拒绝,导致下次申请权限直接失败//返回值的特点:第一次请求权限之前调用返回false(不应该提醒);如果用户拒绝了,则下次调用返回true(应该提醒)//如果之后再次请求权限时,用户拒绝了并选择了"不再提醒",则下次调用返回false(不应该提醒,且不弹授权对话框)boolean state2 = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);if (state2) {// 一般是通过弹一个自定义的对话框告诉用户,我们为什么需要这个权限new AlertDialog.Builder(this).setTitle("请求读写SD卡权限").setMessage("请求SD卡权限,作用是给你保存妹子图片").setPositiveButton("知道了", (dialog, which) -> ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUESTCODE)).create().show();} else {//请求用户授权几个权限,调用后系统会显示一个请求用户授权的提示对话框,开发者不能修改这个对话框ActivityCompat.requestPermissions(MainActivity.this,//api 23以后可以调用Activity的requestPermissions方法new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},//需要申请的权限数组REQUESTCODE);//请求码,会在回调onRequestPermissionsResult()时返回}} else {// 有权限了,去放肆吧。createFileWithoutRequestPermission(this);}}@Override//当用户处理完授权操作时,会回调Activity或Fragment的此方法,参数为:权限数组、授权结果数组public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (grantResults.length > 0) {switch (requestCode) {case REQUESTCODE: {if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {createFileWithoutRequestPermission(this);} else {Toast.makeText(this, "你拒绝了权限,我们已经没法愉快的玩耍了,我将在3秒后关闭!", Toast.LENGTH_SHORT).show();new Handler().postDelayed(this::finish, 3 * 1000);}}}}}}
compile ‘com.github.hotchemi:permissionsdispatcher:2.4.0‘annotationProcessor ‘com.github.hotchemi:permissionsdispatcher-processor:2.4.0‘
allprojects {repositories {jcenter()mavenCentral()//或 maven { url ‘http://oss.jfrog.org/artifactory/oss-snapshot-local/‘ }}}
targetSdkVersion 25
| Annotation | Required | Description |
| @RuntimePermissions | ? | 注解在其内部需要使用运行时权限的Activity或Fragment上 |
| @NeedsPermission | ? | 注解在需要调用运行时权限的方法上,当用户给予权限时会执行该方法 |
| @OnShowRationale | 注解在用于向用户解释为什么需要调用该权限的方法上:第一次请求权限之前调用返回false;如果用户拒绝了,则下次调用返回true;如果之后再次请求权限时,用户拒绝了并选择了"不再提醒",则下次调用返回false。 | |
| @OnPermissionDenied | 注解在当用户拒绝了权限请求时需要调用的方法上 | |
| @OnNeverAskAgain | 注解在当用户选中了授权窗口中的不再询问复选框后并拒绝了权限请求时需要调用的方法,一般可以向用户解释为何申请此权限,并根据实际需求决定是否再次弹出权限请求对话框 |
Activity1PermissionsDispatcher.createFileWithCheck(Activity1.this)
Activity1PermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
@RuntimePermissionspublic class Activity1 extends Activity {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView tv = new TextView(this);setContentView(tv);tv.setBackgroundColor(Color.YELLOW);tv.setOnClickListener(v -> Activity1PermissionsDispatcher.createFileWithCheck(Activity1.this));}@NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)void createFile() {Toast.makeText(this, "【NeedsPermission,用户允许了该权限】", Toast.LENGTH_SHORT).show();MainActivity.createFileWithoutRequestPermission(Activity1.this);}@OnPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE)void doOnPermissionDenied() {Toast.makeText(this, "【OnPermissionDenied,用户拒绝了该权限】", Toast.LENGTH_SHORT).show();}@OnShowRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)void doOnShowRationale(final PermissionRequest request) {Toast.makeText(this, "【OnShowRationale,此时应该显示请求权限的说明】", Toast.LENGTH_SHORT).show();// 一般是通过弹一个自定义的对话框告诉用户,我们为什么需要这个权限new AlertDialog.Builder(this).setTitle("请求读写SD卡权限").setMessage("请求SD卡权限,这样我才能给你保存妹子图片哦").setPositiveButton("我知道了", (dialog, which) -> request.proceed()).setNegativeButton("我不需要", (dialog, which) -> request.cancel()).create().show();}@OnNeverAskAgain(Manifest.permission.WRITE_EXTERNAL_STORAGE)void doOnNeverAskAgain() {Toast.makeText(this, "你拒绝了读写SD卡权限并选择了\"不再提醒\"," +"\n已经没法愉快的玩耍了,我将在3秒后关闭!", Toast.LENGTH_SHORT).show();new Handler().postDelayed(this::finish, 3 * 1000);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);Activity1PermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);}}
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package permission.bqt.com.permissiontest;import android.support.v4.app.ActivityCompat;import java.lang.ref.WeakReference;import permission.bqt.com.permissiontest.Activity1;import permissions.dispatcher.PermissionRequest;import permissions.dispatcher.PermissionUtils;final class Activity1PermissionsDispatcher {private static final int REQUEST_CREATEFILE = 0;private static final String[] PERMISSION_CREATEFILE = new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"};private Activity1PermissionsDispatcher() {}static void createFileWithCheck(Activity1 target) {if(PermissionUtils.hasSelfPermissions(target, PERMISSION_CREATEFILE)) {target.createFile();} else if(PermissionUtils.shouldShowRequestPermissionRationale(target, PERMISSION_CREATEFILE)) {target.doOnShowRationale(new Activity1PermissionsDispatcher.CreateFilePermissionRequest(target));} else {ActivityCompat.requestPermissions(target, PERMISSION_CREATEFILE, 0);}}static void onRequestPermissionsResult(Activity1 target, int requestCode, int[] grantResults) {switch(requestCode) {case 0:if(PermissionUtils.verifyPermissions(grantResults)) {target.createFile();} else if(!PermissionUtils.shouldShowRequestPermissionRationale(target, PERMISSION_CREATEFILE)) {target.doOnNeverAskAgain();} else {target.doOnPermissionDenied();}default:}}private static final class CreateFilePermissionRequest implements PermissionRequest {private final WeakReference<Activity1> weakTarget;private CreateFilePermissionRequest(Activity1 target) {this.weakTarget = new WeakReference(target);}public void proceed() {Activity1 target = (Activity1)this.weakTarget.get();if(target != null) {ActivityCompat.requestPermissions(target, Activity1PermissionsDispatcher.PERMISSION_CREATEFILE, 0);}}public void cancel() {Activity1 target = (Activity1)this.weakTarget.get();if(target != null) {target.doOnPermissionDenied();}}}}
标签:开发者 verify 窗口 列表 请求 repo table extern layout
原文地址:http://www.cnblogs.com/baiqiantao/p/7115892.html