android – How to check permission in fragment-ThrowExceptions

Exception or error:

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
    }
}
How to solve:

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

###

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

For Activity :

ActivityCompat.requestPermissions(this, permissionsList, REQUEST_CODE);

For Fragment :

requestPermissions(permissionsList, REQUEST_CODE);

###

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

###

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

###

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 {

}

###

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.

###

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

###

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

###

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

Leave a Reply

Your email address will not be published. Required fields are marked *