IllegalArgumentException in grantUriPermission on API level 19 - android

The following line of code
context.getApplicationContext().grantUriPermission(packageName, uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
raises this exception when running on devices with API level 19 (KitKat), but not on later versions:
java.lang.IllegalArgumentException: Requested flags 0x40, but only 0x3 are allowed
at android.os.Parcel.readException(Parcel.java:1476)
at android.os.Parcel.readException(Parcel.java:1426)
at android.app.ActivityManagerProxy.grantUriPermission(ActivityManagerNative.java:3461)
at android.app.ContextImpl.grantUriPermission(ContextImpl.java:1732)
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:577)
Why is that so?

I believe this is caused by a change added in KitKat which should have fixed content access but they broke it.
You would need to run a check using Build.VERSION.SDK_INT < 19 (ie. pre-KitKat)
if(Build.VERSION.SDK_INT < 19) {
context.getApplicationContext().grantUriPermission(packageName, uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
} else {
takePersistableUriPermission(packageName, uri);
}
http://developer.android.com/reference/android/content/ContentResolver.html#takePersistableUriPermission

I think this is a bug in KitKat.
https://android.googlesource.com/platform/frameworks/base/+/kitkat-mr2.2-release/services/java/com/android/server/am/ActivityManagerService.java#6214
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION is missing in check condition.
from lolipop version, it works correctly

Related

requestPermissions() method is showing error warning in Activity

I used requestPermissions() method in fragment and its working fine without showing any error or warning but when i use the same code in Activity for same purpose its working fine but showing an error warning. The following code i used in both fragment and Activity
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE, CAMERA}, PERMISSION_REQUEST_CODE);
Its showing like this
Code is running correctly but its showing like this only in Activity not in fragment, Why and how can i fix this ?.
In your AndroidManifest.xml you have specified android:minSdkVersion = "21" but this API is only available on SDK versions 23 and up.
You have to check the android version first or your app will crash on android versions 5.0 (SDK 21) and 5.1 (SDK 22)
For cheking and supporting different android versions refer to https://developer.android.com/training/basics/supporting-devices/platforms
Your minimum api level version is 21 but requestPermission method works from version level 23.
So, to use requestPermission() method you must handle the version code-
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
requestPermission(............................)
}
Problem : Runtime Permission is part of MarshMallow & Above. Your current min API is 21(Lollipop) which does not have runtime permission.
Solution: Either you need to check whether current API is above Marshmallow or use ActivityCompat
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
}
Or
ActivityCompat.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);

Android M Error on api 22, and requestPermissions() method not found

I'm working in API 22, but I want to compile my project in Android M 6.0, I have this code:
Declared at the top:
private static final String[] REQUIRED_PERMISSIONS = new String[]{"READ_EXTERNAL_STORAGE"};
private static final int REQUEST_PERMISSIONS = (Integer) null;
And on my onCreate():
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
LinkedList<String> missingPermissions = new LinkedList<>();
for(String p : REQUIRED_PERMISSIONS){
if(checkCallingOrSelfPermission(p) != PackageManager.PERMISSION_GRANTED){
missingPermissions.add(p);
}
}
if(!missingPermissions.isEmpty()){
String[] mpArray = new String[missingPermissions.size()];
missingPermissions.toArray(mpArray);
requestPermissions(mpArray, REQUEST_PERMISSIONS);
}
}
I was inspired here for checking my problem
and in Eclipse is giving me an error on Build.VERSION_CODES.M(M not found), and then, the callback method requestPermissions(mpArray, REQUEST_PERMISSIONS) isn't found too, any suggestion?
If I'm working on API 22, and I'm compiling with Android 6.0 M. How I can solve the issue for the dangerous permissions like READ_EXTERNAL_STORAGE correctly on API 22?
As per the documentation, Build.VERSION_CODES.M and requestPermissions() were added in API level 23.
Since you are compiling with API level 22, those simply do not exist.
To access APIs introduced in API level 23, you need to compile with API 23. You cannot access these APIs if you continue to compile with API 22.
Note that simply compiling with API 23 will not affect the way your application behaves on any devices, it simply opens up the newer APIs for your use on devices running at least API 23.
if I'm working on API 22, and I'm compiling with Android 6.0 M, how i can do for solve the issue for the dangerous permissions like READ_EXTERNAL_STORAGE correctly on API 22?
Devices running API 22 will continue to use the old install-time model for permissions. Nothing has changed for devices running API 22 and below. Only devices running API 23 use the new runtime permissions model.

Call requires API level 16 (current min is 14)

I have this line in my code:
linearLayout.setBackground(drawable);
setBackground() shows the following error:
Call requires API level 16 (current min is 14)
What does this mean?
Can I raise my API level?
What does a higher/lower API level mean?
Does it limit the amount of devices my app can be used on if the API level is higher?
What does this mean?
It means that the setBackground(Drawable) method was added in API Level 16, and older devices do not have it. However, your app's minSdkVersion is 14. So, unless you take steps to avoid this line on API Level 14 and 15 devices, your app will crash on those devices.
Can I raise my API level?
You could set your minSdkVersion to 16.
Does it limit the amount of devices my app can be used on if the API level is higher?
Yes. If you say that your minSdkVersion is 16, then devices running a version of Android older than that cannot run your app.
At the time of this writing, about 90% of Android devices accessing the Play Store are on API Level 16 or higher (i.e., are running Android 4.1 or higher).
You can read more about the concept of API levels in the documentation. Note that this documentation is a bit old, in that it focuses on the minSdkVersion being defined in the manifest. In Android Studio projects, minSdkVersion is usually defined in your app module's build.gradle file.
Can I raise my API level?
You can set API to 16 it will limit device below 16 but it will perfectly work on devices API 16 and higher
Or else You can use API check and set
final int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
layout.setBackgroundDrawable( getResources().getDrawable(R.drawable.ready) );
} else {
layout.setBackground( getResources().getDrawable(R.drawable.ready));
}
Use a validation method that will be supported only in API LEVEL >= 16 (note the use of ContextCompat class:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
linearLayout.setBackground(ContextCompat.getDrawable(this, drawableid));
}
Use:
layout.setBackgroudResource(R.drawable.ready);

Compiler Ginger Bread, build version codes Jelly Bean Mr1 cannot resolve or is not a field

Question: What code should i use instead of
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){ //perform something }
Build.VERSION_CODES.JELLY_BEAN_MR1 error can not be resolved.
If compiled is set to Jelly Bean Mr1 and higher no errors. If compiler is set below Jelly Bean Mr1 errors occur.
minSdk = 9, targetSdk = 19, compiler = 2.3.1(Ginger Bread) see the below screen shot URL
https://www.evernote.com/shard/s283/sh/401b9ed5-d51d-4d55-b23d-6ebe8eeb8d03/212a791182b162df8dadb614445f2d2d
if Build.VERSION_CODES.JELLY_BEAN_MR1 gives a problem, only write:
import android.os.Build;
if you don't want to write it you can use
if( Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
{
//perform something
} else {
// perform other actions for other versions (below than jelly..)
// find another way to do what you want.
}
if the problem persist maybe you don't have the necessary libraries, please update your libraries with Android SDK Manager.
JELLY_BEAN_MR1 ~ Android 4.2
You should install and use Android 4.2 or higher as a compiler.

How to support different Android versions?

I found that from API 19+ their is a small change in code and it doesn't appear in API 19-.
How can I support both android versions in the same app?
EDIT: The are feature that exists only in android 4.1.2 and in versions below 4.1.2 they doesn't exists.
How can I make an app that support both versions with the exception that in lower version the "new" features won't exist? (its hard for me to explain)
You can wrap the API 19-specific code inside a conditional that queries the device version with the enumerated values present in Build.VERSION_CODES.
for instance :
if ( android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT )
{
// Kitkat (API level 19) code in here...
}
else {
// code for all versions lower than Kitkat in here...
}

Categories

Resources