My application works fine on Android 5.0 and below, but when I tried to run it on a device with Android 6.0 or higher, I got this error:
Writing exception to parcel
java.lang.SecurityException: No permission to write APN settings
at com.android.providers.telephony.TelephonyProvider.checkPermission(TelephonyProvider.java:4058)
at com.android.providers.telephony.TelephonyProvider.query(TelephonyProvider.java:2724)
at android.content.ContentProvider.query(ContentProvider.java:1058)
at android.content.ContentProvider$Transport.query(ContentProvider.java:245)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
Any help would be appreciated.
Maybe you're not getting permission in runtime. so do this
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_APN_SETTINGS);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
//requesting permission
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_APN_SETTINGS}, 1);
} else {
//permission is granted and you can change APN settings
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//premission granted by user
} else {
//permission denied by user
}
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Related
I'm building my android app with minimum api level 23. My app requires storage(READ/WRITE) and current location permission. When user access has been denied 2 times, then the dialog box is not popping up again.
I want to show the popup again & again instead of sending user to app-info to give permission manually after denying. Is that possible?
My Storage permmision code:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 2: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission granted!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this, "Permission denied!", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
My Location permission code:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "Permission granted!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Permission denied!", Toast.LENGTH_SHORT).show();
}
}
}
No, it's not possible. You should display some popup informing the user that your app requires this permission and then after clicking a positive button you should move the user to the app settings.
The reason for that is after denying permission twice the status is set for "denied forever" and the ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) method will return false.
Some apps force users to give permission by disabling a particular feature of the app. For example, after clicking "show on the map" button just request permission and in case of denial show a popup that the app requires this permission and the user can't open the map view.
While scrolling and jump onto one fragment to another, my logcat shown this error and my app crashed and restart. Please suggest me any solution regarding this?
Add in Manifest.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
In activity page
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
}
Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Do here
} else {
Toast.makeText(mContext, "The app was not allowed to write to your storage.", Toast.LENGTH_LONG).show();
}
}
}
}
For more details, please refer the following link
http://www.theappguruz.com/blog/runtime-permissions-in-android-marshmallow
I'm using permission ACCESS_FINE_LOCATION but when run.error:requires ACCESS_FINE_LOCATION permission
why?
thanks in advance.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION both permission required when to trying to get location
so add this both permission in manifest file as well as if you targeting android 6.0 and above than add this runtime permsiion like below code
String permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
if (ActivityCompat.checkSelfPermission(SearchCityClass.this, permission)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.
checkSelfPermission(SearchCityClass.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SearchCityClass.this, new String[]
{permission}, PERMISSION_GPS_CODE);
}
now handle permisiion result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_GPS_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "location_permission_granted ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "location_permission_not_granted ", Toast.LENGTH_SHORT).show();
}
}
}
Did you write run time permissions in your code? As from Android 6.0, for every permission stated in manifest, must also be asked run time from user.
private void requestLocationPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_CODE);
}
}
Also handle user's response as well:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_CODE: {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
return;
}
}
}
Need to check for the grant of the required permissions(specifically to read user device sms)by the android application user as per android 6 and above standards. I am specifically looking for the ContextCompat.checkSelfPermission() method described on android developer site.
See here:
link
Please follow this tutorials Here is complete source code
static final int PERMISSION_ALL = 1;
String[] PERMISSIONS =
{Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION};
protected void runtimePermission() {
if (!hasPermission(ContactUS.this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
}
public static boolean hasPermission(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_ALL:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted
//your logic here
} else {
//permission denied
}
break;
}
}
you can add run time permission like this
follow this steps
step 1 :- first add this permission in manifiest file
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
now, than
step 2 : ask runtime permission
String permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
if (ActivityCompat.checkSelfPermission(SearchCityClass.this, permission)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.
checkSelfPermission(SearchCityClass.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SearchCityClass.this, new String[]
{permission}, PERMISSION_GPS_CODE);
}
step 3: finallly handle permsiion result in onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_GPS_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, location_permission_granted_msg, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, location_permission_not_granted_msg, Toast.LENGTH_SHORT).show();
}
}
}
if the permission is granted by :
checkSelfPermission(Manifest.permission.READ_CONTACTS)
Request permissions if necessary
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
/* MY_PERMISSIONS_REQUEST_READ_CONTACTS is an app-defined int constant */
return;
}
Handle the permissions request response
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/* permission granted */
} else {
/* permission denied */
}
return;
}
/* check for other permissions */
}
}
Also you can use a library like this, anyway good luck!
I am working with media recorder in my application.When I am asking for permission for Record audio in marshmallow and above versions it is returning me permission granted everytime. Here is my code.
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false;
private String[] permissions = {Manifest.permission.RECORD_AUDIO};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Defined SoundLevelView in main.xml file
setContentView(R.layout.activity_noice_meter);
//check for permission
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted) {
finish();
} else {
//Task to be done when permission is granted
//init();
}
}
Use below code inside onCreate. Here you are not checking whether permission is granted or not.
// 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.RECORD_AUDIO)) {
// 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(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
}
}
Try this,
private Context mContext=YourActivity.this;
private static final int REQUEST = 112;
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.RECORD_AUDIO};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST );
} else {
//do here
}
} else {
//do here
}
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//do here
} else {
Toast.makeText(mContext, "The app was not allowed to record audio", Toast.LENGTH_LONG).show();
}
}
}
}
check permissions for marshmallow
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
Manifest
<uses-permission android:name="android.permission.RECORD_AUDIO" />
New Runtime Permission will work like described only when we set the application's targetSdkVersion to 23. If the application's targetSdkVersion is set to less than 23. It will be assumed that application is not tested with new permission system yet and will switch to the same old behavior: user has to accept every single permission at install time and they will be all granted once installed !
Long story short : Please check yopur target sdkversion first and implement the code as shown by #jitesh mohite