I know that this has been asked a dozen times before, but I still get the permission error with this xml config. I have scoured the other responses on this. I am using API level 23. Can someone please point out the mistake ? The error is the obvious:
09-12 09:13:40.016 1295-1309/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.provider.Telephony.SMS_RECEIVED flg=0x8000010 (has extras) } to com.example.richard.simplesmstoast/.SmsReceiver requires android.permission.RECEIVE_SMS due to sender com.android.phone (uid 1001)
<application
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" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="999" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Sending an SMS message is permission-protected. Your app can't use SMS without the SEND_SMS permission line in AndroidManifest. xml. This permission line enables a setting for the app in the Settings app that gives the user the choice of allowing or disallowing use of SMS.
android.permission.GET_ACCOUNTS. Allows access to the list of accounts in the Accounts Service. The app uses this permission in an effort to find the device user's name when the support session is presented to a representative.
Problem lays in new permissions model for Android M (api 23):
Quickview
- If your app targets the M Preview SDK, it prompts users to grant permissions at runtime, instead of install time.
- Users can revoke permissions at any time from the app Settings screen.
- Your app needs to check that it has the permissions it needs every time it runs.
for SMS case documentation bring an example:
For example, suppose an app lists in its manifest that it needs the SEND_SMS and RECEIVE_SMS permissions, which both belong to android.permission-group.SMS. When the app needs to send a message, it requests the SEND_SMS permission. The system shows the user a dialog box asking if the app can have access to SMS. If the user agrees, the system grants the app the SEND_SMS permission it requested. Later, the app requests RECEIVE_SMS. The system automatically grants this permission, since the user had already approved a permission in the same permission group.
Solutions:
First, RECEIVE_SMS permission must be declared in AndroidManifest.xml.
...
<uses-permission android:name="android.permission.RECEIVE_SMS" />
...
<receiver
android:name=".receiver.IncomingSmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Then, from API level 23, we need to request RECEIVE_SMS permission at run time. This is important to notice. https://developer.android.com/training/permissions/requesting.html
public class MainActivity extends AppCompatActivity {
private static final int PERMISSIONS_REQUEST_RECEIVE_SMS = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Request the permission immediately here for the first time run
requestPermissions(Manifest.permission.RECEIVE_SMS, PERMISSIONS_REQUEST_RECEIVE_SMS);
}
private void requestPermissions(String permission, int requestCode) {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
// 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.
Toast.makeText(this, "Granting permission is necessary!", Toast.LENGTH_LONG).show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{permission},
requestCode);
// requestCode is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_RECEIVE_SMS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
NotificationUtil.getInstance().show(this, NotificationUtil.CONTENT_TYPE.INFO,
getResources().getString(R.string.app_name),
"Permission granted!");
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
NotificationUtil.getInstance().show(this, NotificationUtil.CONTENT_TYPE.ERROR,
getResources().getString(R.string.app_name),
"Permission denied! App will not function correctly");
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
}
Hope this help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With