My Android app needs to request permission for location services. I do this with:
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_CODE_ACCESS_COARSE_LOCATION);
But immediately after this is called, onRequestPermissionsResult returns immediately with permission denied:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ACCESS_COARSE_LOCATION: {
}
}
}
The permission is listed in the manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
I also cleared the cache to prevent any previous denial the user gave from affecting this.
I am expecting a dialog to pop up requesting the user to grant or deny permission to the location services but it isn't showing.
Change:
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION"/>
to:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
The permission is for "coarse" location data (i.e., not fine-grained), not "course" location data (e.g., where some university class is being held).
private int PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 100;
private void checkPermission() {
if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(newString[{Manfest.permission.ACCESS_COARSE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
} else {
doShowLocation();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showContacts();
}
}
One more scenario that onRequestPermissionsResult can return denied permission even before permission dialog appears is when you declared some other permission in android manifest and asking some other permission in run time. Example:
You have declared
<uses-permission android:name="android.permission.READ_SMS" />
in android manifest file. However you are trying to get
Manifest.permission.SEND_SMS
in runtime permission. So making the runtime permission to READ_SMS will work without any issues.
Related
I was trying to add a segment to my Android application, which would gather information about the device (like the serial number for example) and use it for digital signing of data, later on.
I was planning on using the output of the getprop function, paired with adequate parameters, for instance getprop ro.serialno.
Googling this issue had me on a path of enabling proper permissions, for this to work.
I am having issues with enabling the READ_PHONE_STATE permission on my device. Adding it to the AndroidManifest.xml file does absolutely nothing. After I reused an already working piece of code to request the user's permission after launching, my app started crashing.
App crashes with:
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.strujomeri, PID: 17563
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.strujomeri/com.strujomeri.MainActivity}: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
All permissions from AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Code that requests permission. Works for other permission but only crashes here:
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_PHONE_STATE},
STATE_REQUEST);
if (requestCode == STATE_REQUEST) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "State request granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "State request granted", Toast.LENGTH_SHORT).show();
}
}
EDIT: This is the error message I get when trying to read the serial number of the phone:
E/libc: Access denied finding property "ro.serialno"
Any ideas on how to get this type of information ? Other methods besides getprop can be useful as well. Thank you
I was looking to enable the READ_PHONE_STATE permission on my Android device, which I need for executing some system calls in my code, but I am experiencing a blockade in enabling this permission and suspect that there is theory underneath this issue which I don't already know.
seem you are edited your code before show here.
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
Problem cause is your permission array.
To easy check permission :
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
#AfterPermissionGranted(RC_PHONE)
private void methodRequiresTwoPermission() {
String[] perms = {Manifest.permission.READ_PHONE_STATE , Any more permission in your manifest};
if (EasyPermissions.hasPermissions(this, perms)) {
// Already have permission, do the thing
// ...
} else {
// Do not have permissions, request
}
}
if you don't want the lib above
prive boolean checkPermission(String [] perms){
for(String perm : perms){
if(ActivityCompat.checkSelfPermission(getApplicationContext(),perm) !=PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
-use
if (!checkPerms(new String[]{
// //your permissions in manifest
})){
requestPermissions(new String[]{
//your permissions in manifest
}, REQUEST_CODE);
}
I need to open a pdf using a uri.
I have the code in place to open the pdf.
My code works fine on Api greater than 23.
I get the following SecurityException when I try to download the file on a Samsung Galaxy device with Api 23 and version 6.
Here is the exception:
01-25 19:28:38.723 6655-6667/android.process.media E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/Canto Quick Start Guide.pdf: Neither user 10022 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
at android.app.ContextImpl.enforce(ContextImpl.java:1438)
at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1470)
at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:675)
at com.android.providers.downloads.DownloadProvider.checkFileUriDestination(DownloadProvider.java:724)
at com.android.providers.downloads.DownloadProvider.insert(DownloadProvider.java:558)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:263)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:163)
at android.os.Binder.execTransact(Binder.java:507)
I have setup the required permission in manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I have the following check in place to test if the user does not have WRITE_EXTERNAL_STORAGE permission then ask the user for granting access.
int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 2;
// Check whether this app has write external storage permission or not.
int writeExternalStoragePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If do not grant write external storage permission.
if (writeExternalStoragePermission != PackageManager.PERMISSION_GRANTED) {
// Request user to grant write external storage permission.
((MainActivity)activity).getSharedPreferenceManager().add(PreferenceConstants.SHAREPOINT_FILE_URI, getUrl((SharepointFile) object, activity));
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getUrl((SharepointFile) object, activity)));
intent.setDataAndType(Uri.parse(getUrl((SharepointFile) object, activity)), "application/pdf");
activity.startActivity(intent);
}
I override the onRequestPermissionResult in MainActivity.java so that as soon as the user grants permission then the download can be initiated.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
String fileUri = getSharedPreferenceManager().get(PreferenceConstants.SHAREPOINT_FILE_URI);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fileUri));
startActivity(intent);
} else {
getSharedPreferenceManager().remove(PreferenceConstants.SHAREPOINT_FILE_URI);
}
break;
}
}
I have the code to ask the user for permission. I do get the dialog/alert to allow access. Once the user clicks allow, I see that it still gives the above exception. I went in settings to check my app's permission and see that it is turned "on" for storage. Why would I still get permission issue? Any pointers on what I could be missing here? Appreciate your help!
It is just an assumption but i see you have declared both
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
But docs says:
Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this (READ_EXTERNAL_STORAGE) permission.
Try to remove
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I'm trying to check permission in activity as below,
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNT);
But I'm getting error at GET_ACCOUNT as Cannot resolve symbol 'GET_ACCOUNT'.
Kindly help what code should I add to fix this?
Thanks in advance.
It should be
Manifest.permission.GET_ACCOUNTS
instead of
Manifest.permission.GET_ACCOUNT
Try like this
int permission = ContextCompat.checkSelfPermission(this,Manifest.permission.GET_ACCOUNTS);
Don't forget to add permission on your Manifest
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
Import this library in your class
import android.Manifest;
First GET_ACCOUNT is not defined in android.Manifest.permission, it is GET_ACCOUNTS
Second, change your Manifest file to use GET_ACCOUNTS
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
then in your code file i.e. java file write like this.
ContextCompat.checkSelfPermission(this, android.Manifest.permission.GET_ACCOUNTS);
Check documentation GET_ACCOUTNS.
The following code worked for me,
Declare below code as:
public static final int PERMISSIONS_REQUEST_GET_ACCOUNT = 133; // any number
Call following code in your onCreate method:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(ContextCompat.checkSelfPermission(Activity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(SplashActivity.this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.GET_ACCOUNTS},
PERMISSIONS_REQUEST_GET_ACCOUNT);
}else{
//furtherCode
}
}else{
//furtherCode
}
in method onRequestPermissionsResult method,
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode){
case PERMISSIONS_REQUEST_GET_ACCOUNT :
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "No such permission to access account!", Toast.LENGTH_SHORT).show();
}
break;
}
}
Here is my manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
This is all I needed for my project but I need it in code, not manually in app settings.
To use the new permission model in Marshmallow, you need to both specify your permissions in the manifest (as you did) AND request the permission at runtime. Only permissions that are considered as "dangerous" require the runtime request. Dangerous is defined as:
A higher-risk permission that would give a requesting application
access to private user data or control over the device that can
negatively impact the user. Because this type of permission introduces
potential risk, the system may not automatically grant it to the
requesting application. For example, any dangerous permissions
requested by an application may be displayed to the user and require
confirmation before proceeding, or some other approach may be taken to
avoid the user automatically allowing the use of such facilities.
From: https://developer.android.com/guide/topics/manifest/permission-element.html
Here's an example of code that checks if you need to request the permission. (Remember, even if the user grants your permission request, they can later revoke it in App Settings, so you need to check each time you need it.)
private final int REQUEST_PERMISSION_ACCESS_FINE_LOCATION=1;
private void requestAccessLocationPermission() {
int permissionCheck = ContextCompat.checkSelfPermission(
this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
showExplanation("Permission Needed", "Rationale", Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_PERMISSION_ACCESS_FINE_LOCATION);
} else {
requestPermission(Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_PERMISSION_ACCESS_FINE_LOCATION);
}
} else {
Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRequestPermissionsResult(
int requestCode,
String permissions[],
int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSION_ACCESS_FINE_LOCATION:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
I am trying to call getCallCapablePhoneAccounts() method of android.telecom.TelecomManager class. Though i have added required user-permission, i am getting Security exception.
Here is the line of code where i am getting exception
List<PhoneAccountHandle> list = getTelecomManager().getCallCapablePhoneAccounts();
user permission added in manifest
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Exception stacktrace
Caused by: java.lang.SecurityException: getDefaultOutgoingPhoneAccount: Neither user 10102 nor current process
has android.permission.READ_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at com.android.internal.telecom.ITelecomService$Stub$Proxy.getDefaultOutgoingPhoneAccount(ITelecomService.java:615)
at android.telecom.TelecomManager.getDefaultOutgoingPhoneAccount(TelecomManager.java:439)
On Android >=6.0, We have to request permission runtime.
Step1: add in AndroidManifest.xml file
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Step2: Request permission.
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
} else {
//TODO
}
Step3: Handle callback when you request permission.
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_READ_PHONE_STATE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
//TODO
}
break;
default:
break;
}
}
Edit:
Read official guide here Requesting Permissions at Run Time
Are you running Android M? If so, this is because it's not enough to declare permissions in the manifest. For some permissions, you have to explicitly ask user in the runtime: http://developer.android.com/training/permissions/requesting.html
I was experiencing this problem on Samsung devices (fine on others). like zyamys suggested in his/her comment, I added the manifest.permission line but in addition to rather than instead of the original line, so:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.Manifest.permission.READ_PHONE_STATE" />
I'm targeting API 22, so don't need to explicitly ask for permissions.