Android 12 SCHEDULE_EXACT_ALARM permission not applied in new process - android

Hy guys
Situation
I have been updated MyApp to target Android 12 and ran into some odd behavior with the new SCHEDULE_EXACT_ALARM permission.
I have following problem with the new introduced permission
In my AndroidManifest.xml I declared the permission as following:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myfirm.myapp">
.... more permissions
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<application>
....
</application>
<service
android:name="com.myfirm..services.KernelStartedService"
android:enabled="true"
android:exported="true"
android:process=":KernelStartedService">
<intent-filter>
<action android:name="com.myfirm.service.kernel.api.ANDROID_KERNEL_SERVICE_BINDING_ACTION" />
</intent-filter>
</service>
</manifest>
As you can see in the declaration the value of the process attributes starts with a colon (:)
this means a new process, private to the application, is created when it's needed and the service runs in that process.
Before Starting or binding this service I invoke a test if the permission is given with this helper function:
private fun canExactAlarmsBeScheduled(): Boolean {
val alarmManager = this.getSystemService(ALARM_SERVICE) as AlarmManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
alarmManager.canScheduleExactAlarms()
} else {
true // below API it can always be scheduled
}
}
In the onStart Method of the first Activity I then do a test if the permission is givien, if not, I provoke showing a dialog to the user that he needs to give this permission to my app:
override fun onStart() {
// non relevant code here
if (canExactAlarmsBeScheduled()) {
initApplication() // here the service will be started/ bound
} else {
// start System Settings to enable alarms, coming back to Myapp will
// provoke an onStart again
AlertDialog.Builder(this)
.setMessage(getString(R.string.bootstrap_need_permission_to_schedule_alarms,getString(R.string.app_name)))
.setPositiveButton(getString(R.string.dialog_ok)) { _: DialogInterface, _: Int ->
intent = Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM).apply {
data = Uri.fromParts(PACKAGE_SCHEME, packageName, null)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
}
.show()
}
}
}
This above is working well for the MyApp.
Problem:
I do ensure that only if the Permission of Scheduling exact alarms is given, the above mentioned Service "KernelStartedService" will be started in a new process.
The already granted permission is not taken by the new process in which the service is running in
If later on in classes that are running in this dedicated Process are testing alarmManager.canScheduleExactAlarms(). Then it ALWAYS is returning false!
Question:
How can I achieve to take over the permission SCHEDULE_EXACT_ALARM also for the process called ":KernelStartedService"?
The other permissions like...
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
...are all respected also for this new process. Why is the declaration
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
not respected in the separate process ":KernelStartedService"
As far as I see, this is a bug of Android 12 (API31 -App) when it creates the Process not applying this permission to the new process.
Expected behavior
I would expect that if the permissions are granted for the app-process, and afterwards I start a service in separate process, that all permissions would be applied to the new created process.
Thanks in advance for any help!

Related

Android13, SYSTEM_ALERT_WINDOW permission not checked in BroadcastReceiver

I want to show a floating view when the user gets a phone call or a text message. But overlay permission check in broadcastReceiver returns false with built apk on Android 13.
I use BroadcastReceiver with RxWorker (more than 12) and Service (less than 12) to get a caller information. In Worker or Service, when you success to get a information, you call WindowManager.addview(mView). When the app is first launched, the user has already granted the permission to draw overlays.
<receiver
android:name=".receiver.PhoneCallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
In this receiver, I check SYSTEM_ALERT_WINDOW permission by using Settings.canDrawOverlays(context).
When I run this in Android Studio, it works well. However, permission is not checked when built with apk only on Android 13. Returns false even though you have permission. Sometimes, an error occurs when calling addView within Worker even if the permission is correctly confirmed on the broadcast!
"android.view.WindowManager$BadTokenException: Unable to add window
android.view.ViewRootImpl$W#7c33a48 -- permission denied for window
type 2038"
<receiver
android:name=".receiver.MessageReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
When receiving a phone call or text message, WindowManager.addView is called within the same worker, but the view is normally displayed when receiving a text message, and there is no permission when receiving a phone call. For your information, I'm testing with Samsung Galaxy S21.
Is there any solution?
Asking permission when a call is received harms the user experience, but I tested it with reference to Fazle Rabbi's answer. Since the context within the broadcast is not an activity context, a separate activity was created to request permission. (The code has been modified. Check to allow permissions with Settings.canDrawOverlays() instead of comparing with result.resultCode.)
#RequiresApi(Build.VERSION_CODES.R)
class PermissionActivity : AppCompatActivity() {
private val requestOverlayPermission = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (Settings.canDrawOverlays(this)) {
//Permission granted
/*
do something
*/
} else {
//Permission denied
}
finish()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pemission)
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
intent.data = Uri.parse("package:$packageName")
requestOverlayPermission.launch(intent)
}
}
In BroadcastReceiver,
if (!Settings.canDrawOverlays(ctx)) {
val i = Intent(ctx,PermissionActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
ctx.startActivity(i)
return
}
Settings.canDrawOverlays returns false and goes to the Permission Request page whenever BroadcastReceiver is called, even if the app's settings confirm that it has overlay privileges. In addition, permissions are still disabled on the moved overlay permission request page.
It's really weird.
Funny how it's normal when it's running on Android studio. It is well confirmed that there is also permission. This only happens when executed with the built APK On Android 13! The problem seems to occur not only on one particular device, but on most Samsung phones updated with Android 13.
Did I miss anything?
It's an issue only with Android 13 Samsung phones.
I also contacted Samsung about the issue. And they replied:
they have SamsungRestrictOverlayProcessor. and Overlay-related permissions are temporarily disabled during calls for applications that have not been installed through an official store (Play store / Galaxy store) or ADB
so you need to distribute and test your application through proper stores.
I hope this was helpful to you.

Can't get permission BIND_NOTIFICATION_LISTENER_SERVICE for NotificationListenerService

I created an app and added a java class that extend `NotificationListenerService'.
Everything should work fine, but I just can't get to permission BIND_NOTIFICATION_LISTENER_SERVICE.
I added it on the manifest, but when I check for the permission with:
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE)
!= PackageManager.PERMISSION_GRANTED)
{
Log.d(TAG, "permission denied");
}
else
Log.d(TAG, "permission granted");
but I keep getting permission denied. I know that this permission isn't a "dangerous permission" so I don't have to ask for it from the user.
In the manifest I declared this:
<service android:name=".PcNotification"
android:label="PCNotificationService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
and it still doesn't work.
I also implemented the function onListenerConnected but it never called, so it means that my service never gets connected to the notification manager, probably because I don't have the permission BIND_NOTIFICATION_LISTENER_SERVICE
I just want to know how to grant this permission to my app.
I just can't get to permission BIND_NOTIFICATION_LISTENER_SERVICE
You do not need to request that permission. You need to defend your service with that permission. You are doing that in the <service> element via the android:permission attribute.
I know that this permission isn't a "dangerous permission" so I don't have to ask for it from the user.
Then get rid of the code that is requesting it from the user. It is unnecessary, and it will not work.
This should be the literal answer to the original question.
Nevertheless, if you need the method below, you misunderstood the use of such services (as did I). You should not launch your notification listener yourself, you should simply test if your service is running, and if not, then you already know that the permission was not granted, and you can point the user to the preferences panel at android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS.
Add this method to your NotificationListenerClass, and it will return true if the permission is granted, false if not:
public Boolean VerifyNotificationPermission() {
String theList = android.provider.Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
String[] theListList = theList.split(":");
String me = (new ComponentName(this, YourNotificationListenerClass.class)).flattenToString();
for ( String next : theListList ) {
if ( me.equals(next) ) return true;
}
return false;
}
The string "enabled_notification_listeners" seems to be defined under the hood in Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, but I cannot resolve that, so I use the perhaps not so well maintainable literal string. If anyone knows how to get it by its reference, please add it / edit!
This specific permission must be granted manually by the user in android Settings, after that your service will be executed as you bound the permission to your service in AndroidManifest.xml with this:
<service android:name=".PcNotification"
android:label="PCNotificationService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
The problem is that most users won't know where to grant this permission (e.g inside android Settings), so you can open it for them with this:
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
You can run this when the user interacts with your app - e.g clicking a button - and ideally you explain why you need this permission.
I find particularly nice to have a card with the explanation and a button to open the settings so the user can enable.

ContextCompat.checkSelfPermission() returns PERMISSION_DENIED although Permission is granted

I'm trying to get the BIND_NOTIFICATION_LISTENER_SERVICE permission granted by the user.
To do that I'm opening the settings app at the correct spot using:
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
What's kinda weird here already is that the Settings are opened twice(if you press the back button once, the same settings screen opens again)
However, in onResume() I then check if the permission has been granted using:
if(ContextCompat.checkSelfPermission(context,Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE)== PackageManager.PERMISSION_GRANTED){
//open next activity
}
And now here is the issue: It doesn't matter if the user granted the permission in the settings, because checkSelfPermission() always returns PERMISSION_DENIED.
And now it gets really weird: my NotificationListenerService is instantiated, bound and fully working although the permission hasn't been granted according to checkSelfPermission().
How am I supposed to know if the user granted the permission?
Permission and Service declaration in my Manifest:
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
<application>
<service
android:name=".service.NotificationListener"
android:directBootAware="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>
My NotificationListenerService:
public class NotificationListener extends NotificationListenerService {
private static final String TAG = NotificationListener.class.getSimpleName();
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
super.onNotificationPosted(sbn);
Log.d(TAG, "onNotificationPosted: "+sbn.getNotification().tickerText + " ;" + sbn.getPackageName());
}
}
What I already tried:
Different devices and API levels (including emulators) -> Everywhere the same issue
PermissionChecker.checkSelfPermission (I don't know what's the difference compared to ContextCompat.checkSelfPermission(), but it returns the same result)
Android Bug Tracker -> no known issues
According to documentation permission BIND_NOTIFICATION_LISTENER_SERVICE has:
Protection level: signature
This means, that only system applications can have it and use it. Asking for permissions by the way you defined is possible only, when the permission has:
Protection level: dangerous
If your app is not a system app and you have not rooted the device to have the possibility to install custom ROM on it with you custom certificate (your app must be signed with it, too), then you just can't get this permission.

Failed to connect to camera service

I'm trying to access the camera on my phone. I'm writing a simple stub app prior to putting the code in a widget. I'm not getting very far. The code always throws a runtime exception "failed to connect to camera service" The code(pinched from a commonsware example) which goes wrong is:
#Override
public void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
Camera.CameraInfo info = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
// Gets to here OK
camera = Camera.open(i);
} catch (Exception e) {
e.printStackTrace();
// throws runtime exception :"Failed to connect to camera service"
}
}
}
}
}
and my manifest is (corrected 20th Oct):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nbt.cameratest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".CameraTestActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</application>
</manifest>
Can anyone please suggest what might be wrong?
UPDATE 20th Oct
Logcat in SDK 4.0 is broken and wont show the end of the log, so I've cut this bit as best as I can from command line adb logcat:
W/ServiceManager( 2588): Permission failure: android.permission.CAMERA from uid=10136 pid=5744
E/CameraService( 2588): Permission Denial: can't use the camera pid=5744, uid=10136
W/System.err( 5744): java.lang.RuntimeException: Fail to connect to camera service
W/System.err( 5744): at android.hardware.Camera.native_setup(Native Method)
W/System.err( 5744): at android.hardware.Camera.<init>(Camera.java:294)
W/System.err( 5744): at android.hardware.Camera.open(Camera.java:255)
etc..
I don't know why I haven't permission as it is declared in the manifest
Few things:
Why are your use-permissions and use-features tags in your activity tag. Generally, permissions are included as direct children of your <manifest> tag. This could be part of the problem.
According to the android camera open documentation, a runtime exception is thrown:
if connection to the camera service fails (for example, if the camera is in use by another process or device policy manager has disabled the camera)
Have you tried checking if the camera is being used by something else or if your policy manager has some setting where the camera is turned off?
Don't forget the <uses-feature android:name="android.hardware.camera.autofocus" /> for autofocus.
While I'm not sure if any of these will directly help you, I think they're worth investigating if for no other reason than to simply rule out. Due diligence if you will.
EDIT
As mentioned in the comments below, the solution was to move the uses-permissions up to above the application tag.
For newer android versions that support setting permissions per app (since Marshmallow, 6.0) the permission for camera could be disabled and should be enabled from the app settings.
Make sure to call the release() method to release the camera when it is no longer needed, or you will not be able to use the camera. Perhaps as a sanity check, see if your regular camera works. If it says it fails, then your previous attempts at runni
The problem is related to permission. Copy following code into onCreate() method. The issue will get solved.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
}
}
After that wait for the user action and handle his decision.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_PERMISSION_REQUEST_CODE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Start your camera handling here
} else {
AppUtils.showUserMessage("You declined to allow the app to access your camera", this);
}
}
}
I know this question has been answered long time ago, but I would like to add a small thing.
To everyone having the same error, make sure to add this permission in you manifest file:
<uses-permission android:name="android.permission.CAMERA" />
IMPORTANT to use the CAPITAL letters for CAMERA, as I had the permission with small letters and it didn't work.
running your code hundred times may affect the camera to function wrongly.Your activity may be performing correctly but system could not buy it.so camera forces stop.
One main tip all missed is rebooting your phone and not only eclipse..It worked for me..
since this question was asked 4 years back..and i didn't realised that unless mentioned by the Questioner..when there were no Run time permissions support.
but hoping it useful for the users who still caught in this situation..
Have a look at Run Time Permissions ,for me it solved the problem
when i added Run time permissions to grant camera access.
Alternatively you can grant permissions to the app manually by going to your mobile settings=>Apps=>(select your app)=>Permissions section in the appeared window and enable/disable desired permissions.
hope this will work.
I came up with the same problem and I'm sharing how I fixed it. It may help some people.
First, check your Android version. If it is running on Android 6.0 and higher (API level 23+), then you need to :
Declare a permission in the app manifest. Make sure to insert the permission above the application tag.
**<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />**
<application ...>
...
</application>
Then, request that the user approve each permission at runtime
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// here, Permission is not granted
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.CAMERA}, 50);
}
For more information, have a look at the API documentation here
when you use camera.open; and you finish using the camera write this commend camera.release(); this will stop the camera so you can use it again

java.lang.SecurityException trying to read from Android Contacts URI

I am trying to read Contact names, phone #'s, and emails from the ContactsContract URI, and I am getting a SecurityException when I try to run the program. I have set the permission in the AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.smumn.cs394"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
**<uses-permission android:name="android.pemission.READ_CONTACTS"/>**
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".ReadPhoneNumbers"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>`
The following is the application code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_list);
ContentResolver resolver = getContentResolver();
Cursor c = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
//[...] Work through data here`
I get a security exception on the last line (resolver.query()):
`03-08 07:41:40.812: ERROR/AndroidRuntime(416): FATAL EXCEPTION: main
03-08 07:41:40.812: ERROR/AndroidRuntime(416): java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.smumn.cs394/edu.smumn.cs394.ReadPhoneNumbers}: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS
[...]
03-08 07:41:40.812: ERROR/AndroidRuntime(416): Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/contacts from pid=416, uid=10037 requires android.permission.READ_CONTACTS
[...]
03-08 07:41:40.812: ERROR/AndroidRuntime(416): at edu.smumn.cs394.ReadPhoneNumbers.onCreate(ReadPhoneNumbers.java:30)
[...]`
I must be missing something, but I can't figure out what.
Requesting Permissions at Run Time
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
If the permission you need to add isn't listed under the normal permissions, you'll need to deal with "Runtime Permissions". Runtime permissions are permissions that are requested as they are needed while the app is running. These permissions will show a dialog to the user, similar to the following one:
The first step when adding a "Runtime Permission" is to add it to the AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codepath.androidpermissionsdemo" >
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
Next, you'll need to initiate the permission request and handle the result. The following code shows how to do this in the context of an Activity, but this is also possible from within a Fragment.
// MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// In an actual app, you'd want to request a permission when the user performs an action
// that requires that permission.
getPermissionToReadUserContacts();
}
// Identifier for the permission request
private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;
// Called when the user is performing an action which requires the app to read the
// user's contacts
public void getPermissionToReadUserContacts() {
// 1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid
// checking the build version since Context.checkSelfPermission(...) is only available
// in Marshmallow
// 2) Always check for permission (even if permission has already been granted)
// since the user can revoke permissions at any time through Settings
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// The permission is NOT already granted.
// Check if the user has been asked about this permission already and denied
// it. If so, we want to give more explanation about why the permission is needed.
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_CONTACTS)) {
// Show our own UI to explain to the user why we need to read the contacts
// before actually requesting the permission and showing the default UI
}
// Fire off an async request to actually get the permission
// This will show the standard permission request dialog UI
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
READ_CONTACTS_PERMISSIONS_REQUEST);
}
}
// Callback with the request from calling requestPermissions(...)
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
// Make sure it's our original READ_CONTACTS request
if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Make sure you add it outside of the application tag. While developing for a target platform of 2.3.3 using Eclipse on Ubuntu, I had permission failures in the log file that indicated I needed this exact line while working on something similar. It wasn't until I moved the *uses-permission...READ_CONTACTS* line to outside the application tag that things worked.
Hello Steven the debug log trace tells you that you need
... requires android.permission.READ_CONTACTS
so just try something by editing the Manifest.xml like adding another permission, let see if its not correctly readed.
and check this line without **
<uses-permission android:name="android.permission.READ_CONTACTS" />
dan
with the api 23, permission <uses-permission android:name="android.pemission.READ_CONTACTS"/> dont work, change the api level in the emulator for api 22(lollipop) or lower
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
EXAMPLE:
//thisActivity is the running activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// 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(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
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.
}
}
http://developer.android.com/training/permissions/requesting.html

Categories

Resources