In the main activity of an Android application I check for permissions (Manifest.permission.MANAGE_DOCUMENTS), detect I do not have them, and call requestPermisions.
Then in onRequestPermissionResult I almost immediately get denied permission, without a dialog ever showing.
I already confirmed the same permission in another activity of the same app (through requestPermissions again, which works), so I expected this decision to be stored (for the session, or whatever), and I have never selected to deny the permission. Either way, the permission dialog is not displayed and the permission is denied automatically.
So far I have tested this on emulators of Android 7 and 6 (API 24 and 23).
I have tried:
clearing the app's data cache and wiping the device, so it's fresh
definitely not this Getting permission denied on Android M
triple-checked spelling after seeing this onRequestPermissionsResult returns immediately with denied permission and I am calling the super method
a bunch of other suggestions on stack overflow
I'm pretty stumped...
Here is the permission request (see comment in the code):
private fun askForPermissionOrSendRequest(view: View, permission: String) {
if (checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED) {
if (shouldShowRequestPermissionRationale(permission)) {
cachedView = view
val explanationDialog = AlertDialog.Builder(this).setMessage("We need permissions to read your storage in order to show your profile image.").setOnDismissListener {
requestPermissions(
arrayOf(permission),
BSMainActivity.permissionRequestSendProfilePic
)
}.create()
explanationDialog.show()
} else {
cachedView = view
// this branch is always hit - the permission seems to be missing every time
requestPermissions(
arrayOf(permission),
BSMainActivity.permissionRequestSendProfilePic
)
}
} else {
sendRequest(view)
}
}
I immediately get to the result handler without a dialog showing up to ask me for permissions. I may or may not have confirmed the same permission in another (child) activity of the same app (doesn't seem to make a difference).
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
BSMainActivity.permissionRequestSendProfilePic -> {
// This gets hit, MANAGE_DOCUMENTS was denied
if (permissions.contains(Manifest.permission.MANAGE_DOCUMENTS) && grantResults[permissions.indexOf(Manifest.permission.MANAGE_DOCUMENTS)] == PackageManager.PERMISSION_DENIED) {
Log.w(logName, "Permission to open image was denied while sending a tag request: %s %s".format(
permissions.joinToString(",", "[", "]"),
grantResults.joinToString(",", "[", "]")
))
}
// send request regardless of the result for now
sendRequest(cachedView)
}
}
}
In my manifest I have the following:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.monomon.bs">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
Only dangerous permissions can be requested at runtime and MANAGE_DOCUMENTS is not a dangerous permission.
As per the MANAGE_DOCUMENTS documentation:
This permission should only be requested by the platform document management app. This permission cannot be granted to third-party apps.
Related
I am very new to Android programming and I am having trouble requesting storage permission. The idea is to have the phone generate a small label that will print from a mobile printer via Bluetooth, but as proof of concept I was going to have the phone just save a PDF or something for now.
I added this line to the AndroidManifest.xml:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:remove="android:maxSDKVersion" />
and from the MainActivity.kt:
class MainActivity : AppCompatActivity() {
private val REQUEST_STORAGE = 101
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{
println("Permissions Denied")
requestStoragePermission()
println("Passed Command")
} else {
println("PERMISSIONS GRANTED")
}
private fun requestStoragePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
permission.WRITE_EXTERNAL_STORAGE
)
) {
requestPermissions(this, arrayOf(permission.WRITE_EXTERNAL_STORAGE), REQUEST_STORAGE)
} else {
// Eh, prompt anyway
requestPermissions(this, arrayOf(permission.WRITE_EXTERNAL_STORAGE), REQUEST_STORAGE)
}
}
}
No matter what iteration of the requestPermissions command I try, the dialog box never shows and attempting to save any file results in a failure. I know this question has been asked a lot, but none of the solutions that work for other people are working here and I'm not sure why.
I have tried:
\\this is latest iteration
requestPermissions(this, arrayOf(permission.WRITE_EXTERNAL_STORAGE), REQUEST_STORAGE)
\\this was first iteration
ActivityCompact.requestPermissions(
this#MainActivity,
arrayOf(permission.WRITE_EXTERNAL_SOTRAGE),
REQUEST_STORAGE
)
\\this one also caused an error so I abandoned the idea of moving this out of the main class
ActivityCompact.requestPermissions(
MainActivity(),
arrayOf(permission.WRITE_EXTERNAL_SOTRAGE),
REQUEST_STORAGE
)
I need the user to be able to give storage access, at least while it's still in development to convince my boss to buy a mobile printer I can use to print the actual label.
I have started default google sample project related to request runtime permissions topic. By default it uses camera permission. When I had changed Camera permission to WRITE_EXTERNAL_STORAGE permission it stops showing permission dialog too. It means nothing is wrong with your code, the issue has some different cause.
Likely it is related to changes in behaviour related to new Android API.
I haven't found root cause yet, but this links shows changes in behaviour on Android 9, 10, 11:
Different use cases
No need in permission since API 19
Variety of changes among different APIs
UPDATE
Code above doesn't show dialog for MANAGE_EXTERNAL_STORAGE permission, but you have asked for WRITE_EXTERNAL_STORAGE permission. Default google sample is able to show this permission dialog on Android API 30. Here is relevant code:
if (shouldShowRequestPermissionRationaleCompat(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// Display a SnackBar with a button to request the missing permission.
layout.showSnackbar(R.string.camera_access_required,
Snackbar.LENGTH_INDEFINITE, R.string.ok) {
requestPermissionsCompat(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_CAMERA)
}
} else {
layout.showSnackbar(R.string.camera_permission_not_available, Snackbar.LENGTH_SHORT)
// Request the permission. The result will be received in onRequestPermissionResult().
requestPermissionsCompat(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_REQUEST_CAMERA)
}
fun AppCompatActivity.requestPermissionsCompat(permissionsArray: Array<String>,
requestCode: Int) {
ActivityCompat.requestPermissions(this, permissionsArray, requestCode)
}
According to "developer.android.com"
If the app targets Android 8.0 (API level 26), the system grants only
READ_EXTERNAL_STORAGE at that time; however, if the app later requests
WRITE_EXTERNAL_STORAGE, the system immediately grants that privilege
without prompting the user.
Now, I have the READ_EXTERNAL_STORAGE and I'm requesting the DownloadManager to download a file in the Public Download folder
downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mAttachmentItem.getFilename());
Unfortunately, I got
E/UncaughtException: java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/data/user/0/com.abc.cba/files
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:699)
I have declared both of permissions in the Manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Read permission is already Granted and in Runtime I'm requesting Write permission, the system doesn't prompt any message or dialog, it's always Denied(Not Granted) in "onRequestPermissionsResult"
public static boolean isPermissionsToAccessStorageAreGranted(Context context, Activity activity) {
ArrayList<String> permissions = new ArrayList<>();
if (!PermissionUtil.checkPermissions(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (!permissions.isEmpty()) {
String[] permissionsList = permissions.toArray(new String[permissions.size()]);
PermissionUtil.requestPermissions(activity, permissionsList,
PermissionUtil.REQUESTCODE_ACCESS_STORAGE);
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==REQUESTCODE_ACCESS_STORAGE && grantResults[0]== PackageManager.PERMISSION_GRANTED){
/* downloadFile(); */
}
}
I'm trying to grant those two permissions via ADB, it shows me an error:
adb shell pm grant com.abc.cba
android.permission.WRITE_EXTERNAL_STORAGE
Operation not allowed: java.lang.SecurityException: Package com.abc.cbs
has not requested permission android.permission.WRITE_EXTERNAL_STORAGE
adb shell pm grant com.abc.cba
android.permission.READ_EXTERNAL_STORAGE
Operation not allowed: java.lang.SecurityException: Can't change
android.permission.READ_EXTERNAL_STORAGE. It is required by the
application
Actually, It was an external problem. One of App Libs I'm using request the WRITE_EXTERNAL_PERMISSION with android:maxSdkVersion. So when merging with my Manifest it will remove the permission for the whole application.
The Solution is to add:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
You are correct in adding the permissions to the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
For versions of Lollipop and higher, you need to also request the permissions at runtime. To solve this problem, I created a new method requestAppPermission that I call when the main activity is created. This method runs only for Lollipop and higher, and returns early otherwise:
private void requestAppPermissions() {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
if (hasReadPermissions() && hasWritePermissions()) {
return;
}
ActivityCompat.requestPermissions(this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_WRITE_STORAGE_REQUEST_CODE); // your request code
}
private boolean hasReadPermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasWritePermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
I call this method in the activity's onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Other things
requestAppPermissions();
}
On first load, this will prompt the user to accept permissions.
Then, before you run any code that needs to read and write to storage, you can check these permissions, either by storing the values or running those checks again using methods hasReadPermissions() and hasWritePermissions() defined above.
UPDATE: See this answer for a better solution
EDIT: This is not a solution, just a quick workaround.
If you get permission denied error even when the permissions are granted and you already implemented permission checks,
make sure you're not targetting api level 29:
Change targetSdkVersion and compilesdkversion from 29 to 28 or any other lower level.
For Oreo,
you need to explicitly do a READ_EXTERNAL_STORAGE request (by code) even if you have already requested and is granted the WRITE_EXTERNAL_STORAGE permission, and vis versa.
prior to this, READ_EXTERNAL_STORAGE is automatically granted when WRITE_EXTERNAL_STORAGE is granted.
so what you need to do, is to
1) ask for WRITE permission in your codes.
2) when user grants the WRITE permission, ask again for READ permission - this will be automatically granted (you will get an exception if you do not ask for a READ explicitly)
The changes for Oreo doesn't make much sense to me (no idea why do we need to ask for a permission that is automatically granted), but that is what it is.
https://developer.android.com/about/versions/oreo/android-8.0-changes.html#rmp
You have to grant permissions at runtime on Marshmallow or higher.
Sample snippet :
private static final int REQUEST_WRITE_STORAGE = 112;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
boolean hasPermission = (ContextCompat.checkSelfPermission(getBaseContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
ActivityCompat.requestPermissions(SplashScreen.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.RECORD_AUDIO, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.INTERNET
},
REQUEST_WRITE_STORAGE);
}else{ startMainActivity(); }
}
Hope it helps.
Use this
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
instead of
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE/>"
Some of your third party libraries are override maxSdkVersion like com.vungle:publisher-sdk-android, to finding them just check the Merged Manifest below of your manifest screen. see this
For SDK 29 and Later
If you are still having issue to accessing external storage, consider using android:requestLegacyExternalStorage="true" in your <application> tag of your manifest.
Just a notice: on Android P I had to show a terminate dialog box to user asking to restart the app because even after all written above app couldn't read external storage, only after restart. Seriously, those guys in google makes Android better each time. 6, 8, and now so much troubles with 9, one more such stupid update and I will go to iOS :)
I'm developing an app that require some system permissions, however these are no longer granted automatically at installation time on Android Marshmallow.
I would like to request these permissions at runtime and run some kind of automation to grant them without needing a user to tap the 'allow' button when the System permissions Dialog appears.
How can I achieve this? Is there any way to do so in Marshmallow and later versions?
For Marshmallow or later permissions are not granted at install time and must be requested when required at runtime (if not granted previously.)
To do this, you need to run ActivityCompat.requestPermissions() to pop up the systems permissions dialog in your Activity, at the time when the user is undertaking an action that requires additional system permissions.
An example of this for the WRITE_EXTERNAL_STORAGE permission would be:
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST_CODE
);
Note: WRITE_EXTERNAL_STORAGE_REQUEST_CODE is an arbitrary integer constant you should define elsewhere.
The permissions you request should also be declared in your AndroidManifest.xml. In this example the declaration would be:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In order to handle the system permissions dialog response you will also need to implement onRequestPermissionsResult() in your Activity. For this example the code would be similar to
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
if (grantResults.length == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) {
return; //permission not granted, could also optionally log an error
}
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
//Do whatever you needed the write permissions for
}
}
If you are automating your app through Espresso, UIAutomator and/or some other UI testing framework you will need to anticipate and click the system dialog during your test, which can be accomplished with the following test code:
private void allowPermissionsIfNeeded() {
if (Build.VERSION.SDK_INT >= 23) {
UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
if (allowPermissions.exists()) {
try {
allowPermissions.click();
} catch (UiObjectNotFoundException e) {
Timber.e(e, "There is no permissions dialog to interact with ");
}
}
}
}
A more comprehensive explanation of testing System UI Permissions is available here.
I found out that an simpler way to automate the permission acceptance without using UIAutomator or espresso in a CI scenario is to simply, pre-installing the apk via adb using:
adb install -g {my_apk_file}
The -g flag automatically grants all manifest permissions to the app. Afterwards if you launch your espresso test suite, the ui won't ask you again to grant them.
I'm trying to get the user to enable the location group permission for my app with Cordova's hasPermission/requestPermission methods, but the results are confusing...
When I call hasPermission with ACCESS_FINE_LOCATION, it always returns true. Calling this on Manifest.permission_group.LOCATION seems to return true/false appropriately.
Calling requestPermission with Manifest.permission_group.LOCATION doesn't present a system dialog, so I'm calling this with ACCESS_FINE_LOCATION to get the dialog.
The dialog Allow button turns on the Location group permission for my app and calls onRequestPermissionResult with PackageManager.PERMISSION_GRANTED, but the Deny button also returns ...GRANTED, leaving the Location group permission off.
For illustration, here's my current code:
private void checkPermissions() {
if (!cordova.hasPermission(Manifest.permission_group.LOCATION)) {
cordova.requestPermission(this, PERMISSION_RUNTIME_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION);
}
}
#Override
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException {
if (permissions.length != 1 || grantResults.length != 1 || !Manifest.permission.ACCESS_FINE_LOCATION.equals(permissions[0])) {
throw new RuntimeException("Unexpected permission results " + Arrays.toString(permissions) + ", " + Arrays.toString(grantResults));
}
int result = grantResults[0];
String action = null;
switch (result) {
case PackageManager.PERMISSION_DENIED:
action = Constants.ACTION_RUNTIME_PERMISSION_DENIED;
break;
case PackageManager.PERMISSION_GRANTED:
action = Constants.ACTION_RUNTIME_PERMISSION_GRANTED;
break;
default:
throw new RuntimeException("Unexpected permission result int " + result);
}
Intent i = new Intent(action);
i.putExtra("permission", Constants.EXTRA_RUNTIME_PERMISSION_NOTIFICATION_ID);
getContext().sendBroadcast(i);
}
What's the right way to handle this? Sometimes using an individual permission and sometimes using a group with these methods doesn't seem right - I would expect this to be consistent. My guess is that the PERMISSION_GRANTED after the DENY button is pushed on the dialog is because I'm requesting an individual permission, which is on even though the group is off; is there a way to detect that the user denied the request?
I have a lot of questions there which basically boil down to "how do I either get the user to enable the Location group permission when it's off or know when they decline"?
If it helps, my android-targetSdkVersion is set to 22, and I'm using Cordova 6.1.1.
If it helps, my android-targetSdkVersion is set to 22, and I'm using Cordova 6.1.1.
Android run-time permissions were only introduced in API 23, so if your android-targetSdkVersion is set to 22, run-time permissions code will always return GRANTED for any permission, since permissions are granted at installation time via the manifest.
However, if your app is displaying runtime permissions dialogs, I'm guessing that you must be building against API 23 and using cordova-android#5+ for the Android platform.
Regarding permission groups vs individual permissions, you should read the Android documentation regarding runtime permissions:
The dialog box shown by the system describes the permission group your app needs access to; it does not list the specific permission. For example, if you request the READ_CONTACTS permission, the system dialog box just says your app needs access to the device's contacts. The user only needs to grant permission once for each permission group. If your app requests any other permissions in that group (that are listed in your app manifest), the system automatically grants them. When you request the permission, the system calls your onRequestPermissionsResult() callback method and passes PERMISSION_GRANTED, the same way it would if the user had explicitly granted your request through the system dialog box.
So in your case, requesting ACCESS_FINE_LOCATION grants access to all permissions in the LOCATION group (you can find the full list of groups and permissions here).
the Deny button also returns ...GRANTED, leaving the Location group permission off.
This should not return GRANTED. If the Deny button is pressed, access will be DENIED to that entire permission group (including the requested permission). The logic in your code snippet looks OK to handle this, so I would use the step-through debugger in Android Studio to see exactly what is happening in your code here.
I just started off with android M and I am unable to access the external storage. I get the following error
Caused by: java.lang.SecurityException: Permission Denial: reading
com.android.providers.media.MediaProvider uri
content://media/external/images/media from pid=15355, uid=10053 requires
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
I am adding user-permission in manifest like
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and my build file is with following settings :
compileSdkVersion 23
buildToolsVersion "22.0.1"
minSdkVersion 16
targetSdkVersion 23
How to read and write from external storage in android M?
Reading from the documentation. I have to ask user for permission at runtime. Code example :
Add permission to android manifest like we used to do earlier :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Check if the user has already granted the permission. If yes, skip asking for permission and continue with your work flow else ask user for permission :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(this)) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 2909);
} else {
// continue with your code
}
} else {
// continue with your code
}
Now to check if the user granted the permission or denied it #Override OnRequestPermissionResult to get a callback :
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 2909: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("Permission", "Granted");
} else {
Log.e("Permission", "Denied");
}
return;
}
}
}
I was not able to READ external storage only by asking WRITE
permission, so i had to request for
Manifest.permission.READ_EXTERNAL_STORAGE as well.
Also if you want to target versions below api 23, check the Build
VERSION at runtime with IF statement and ask for permissions only if
VERSION is equal or above Android M.
In case you are looking for a way to handle in any android version (you are compiling for M, but some devices can be using other versions) there is a compatibility version.
if (ContextCompat.checkSelfPermission(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(CreatePlayerActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Show an expanation 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(CreatePlayerActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
In regards to the selected answer:
Settings.System.canWrite(this) and WRITE_EXTERNAL_STORAGE are two very different things! Should be:
boolean needsRead = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
boolean needsWrite = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED;
if (needsRead || needsWrite)
requestStoragePermission()
I was struggling with WRITE_EXTERNAL_STORAGE permission: after I requested it, the dialog didn't show up and immediately returned DENIED.
The problem was in one of the included libraries. It contained the same permission declaration in its AndroidManifest.xml, but with maxSdkVersion="22". The declaration in application's manifest file was overridden by the library.
To override permission from the library I used the following:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="remove"
tools:selector="com.example.lib" />
I hope this might be helpful.
I used this utility on github. It works with with both API 22 and 23. Adding runtime permissions is not hard but having to seperate your code and move the methods around to capture callbacks is a little pain. This library provides a chained api to do all you need to do for supporting runtime permissions.
https://github.com/kayvannj/PermissionUtil