Kotlin: App not asking user for permissions - android

I am creating an Android application that reads a user's SMS messages. I first check whether the user has granted permission for me to read the SMS messages with the if conditional. I have verified that my test phone has not granted access to the app to read the SMS messages, as the print statement is executed. However, the requestPermissions method is not triggered (there is no popup asking to grant permission to read the SMS messages). I suspect I might be using the wrong permission code or the wrong method to begin with. I have included the following permission in my Manifest.xml file:
<uses-permission android:name="android.permission.SEND_SMS"/>
Below is my Kotlin code:
// See if the user has not granted permission to read his or her text messages
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED) {
// Request the user to grant permission to read SMS messages
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_SMS), 2);
System.out.println("Permission Denied")
}

In AndroidManifest.xml add READ_SMS
permission.
Use
<uses-permission android:name="android.permission.READ_SMS"/>
Instead of
<uses-permission android:name="android.permission.SEND_SMS"/>

As it is mentioned in comments, You have declared SEND_SMS permission in Manifest.xml file and requesting READ_SMS permission dynamically(runtime).
Also it is not recommended to use this permission unless app acts as default messaging app. Please go through documentation Manifest.permission.READ_SMS which states following
This is a hard restricted permission which cannot be held by an app
until the installer on record whitelists the permission. For more
details see
PackageInstaller.SessionParams.setWhitelistedRestrictedPermissions(Set)

Related

Permission not asked

I'd like to know why my permission are not asked when I'm launching my app, here's my manifest permissions :
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
And when I go through the param of my phone, I only have the "position" permission (and it's disabled).
If by permission not asked you mean that the user isn't being prompted to allow internet permission then that is normal. Internet is in the normal permissions list so it is auto granted. For more information about normal permissions take a look at: https://developer.android.com/guide/topics/permissions/normal-permissions.html
Also, adding permissions is a two step process; once you have declared the permission you need in your manifest, you will also have to do some setup in your java file. Take a look at https://developer.android.com/training/permissions/requesting
Additionally, if you are looking for easier ways to deal with permissions then there are libraries out there for that too such as RxPermissions: https://github.com/tbruyelle/RxPermissions
Hopefully this helps!
You should ask for a Runtime Permission
Please see the documentation:
Request App Permissions
If you are targeting SDK 26+, then you need to check for permissions in code like this:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation 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,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_PERMISSIONS_ACCESS_FINE_LOCATION)
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
// Permission has already been granted - or running on old Android
}
It is described in Request App Permissions
for marshmallow(API 23) and above you should get permission for location, phone states and other dangerous permissions not only in your manifest but in your code (Run Time Permission).for other permissions, manifest is enough.
see this video
also you can find your solution in this Q&A

Android 6 (23) - no permission requested

I stucked on new permission model in the Android 6.
I defined following permissions in the manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application...
But if i launched the app in the emulator and opened the app detail i saw the following :
It says that app does not require any permission.
How can i solve it please?
Many thanks for any advice.
It says that app does not require any permission.
That is correct. That portion of your app's page lists dangerous permissions. None of yours have a protectionLevel of dangerous.
How can i solve it please?
There is nothing wrong, and so there is nothing to solve.
Until Android 6.0, There are some permissions that will be automatically granted at install time and will not be able to revoke. We call it Normal Permission (PROTECTION_NORMAL). Here is the full list of them:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
Just simply declare those permissions in AndroidManifest.xml and it will work just fine. No need to check for the permission listed above since it couldn't be revoked.
as #Saini said, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
But if you choose targetSdkVersion lower than 23, your application will be treated like before and will ask user to grant permission to the app when they want to install application. you could read more from here
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
For more info: https://developer.android.com/training/permissions/requesting.html
https://developer.android.com/training/permissions/declaring.html
https://developer.android.com/training/permissions/best-practices.html
// Here, thisActivity is the current 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.
}
}
In addition to https://stackoverflow.com/a/42697645/984471
Here is the protection_normal permissions link:
https://developer.android.com/guide/topics/permissions/overview#normal_permissions
And the comparison between old and new, normals

Marshmallow FINE and COARSE location permission

I'm trying to access ACCESS_FINE_LOCATION and if it cannot be found access ACCESS_COARSE_LOCATION. So I request for those 2 permission, but they give me the same dialog asking for location permission. I know those are both in the same group but Google says:
Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.
This means I ask for those 2 permissions within a second, which results in 2 dialog in a row. THis does not seem very user friendly to me. Is there a better way?
You do not need ACCESS_COARSE_LOCATION permission when you define ACCESS_FINE_LOCATION permission.
From Android Documentation:
Requesting User Permissions
In order to receive location updates from NETWORK_PROVIDER or
GPS_PROVIDER, you must request user permission by declaring either the
ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission,
respectively, in your Android manifest file. For example:
<manifest>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
.......
</manifest>
Without these permissions, your application will fail at runtime when
requesting location updates.
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then
you need to request only the ACCESS_FINE_LOCATION permission, because
it includes permission for both providers. (Permission for
ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.)
Please look at https://developer.android.com/guide/topics/location/strategies.html
I have resolved the same problem.Try to give it runtime permission and Firstly check the manifest SDK version and if your version is greater than 6.0 or equal to 6.0 then you need to check permissions for your permission and pass permission Fine location only in request location then definitely it will work.
if you got stuck in code then you may ask for code I will update you but firstly go through these steps.
if you got success to perform your task then rate it.

Android Program request permissions

I am trying to use GPS in android but it gives me this error:
I put in manifest these permission
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
can anyone help me please
As the hint suggests : The user may deny permission. In that case this call will throw error...
Right now, android asks for the user to accept all the permissions an app asks for in the manifest on installation. In the upcoming M release, android will switch over to the iOS style of permissions with an "on needed" basis.
Call this method to see if permission is granted or not. If not, you need to handle that situation.
context.checkCallingPermission(permission)
Declaring permission in manifest only means that you are requesting permission. In new releases it will not guarantee that user will give you that permission.
In older releases the user has to accept all or reject all permissions
This is not an error actually but a heads-up by the Lint and which may cause an issue!
Hope you are aware about the new permission model is introduced in Android 6.0 (Marshmallow), through which user may not permit to use GPS or Network or anything else and so it may cause an issue in your application!
Now, as per the lint analysis, so before implementing particular functionality, you should check whether permission for the same is available or not!
Since SDK 23, you should/need to check the permission using checkSelfPermission
http://developer.android.com/reference/android/support/v4/content/ContextCompat.html
for example
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
This condition checks user allowed to access the permission to read the location
if(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED||checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER,meter,mill,new locationlist(this));
}

MarshMallow Permission for gmaps

If gmaps needs this permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
should I ask for each one to the user with requestPermissions ?
I checked some times and it only crash saying that the user didnt give permissions for android.permission.ACCESS_FINE_LOCATIONbut not the others, why?
should I ask for each one to the user with requestPermissions ?
First when to use requestPermission ?
requestPermission is only call after checkSelfPermission when this method doesn't return PERMISSION_GRANTED.
You can find a list of permission that android M requires during the runtime. Each of these Permissions are part of a Permission group. WRITE_EXTERNAL_PERMISSION is from android.permission-group.STORAGE and ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION are from android.permission-group.LOCATION.
If the user allows the access to a permission -for example ACCESS_COARSE_LOCATION-, then android will automatically grant the access of this permission group -i.e. permission-group.LOCATION-. So if you later checkSelfPermission for ACCESS_FINE_LOCATION, you should receive PackageManager.PERMISSION_GRANTED.
If you app crashes, it means that you tried to call, for example LocationServices.FusedLocationApi.requestLocationUpdates before requesting from the user the permission-group Location.
Edit:
Do not forget that requestPermission is asynchronous. So do not call a method that requires a permission right after requestPermission. To call a method that requires a permission, you should override onRequestPermissionsResult that give you a list of permission and their state -granted/denied-.
You should only need to request permission for the LOCATION and STORAGE groups. I'm also pretty sure Fine location includes permission for Coarse, so you don't need to include that line in your manifest.

Categories

Resources