在 Android 中使用 checkSelfPermission?

Posted

技术标签:

【中文标题】在 Android 中使用 checkSelfPermission?【英文标题】:Use of the checkSelfPermission in Android? 【发布时间】:2018-02-28 06:40:28 【问题描述】:

我正在开发一个需要用户授予多个权限(位置、外部存储、相机和手机状态)的应用程序,如果我一个接一个地提出请求,则在运行时只向用户询问一个应用程序,这是一个问题:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
        //ask for the location permission
        ActivityCompat.requestPermissions(this, new String[]Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, 123);

    
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 
        //ask for the location permission
        ActivityCompat.requestPermissions(this,
                new String[]Manifest.permission.CAMERA, REQUEST_CAMERA);

    
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) 

        ActivityCompat.requestPermissions(this,
                PERMISSION_EXTERNAL, REQUEST_EXTERNAL_STORAGE);
    

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED)
    
        ActivityCompat.requestPermissions(this, new String[]Manifest.permission.READ_PHONE_STATE, REQUEST_PHONE_STATE);
    

有多个测试来创建一个包含所有权限请求的字符串非常烦人,我尝试只请求权限而不测试它们是否被 checkSelfPermision 方法授予:

ActivityCompat.requestPermissions(this,
            new String[]Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.READ_PHONE_STATE, REQUEST_MULTIPLE);

它可以工作,它一个接一个地堆叠所有不同的请求,如果我重新运行应用程序,它不会再次询问,因为已授予权限,如果我手动删除其中一个权限,应用程序只会询问对于我删除的那个。

那么,如果不使用 checkSelfPermission 测试一切都可以完美运行,那么这个方法有什么用呢?是否存在我错过或不知道的风险?

【问题讨论】:

阅读文档developer.android.com/training/permissions/requesting.html 那没用,文档说我们需要 checkpermission 才能知道它是否已被授予,但经过测试我发现 requestpermissions 已经自己做到了 你说的没用是什么意思 文档没有回答我的问题,这就是为什么我们可以不使用 checkPermission 以及在避免它时是否需要考虑什么 【参考方案1】:

@Waylan 这里有一两个非常有用的链接,我将发布一些代码来帮助您处理用户可以与他们选择的内容交互的三种方式中的哪一种。 即先拒绝允许和不再询问链接

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) 
            //.... write file into storage ...
            System.out.println("SDK > BuildVersion TRUE");
         else 
            requestPermissions(new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, 666);  // Comment 26
            System.out.println("go to requestPermissions");
        
    
    onLoad();


@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) 

        case 666: // Allowed was selected so Permission granted
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 

                Snackbar s = Snackbar.make(findViewById(android.R.id.content),"Permission Granted",Snackbar.LENGTH_LONG);
                View snackbarView = s.getView();
                TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
                textView.setTextColor(Color.RED);
                textView.setTextSize(18);
                textView.setMaxLines(6);
                s.show();

                // do your work here

             else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) 
                // User selected the Never Ask Again Option Change settings in app settings manually
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                alertDialogBuilder.setTitle("Change Permissions in Settings");
                alertDialogBuilder
                        .setMessage("" +
                                "\nClick SETTINGS to Manually Set\n"+"Permissions to use Database Storage")
                        .setCancelable(false)
                        .setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int id) 
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", getPackageName(), null);
                                intent.setData(uri);
                                startActivityForResult(intent, 1000);     // Comment 3.
                            
                        );

                AlertDialog alertDialog = alertDialogBuilder.create();
                alertDialog.show();

             else 
                    // User selected Deny Dialog to EXIT App ==> OR <== RETRY to have a second chance to Allow Permissions
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) 

                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                    alertDialogBuilder.setTitle("Second Chance");
                    alertDialogBuilder
                            .setMessage("Click RETRY to Set Permissions to Allow\n\n"+"Click EXIT to the Close App")
                            .setCancelable(false)
                            .setPositiveButton("RETRY", new DialogInterface.OnClickListener() 
                                public void onClick(DialogInterface dialog, int id) 
                                    //ActivityCompat.requestPermissions((Activity) context, new String[]Manifest.permission.READ_EXTERNAL_STORAGE, Integer.parseInt(WRITE_EXTERNAL_STORAGE));
                                    Intent i = new Intent(MainActivity.this,MainActivity.class);
                                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(i);
                                    
                            )
                            .setNegativeButton("EXIT", new DialogInterface.OnClickListener() 
                                public void onClick(DialogInterface dialog, int id) 
                                    finish();
                                    dialog.cancel();
                                
                            );
                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();
                
            
            break;
    ;

【讨论】:

以上是关于在 Android 中使用 checkSelfPermission?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android 应用程序中使用 OSM 地图。?有啥教程可以学习在android中使用OSM吗?

如何在Mac中使用Android SDK

在 Android 中使用 Intent 在活动中传递 android 位图数据

无法在 Android 中使用 Android Crop 图像裁剪库

Android:如何在 Android 中使用 tensorflow lite 扩展图像的维度

如何在android中使用WCF服务?