如何检查片段中的权限

How to check permission in fragment

我想检查片段中的权限。

我的代码:

        // Here, thisActivity is the current activity
        if (ContextCompat.checkSelfPermission(getActivity(),
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {


            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                    android.Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

            } else {

                // No explanation needed, we can request the permission.

                ActivityCompat.requestPermissions(getActivity(),
                        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                        1);



                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }

onRequestPermissionsResult 未在允许或拒绝后调用。

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            Log.e("test","0");
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                //yes

                Log.e("test","1");

                Intent intent = new Intent(getActivity(), MapsActivity.class);
                intent.putExtra("latitude", 35.694828);
                intent.putExtra("longitude", 51.378129);
                startActivity(intent);

            } else {
                utilityFunctions.showSweetAlertWarning(getActivity(),r.getString(R.string.str_warning_title_empty),
                        r.getString(R.string.str_you_must_allow_this_permission_toast),
                        r.getString(R.string.str_warning_btn_login));

                Log.e("test","2");
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

如果您从设置中关闭了您的应用程序权限,您将无法通过代码或您的 android 版本低于 Marshmallow 打开您的权限。

你可以查看这个文档 https://developer.android.com/training/permissions/requesting.html 这是一个例子 https://www.learn2crack.com/2015/10/android-marshmallow-permissions.html

我已完成以下操作以检查片段中的权限。

if (ActivityCompat.checkSelfPermission(getContext(),
            android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getContext(),
                    android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
         requestPermissions(getActivity(),
                new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION,
                        android.Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_LOCATION);
    } else {
        Log.e("DB", "PERMISSION GRANTED");
    }

更新

由于 Fragment.requestPermissions 现在是 deprecated,Google 建议改用 registerForActivityResult

我已经完成了这样的请求:

val permissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        // Do if the permission is granted
    }
    else {
        // Do otherwise
    }
}

permissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)

有关此方法的更多文档,您可以查看 this link

onRequestPermissionsResult 在 activity 而不是片段中被调用。尝试覆盖 activity 中的 onRequestPermissionsResult

片段有requestPermissions()onRequestPermissionsResult()方法,使用它。

但是 checkSelfPermission() 来自 ActivityCompat(不需要 Activity,只需要 Context)。

if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions( //Method of Fragment
        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
        REQUEST_PERMISSIONS_CODE_WRITE_STORAGE
    );
} else {
    downloadImage();
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_PERMISSIONS_CODE_WRITE_STORAGE) {
        if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            proceedWithSdCard();
        }
    }
}

我就是这样做的,对我有用。谢谢!

对于Activity:

ActivityCompat.requestPermissions(this, permissionsList, REQUEST_CODE);

片段:

requestPermissions(permissionsList, REQUEST_CODE);

使用 Kotlin,您调用 requestPermissions(arrayOf(Manifest.permission.THE_PERMISSION_CODE_YOU_WANT), PERMISSION_REQUEST_CODE) 并将以下覆盖添加到您的片段

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out kotlin.String>, grantResults: IntArray): Unit {

}

对我有用的是在 activity 中调用 onRequestPermissionsResult 方法,其中 fragment 是实现的,而不是在片段本身中调用它。 片段中的 onCreateView 方法内部:

    Button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int permissionCheck = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);

            if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_MEDIA);
            }else{
                //Do your work
                fetchMethod();
            }

        }
});

在帮助实现片段的Activity中,在onCreate方法之外:

    @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_MEDIA:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                fetchMethod();

            }else{
                Toast.makeText(getApplicationContext(), "Permission not granted!", Toast.LENGTH_SHORT).show();
            }
            break;

        default:
            break;
    }
}

要在 Fragment 调用 requestPermissions 方法中处理权限。如果您在包含该片段的片段和 activity 中覆盖 onRequestPermissionsResult 方法,请确保在 activity 方法中调用 super.onRequestPermissionsResult(...) 以传播对 onRequestPermissionsResult 的调用片段中的方法。

我在 Fragment 中使用 checkSelfPermission() 时被绊倒了,想知道什么是 Context 为空的最佳方法(特定于 Kotlin)...我应该使用 !! 其他

我根据 code I found in iosched 选择了 其他 。看看下面的示例,请记住,在 Fragment 附加到 Activity 之前,Context 将为空。

private fun fineLocationPermissionApproved(): Boolean {

    val context = context ?: return false

    return PackageManager.PERMISSION_GRANTED == checkSelfPermission(
        context,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
}

从 Fragment 检查权限(2021 年的方式)

片段中的 registerForActivityResult() 方法现已弃用。弃用消息建议使用 registerForActivityResult。因此,经过反复试验,这是 2021 年的方式:

假设您的片段名称是 AwesomeFragment。然后在构造函数中(准确地说是在片段的 onCreate 方法之前),初始化 ActivityResultLauncher<String[]> activityResultLauncher.

java版本

private ActivityResultLauncher<String[]> activityResultLauncher; 

public AwrsomeFragment() {
 activityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
            public void onActivityResult(Map<String, Boolean> result) {
                Log.e("activityResultLauncher", ""+result.toString());
                Boolean areAllGranted = true;
                for(Boolean b : result.values()) {
                    areAllGranted = areAllGranted && b;
                }

                if(areAllGranted) {
                    capturePhoto();
                }
            }
        });
}

然后也许在点击某个按钮时,您调用 launch 方法:

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        String[] appPerms;
        appPerms = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
        this.cameraClick.setOnClickListener(v -> {
            this.activityResultLauncher.launch(appPerms);
        });
    }

kotlin 版本

private var activityResultLauncher: ActivityResultLauncher<Array<String>>
init{
this.activityResultLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()) {result ->
        var allAreGranted = true
        for(b in result.values) {
            allAreGranted = allAreGranted && b
        }
        
        if(allAreGranted) {
          capturePhoto()            
        }
    }
}

// --- ---
 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
// ... ... init views / binding... ...
   someBtn.setOnClickListener{
        val appPerms = arrayOf(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA
        )
        activityResultLauncher.launch(appPerms)
  }       
}

为了检查片段中的权限,我执行了以下操作。

在Fragment的onCreateView之前添加如下内容,

private final int STORAGE_PERMISSION_CODE = 1;

private Activity mActivity;
 
 @Override
    public void onAttach(@NotNull Context context) {
        super.onAttach(context);
        mActivity = (Activity) context;
    }

检查权限,

if ((ContextCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
            {
                if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    new AlertDialog.Builder(mActivity)
                            .setTitle("Permission needed")
                            .setMessage("Allow "+getResources().getString(R.string.app_name)+" to access your storage?")
                            .setPositiveButton("ok", (dialog, which) -> ActivityCompat.requestPermissions(mActivity,
                                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE)
                            )
                            .setNegativeButton("cancel", (dialog, which) -> {
                                dialog.dismiss();
                                Toast.makeText(mActivity, "Please allow this permission!", Toast.LENGTH_SHORT).show();
                            })
                            .create().show();
                } else {
                    ActivityCompat.requestPermissions(mActivity,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
                }
            }

在 MainActivity 中放置以下代码,以便在用户永远拒绝权限的情况下从应用程序的设置中启用权限。

@Override
            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
            {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                if (requestCode == STORAGE_PERMISSION_CODE) {
        
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        Toast.makeText(this, "Permission GRANTED", Toast.LENGTH_SHORT).show();
                    } else {
        
                        //Now further we check if used denied permanently or not
                        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                            // 1. The user has temporarily denied permission.
                            Toast.makeText(MainActivity.this, "Permission DENIED", Toast.LENGTH_SHORT).show();
        
                        } else {
                            // 2. Permission has been denied.
                            // From here, you can access the setting's page.
        
                            new AlertDialog.Builder(MainActivity.this)
                                    .setTitle("Permission Required")
                                    .setMessage("This permission was already declined by you. Please open settings, go to \"Permissions\", and allow the permission.")
                                    .setPositiveButton("Settings", (dialog, which) -> {
                                        final Intent i = new Intent();
                                        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                        i.addCategory(Intent.CATEGORY_DEFAULT);
                                        i.setData(Uri.parse("package:" + MainActivity.this.getPackageName()));
                                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                                        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                                        MainActivity.this.startActivity(i);
                                    })
                                    .setNegativeButton("cancel", (dialog, which) -> {
                                        dialog.dismiss();
                                        Toast.makeText(MainActivity.this, "Please allow this permission!", Toast.LENGTH_SHORT).show();
                                    })
                                    .create().show();
                        }
        
                    }
                }
            }