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
}
}
135352 次浏览

如果您从设置中关闭了应用程序的权限,则不能从代码或低于棉花糖的安卓版本中打开您的权限。

您可以检查这个文档 Https://developer.android.com/training/permissions/requesting.html 这就是一个例子 Https://www.learn2crack.com/2015/10/android-marshmallow-permissions.html

I have done following to check a permission inside a fragment.

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现在是 不赞成,谷歌建议改用 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)

有关此方法的更多文档,可以检查 这个链接

在活动中而不是片段中调用 onRequestPermissionsResult。尝试在活动中重写 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();
}
}
}

我就是这么做的,对我很有效,谢谢!

活动:

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 {


}

对我有效的方法是在 活动中调用 onRequestPermissionsResult方法,碎片活动中实现,而不是在片段本身中调用它。 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();
}


}
});

在有助于实现片段的活动中,在 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方法中的权限。如果在片段和包含该片段的活动中重写 onRequestPermissionsResult方法,请确保在活动方法中调用 super.onRequestPermissionsResult(...),以传播对片段中的 onRequestPermissionsResult方法的调用。

I was getting tripped up using checkSelfPermission() in a Fragment and wondering what would be the best approach for Context being null (Kotlin specific)... should I use !! or 别的东西?

我根据 我在 iosching 找到的密码选了 something else。看一下下面的示例,并记住,在 Fragment附加到 Activity之前,Context将为空。

private fun fineLocationPermissionApproved(): Boolean {


val context = context ?: return false


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

Check Permissions from Fragment (the 2021 way)

片段中的 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)
}
}

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

在片段中的 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();
}
        

}
}
}

如果有人对 Kotlin 感兴趣,请拨打允许电话。

    private fun directCall() {
val numberText = phoneNo
val intent = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$numberText")
if (ActivityCompat.checkSelfPermission(requireContext(),Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED)
{
if(ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), Manifest.permission.CALL_PHONE)){
Toast.makeText(requireContext(), "Permission denied.", Toast.LENGTH_LONG).show()
return //<-- Check user input history if user already denied then second time not request and not ask.
}
else{
requestPermissions(arrayOf(Manifest.permission.CALL_PHONE),1)
return //<--return will call onRequestPermissionsResult and wait for user input.
}
}
startActivity(intent)
}


override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray) {
if (requestCode == requestPhoneCall && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
directCall()
}else{
Toast.makeText(requireContext(), "Permission denied", Toast.LENGTH_LONG).show()
return
}
}
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission( getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

对我来说很管用

如果(Build.VERSION.SDK _ INT > = Build.VERION _ CODES. M & & ActivityCompat.checkSelfPermission (getActivity () ,Manifest.permission. READ _ CONTACTS) ! = PackageManager. PERMISION _ GRANTED){ requestPermissions(new String[]{ PERMISSION _ REQUEST _ READ _ CONTACTS) ; //此时,在 onRequestPermisonsResult (int,String [] ,int [])重写方法中等待回调 { //Android 版本小于6.0或已获得许可。 列出联系人 = getContactNames () ; }

checkSelfPermission not working in fragments?? we can try this code

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ActivityCompat.checkSelfPermission(
getActivity(),Manifest.permission.READ_CONTACTS) !=
PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[].
{Manifest.permission.READ_CONTACTS},
PERMISSIONS_REQUEST_READ_CONTACTS); //After this point you wait for
callback in onRequestPermissionsResult(int, String[], int[]) overriden
method } else { // Android version is lesser than 6.0 or the permission
is already granted. List<String> contacts = getContactNames();
}

检查片段内部的权限

我们应该使用 requestPermissions而不是 ActivityCompat.requestPermissions

// Replace with Permissions you need to check.
requestPermissions(arrayOf(
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION"
), YOUR_REQUEST_CODE)

然后重写 onRequestPermissionsResult为 Uduel

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == YOUR_REQUEST_CODE) {
if (
grantResults.isNotEmpty() &&
grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
// Permission granted
Log.d("onRequestPermissionsResult", "permission granted")
} else {
// Permission was denied. Display an error message.
Log.d("onRequestPermissionsResult", "permission denied")
}
}
}