How to check permission in fragment

JavaAndroidKotlinAndroid FragmentsAndroid Permissions

Java Problem Overview


I want to check a permission inside a fragment.

my code:

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

but onRequestPermissionsResult not called after allow or deny.

@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
    }
}

Java Solutions


Solution 1 - Java

This is how I did, it works for me. Thanks!

For Activity :

ActivityCompat.requestPermissions(this, permissionsList, REQUEST_CODE);

For Fragment :

requestPermissions(permissionsList, REQUEST_CODE);

Solution 2 - Java

Fragment has requestPermissions() and onRequestPermissionsResult() methods, use it.

But checkSelfPermission() is from ActivityCompat (not require Activity, only 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();
        }
    }
}

Solution 3 - Java

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");
    }

Update

Since Fragment.requestPermissions is now deprecated, Google advises using registerForActivityResult instead.

I have done the request like this:

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

permissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)

For more documentation on this method you can check this link.

Solution 4 - Java

Check Permissions from Fragment (the 2021 way)

The registerForActivityResult() method in fragment is now deprecated. The deprecation message suggests to use registerForActivityResult. So after some trial and errors, here is the 2021 way:

Suppose your fragment's name is AwesomeFragment. Then in the constructor (before the fragment's onCreate method to be precise), you initialize ActivityResultLauncher<String[]> activityResultLauncher.

java version
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();
                }
            }
        });
}

Then maybe on some button click, you invoke the launch method:

    @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 version
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)
  }       
}

Solution 5 - Java

To handle permissions in a Fragment call requestPermissions method. If you override onRequestPermissionsResult method in both fragment and activity, containing that fragment, make sure to call super.onRequestPermissionsResult(...) in the activity method to propagate call to the onRequestPermissionsResult method in the fragment.

Solution 6 - Java

Using Kotlin, you call requestPermissions(arrayOf(Manifest.permission.THE_PERMISSION_CODE_YOU_WANT), PERMISSION_REQUEST_CODE) and add the following override to your fragment

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

Solution 7 - Java

onRequestPermissionsResult is invoked in the activity not the fragment. Try overriding onRequestPermissionsResult in the activity instead.

Solution 8 - Java

What worked for me was calling the onRequestPermissionsResult method in the activity inside which fragment is implemented rather than calling it in fragment itself. Inside onCreateView method in fragment:

    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();
            }

        }
});

In the Activity which helps to implement fragment, outside of onCreate method:

    @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;
    }
}



    

Solution 9 - Java

If you closed your permission of app from settings , you can not open your permission from code or your android version lower than Marshmallow.

You can check this documentation https://developer.android.com/training/permissions/requesting.html And this is a example https://www.learn2crack.com/2015/10/android-marshmallow-permissions.html

Solution 10 - Java

To check permission within a fragment, I did the following.

Before onCreateView in Fragment add the following,

private final int STORAGE_PERMISSION_CODE = 1;

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

Check the permission,

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

Place the following code in MainActivity to enable permission from the app's settings if the user denied the permission forever.

@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();
                        }
        
                    }
                }
            }

Solution 11 - Java

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 something else?

I went with something else based on code I found in iosched. Have a look at the sample below, and remember, before the Fragment is attached to an Activity, the Context will be null.

private fun fineLocationPermissionApproved(): Boolean {

    val context = context ?: return false

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionS.M_EmamianView Question on Stackoverflow
Solution 1 - JavaThetNaing MizoView Answer on Stackoverflow
Solution 2 - JavaEvgeny NozdrevView Answer on Stackoverflow
Solution 3 - JavarookieDeveloperView Answer on Stackoverflow
Solution 4 - JavaQazi Fahim FarhanView Answer on Stackoverflow
Solution 5 - JavaBigStView Answer on Stackoverflow
Solution 6 - JavaErikView Answer on Stackoverflow
Solution 7 - JavaRyanView Answer on Stackoverflow
Solution 8 - JavaPranay AnandView Answer on Stackoverflow
Solution 9 - JavaMuhammed AlmazView Answer on Stackoverflow
Solution 10 - JavaHAZEEM JOONUSView Answer on Stackoverflow
Solution 11 - JavacodingjeremyView Answer on Stackoverflow