I've a strange android permission denial, here is it:
java.lang.SecurityException: Permission Denial: isUserRunning() from pid=1078, uid=10284 requires android.permission.INTERACT_ACROSS_USERS
I haven't found anything about android.permission.INTERACT_ACROSS_USERS only android.permission.INTERACT_ACROSS_USERS_FULL
Here is the full logcat:
java.lang.SecurityException: Permission Denial: isUserRunning() from pid=25403, uid=10310 requires android.permission.INTERACT_ACROSS_USERS
at android.os.Parcel.readException(Parcel.java:1693)
at android.os.Parcel.readException(Parcel.java:1646)
at android.app.ActivityManagerProxy.isUserRunning(ActivityManagerNative.java:7000)
at android.os.UserManager.isUserUnlocked(UserManager.java:1069)
at android.os.UserManager.isUserUnlocked(UserManager.java:1063)
at com.android.launcher3.compat.UserManagerCompatVN.isUserUnlocked(UserManagerCompatVN.java:39)
at com.android.launcher3.LauncherModel$LoaderTask.loadWorkspace(LauncherModel.java:1759)
at com.android.launcher3.LauncherModel$LoaderTask.loadAndBindWorkspace(LauncherModel.java:1387)
at com.android.launcher3.LauncherModel$LoaderTask.run(LauncherModel.java:1486)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
I've added this to my manifest:
<permission android:name="android.permission.INTERACT_ACROSS_USERS" android:protectionLevel="signature"/>
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>
TL;DR; Either this stack trace does not belong to your application or you need a permission that you don't have. To know about those permissions read the rest.
Although Michele probably has found the answer, I've decided to answer this question as it might be useful for others. Mentioned permissions are signature|system level permissions. To read more about different types of permissions read this: Permissions overview
Basically these permissions are needed to use multi-user APIs such as:
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
To know more, read this: Supporting Multiple Users and this: Building Multiuser-Aware Apps
Due to the error, Michele has come to this conclusion that he has to add these permissions to manifest (which we will see how it is possible for an application to have these permissions granted), but instead, he has defined these permissions(to know more about defining a permission read this: Define a Custom App Permission):
<permission android:name="android.permission.INTERACT_ACROSS_USERS" android:protectionLevel="signature"/>
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>
I think you will end up seeing a run time error because you can't define these permissions since they have the same name as two system permission that are already defined. Want to be sure? Take a look at a part of a real system manifest:
<!-- #SystemApi #hide Allows an application to call APIs that allow it to do interactions
across the users on the device, using singleton services and
user-targeted broadcasts. This permission is not available to
third party applications. -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS"
android:protectionLevel="signature|system|privileged" />
<!-- #hide Fuller form of {#link android.Manifest.permission#INTERACT_ACROSS_USERS}
that removes restrictions on where broadcasts can be sent and allows other
types of interactions. -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
android:protectionLevel="signature" />
You see in this manifest file of an android system, these permissions are defined already and to use them we should use the tag.
So now lets talk how theses permissions might be granted to your application. In my experience OEMs define system manifest in a way that these permissions could be granted to
Apps which have the same signature as the system(practically only apps which are developed by the OEM)
Privileged apps being under the /system/priv-app.
In the system manifest I mentioned above the second permission is only defined as signature so only apps with the same signature as system can have those permissions granted.
If you have write access on a device (probably it should be rooted, I don't know much about that), you can copy your apk in the priv-app folder by this command:
adb push path-to-your-app/your-app.apk /system/priv-app
Is that all? Not yet!
Since android 8.0 there are some complications about permissions being granted to applications under priv-app that you can read about it here: Privileged Permission Whitelisting
You should implement permission request at run-time in Android, specifically for Marshmallow or higher version.
If you don’t implement run-time permission, then your application will crash or will not work properly on the device having Marshmallow.
I hope you are now pretty much aware with Runtime Permission concept in Marshmallow. Let’s understand this code:
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.INTERACT_ACROSS_USERS)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("Interact across users permission is necessary to this app");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.INTERACT_ACROSS_USERS}, MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.INTERACT_ACROSS_USERS}, MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do something here...
Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
} else {
//code for deny
Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
break;
}
}
Related
I'm experiencing app crashes on Oreo Android 8.0/8.1 devices when using the calendar provider. The problem does not show on my devices running Nougat and below.
Permission Denial: reading com.android.providers.calendar.CalendarProvider2 uri content://com.android.calendar/calendars from pid=8522, uid=10197 requires android.permission.READ_CALENDAR, or grantUriPermission()
What puzzles me is that crashes happen even though the system requests persmissions in runtime, they are confirmed by the user, and they can be verified in the system settings. Even checking permissions before access (see my code below) does not help. Access is confirmed - and then denied.
In my AndroidManifest:
<manifest ...>
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application>
...
</application>
</manifest>
As an example (the problem occurs also for other queries), I create a calendar using this method:
public static void createCalendarIfNotExists(android.app.Activity activity) throws SecurityException {
ContentResolver contentResolver = activity.getContentResolver();
// Check if calendar already exists.
String[] projection = new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME};
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
Cursor cursor = contentResolver.query(CalendarContract.Calendars.CONTENT_URI,
projection,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + " = ?",
new String[]{CALENDAR_NAME},
null);
if (cursor != null) {
if (cursor.getCount() == 0) {
final ContentValues cv = buildNewCalContentValues(activity);
Uri calUri = buildCalUri();
// Insert the calendar into the database.
contentResolver.insert(calUri, cv);
}
if (!cursor.isClosed()) {
cursor.close();
}
}
}
}
Despite checking calendar permissions with result GRANTED the query fails due to lack of permissions (the request for permissions is done outside this function but the permissions are verified here before running the query).
Why is this happening, and why does it seem to start happening with Android Version 8?
Why is this happening
You are checking for the wrong permission. The error says that you need READ_CALENDAR; you are checking for WRITE_CALENDAR. While you do not show the requestPermissions() call, my guess is that you are only requesting WRITE_CALENDAR.
why does it seem to start happening with Android Version 8?
They tightened up security. Quoting the documentation:
Prior to Android 8.0 (API level 26), if an app requested a permission at runtime and the permission was granted, the system also incorrectly granted the app the rest of the permissions that belonged to the same permission group, and that were registered in the manifest.
For apps targeting Android 8.0, this behavior has been corrected. The app is granted only the permissions it has explicitly requested. However, once the user grants a permission to the app, all subsequent requests for permissions in that permission group are automatically granted.
For example, suppose an app lists both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE in its manifest. The app requests READ_EXTERNAL_STORAGE and the user grants it. If the app targets API level 25 or lower, the system also grants WRITE_EXTERNAL_STORAGE at the same time, because it belongs to the same STORAGE permission group and is also registered in the manifest. 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.
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/> syntax, could you help me please?
(the following is extracted from a blog post of mine about this)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
ACCEPT_HANDOVER
ACCESS_BACKGROUND_LOCATION
ACCESS_MEDIA_LOCATION
ACTIVITY_RECOGNITION
ANSWER_PHONE_CALLS
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion 23+ app
need to have the <uses-permission> element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission() and
requestPermissions().
As a temporary workaround, drop your targetSdkVersion below 23.
However, eventually, you will have some reason to want your
targetSdkVersion to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
Above API level 23 you will be given programmatically pragmatically like:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
Please go through the link below,
https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
request permission pragmatically (after API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
If you are using sdk 23 or higher then you must check run time permissions.
when you declare permisson in Manifest and it's not work means you are performing Task in MarshMallow and for MarshMallow you have set Permisson at RunTime.
like this way
ActivityCompat.requestPermissions();
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
Check this: https://developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
Along with CommonsWare's answer,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
I added this to my MainActivity, that resolve my problem
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_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(this,
new String[]{Manifest.permission.WRITE_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.
}
}
I hope the solution to write to external storage will be useful too
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}
So i had to create an app to send and receive messages but the send action crashed whenever i clicked on send even though the permission was granted . I had requested runtime permissions and allowed them, still i faced a crash that the process doesnt have the requested permission to send SMS .
I had checked the granted permissions from :
adb shell dumpsys package <package-name>
The order of my request for permissions was
RECEIVE_SMS
SEND_SMS
I reverted the order of request and it works fine . This was tested with a complete new app(uninstall-> install -> test). The answer may seem weird but just give it a shot .
(If it works in the shown way in a certain order, then Android might have a bug!!)
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/> syntax, could you help me please?
(the following is extracted from a blog post of mine about this)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
ACCEPT_HANDOVER
ACCESS_BACKGROUND_LOCATION
ACCESS_MEDIA_LOCATION
ACTIVITY_RECOGNITION
ANSWER_PHONE_CALLS
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion 23+ app
need to have the <uses-permission> element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission() and
requestPermissions().
As a temporary workaround, drop your targetSdkVersion below 23.
However, eventually, you will have some reason to want your
targetSdkVersion to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
Above API level 23 you will be given programmatically pragmatically like:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
Please go through the link below,
https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
request permission pragmatically (after API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
If you are using sdk 23 or higher then you must check run time permissions.
when you declare permisson in Manifest and it's not work means you are performing Task in MarshMallow and for MarshMallow you have set Permisson at RunTime.
like this way
ActivityCompat.requestPermissions();
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
Check this: https://developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
Along with CommonsWare's answer,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
I added this to my MainActivity, that resolve my problem
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_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(this,
new String[]{Manifest.permission.WRITE_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.
}
}
I hope the solution to write to external storage will be useful too
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}
So i had to create an app to send and receive messages but the send action crashed whenever i clicked on send even though the permission was granted . I had requested runtime permissions and allowed them, still i faced a crash that the process doesnt have the requested permission to send SMS .
I had checked the granted permissions from :
adb shell dumpsys package <package-name>
The order of my request for permissions was
RECEIVE_SMS
SEND_SMS
I reverted the order of request and it works fine . This was tested with a complete new app(uninstall-> install -> test). The answer may seem weird but just give it a shot .
(If it works in the shown way in a certain order, then Android might have a bug!!)
I'm trying to write code to send an SMS from an Android app, but when I try to send the SMS it sends me back the error:
09-17 18:37:29.974 12847-12847/**.**.****E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: **.**.****, PID: 12847
java.lang.SecurityException: Sending SMS message: uid 10092 does not have android.permission.SEND_SMS.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
at **.**.****.MainActivity$3.onClick(MainActivity.java:70)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I checked but I have the permissions in the manifest, as follows:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-feature android:name="android.hardware.telephony"
android:required="true"/>
<application
android:exported="true"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I searched the internet but all the errors were about the <uses-permission/> syntax, could you help me please?
(the following is extracted from a blog post of mine about this)
The big reason for not getting your permission nowadays is because
your project has a targetSdkVersion of 23 or higher, and the permission
that you are requesting is "dangerous". In Android 6.0, this includes:
ACCEPT_HANDOVER
ACCESS_BACKGROUND_LOCATION
ACCESS_MEDIA_LOCATION
ACTIVITY_RECOGNITION
ANSWER_PHONE_CALLS
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ADD_VOICEMAIL
BODY_SENSORS
CALL_PHONE
CAMERA
GET_ACCOUNTS
PROCESS_OUTGOING_CALLS
READ_CALENDAR
READ_CALL_LOG
READ_CELL_BROADCASTS
READ_CONTACTS
READ_EXTERNAL_STORAGE
READ_PHONE_STATE
READ_SMS
RECEIVE_MMS
RECEIVE_SMS
RECEIVE_WAP_PUSH
RECORD_AUDIO
SEND_SMS
USE_SIP
WRITE_CALENDAR
WRITE_CALL_LOG
WRITE_CONTACTS
WRITE_EXTERNAL_STORAGE
For these permissions, not only does your targetSdkVersion 23+ app
need to have the <uses-permission> element(s), but you also have
to ask for those permissions at runtime from the user on Android 6.0+
devices, using methods like checkSelfPermission() and
requestPermissions().
As a temporary workaround, drop your targetSdkVersion below 23.
However, eventually, you will have some reason to want your
targetSdkVersion to be 23 or higher. At that time, you will need
to adjust your app to use the new runtime permission system.
The Android documentation has
a page dedicated to this topic.
Above API level 23 you will be given programmatically pragmatically like:
private static final int PERMISSION_REQUEST_CODE = 1;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.SEND_SMS)
== PackageManager.PERMISSION_DENIED) {
Log.d("permission", "permission denied to SEND_SMS - requesting it");
String[] permissions = {Manifest.permission.SEND_SMS};
requestPermissions(permissions, PERMISSION_REQUEST_CODE);
}
}
Please go through the link below,
https://developer.android.com/guide/topics/permissions/overview.html
Some samples are also available there to get start with the permissions.
To make android more secure now developers has to mention permission in manifest as well as they should have to ask user as well in run time to get the work done. They are permission categorized in dangerous permission section which are mention below
CALENDAR
READ_CALENDAR
WRITE_CALENDAR
CAMERA
CAMERA
CONTACTS
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE
RECORD_AUDIO
PHONE
READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS (must request at runtime)
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
ANSWER_PHONE_CALLS
SENSORS
BODY_SENSORS
SMS
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
request permission pragmatically (after API 23)
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Ask for permision
ActivityCompat.requestPermissions(this,new String[] { Manifest.permission.SEND_SMS}, 1);
}
else {
// Permission has already been granted
}
"If the app has the permission, the method checkSelfPermission() returns PERMISSION_GRANTED, and the app can proceed with the operation.
If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission. You need to prompt the user for that permission, as shown in the above code. Calling requestPermissions() brings up a standard Android dialog, which you cannot customize."
If you are using sdk 23 or higher then you must check run time permissions.
when you declare permisson in Manifest and it's not work means you are performing Task in MarshMallow and for MarshMallow you have set Permisson at RunTime.
like this way
ActivityCompat.requestPermissions();
If you are using Android version "23" or "23+", then app will show you errors when you are trying to access anything which requires user's permission. You have to ask for permissions at run-time even if you have declared those permissions in Android manifest.
Check this: https://developer.android.com/training/permissions/requesting.html
But if you have created your whole application and don't want to change at every place then a little cheat will be sufficient.
Go to "Build.gradle" file and change the target Sdk version to less than 23, like 22, 21.
Along with CommonsWare's answer,
There is a Security Setting (I checked on CM13) to set SMS Message Limit. If you set this to "None", OS will popup a Dialog for every SMS, even after obtaining SMS_SEND permission in the runtime. Best thing is to set this to maximum.
If the maximum is not enough, there are ways to increases the maximum rate on a rooted device.
I added this to my MainActivity, that resolve my problem
int MY_PERMISSIONS_REQUEST_READ_CONTACTS=0;
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_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(this,
new String[]{Manifest.permission.WRITE_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.
}
}
I hope the solution to write to external storage will be useful too
public boolean checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Timber.tag(LOG_TAG).e("Permission error. You have permission");
return true;
} else {
Timber.tag(LOG_TAG).e("Permission error. You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else {
// for a stuff below api level 23
Timber.tag(LOG_TAG).e("Permission error. You already have the permission");
return true;
}
}
So i had to create an app to send and receive messages but the send action crashed whenever i clicked on send even though the permission was granted . I had requested runtime permissions and allowed them, still i faced a crash that the process doesnt have the requested permission to send SMS .
I had checked the granted permissions from :
adb shell dumpsys package <package-name>
The order of my request for permissions was
RECEIVE_SMS
SEND_SMS
I reverted the order of request and it works fine . This was tested with a complete new app(uninstall-> install -> test). The answer may seem weird but just give it a shot .
(If it works in the shown way in a certain order, then Android might have a bug!!)
I'm trying to create a simple app that can get an image from the Gallery app and display it on an imageButton. I'm testing with API 21 on a phone running Android 5.0.1. Unfortunately, no matter what I try I keep getting a security error - even when I specify the permissions.
My code for getting retrieving the image is:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode){
case PICK_IMAGE_REQUEST:
if(resultCode == RESULT_OK && imageReturnedIntent != null && imageReturnedIntent.getData() != null) {
Uri uri = imageReturnedIntent.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// Log.d(TAG, String.valueOf(bitmap));
ImageButton ib = (ImageButton) findViewById(R.id.inputImg);
ib.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
break;
}
}
The code works when I try to select an image from Dropbox, but when I select an image from gallery, I get
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
I made the use-permission tag for READ_EXTERNAL_STORAGE a child of manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="[REDACTED]">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission tools:node="replace" android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
<application>
[REDACTED]
</application>
</manifest>
I've searched high and low on other posts, but still can't seem to figure out why I'm still getting this pesky error.
PROBLEM
Your have the error
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/35634 from pid=25240, uid=10070 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission().
CAUSE
You are not giving correctly permissions because of android:maxSdkVersion="18", which according to documentation.
The highest API level at which this permission should be granted to your app. Setting this attribute is useful if the permission your app requires is no longer needed beginning at a certain API level.
As long as you didn't give permissions to API 21 your app is behaving ok.
Check this topic for further info.
SOLUTION
If you wanna give read permissions under API 21, you must declare them as:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
IMPORTANT:
This only make sense when you need to give extra permissions because some old api's require permissions that new versions doesn't, so user experience get's improved because you only ask for certain permissions when needed.
So (in this case) the correct way will be:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
ADD ON
If you want to save data you must add WRITE_EXTERNAL_STORAGE permissions.
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Simply replace with the below one and try,
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
While debugging on some devices you need to grant permission explicitly by going to your settings --> apps --> MY_APPLICATION --> Permissions and then grant required permissions.
In addition to adding the below in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
we also need to request permission in the activity for the app to actually have access to external storage. https://developer.android.com/training/permissions/requesting.html