Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic error in AndroidManifest.xml for SMS receiving permission

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"/>

like image 350
Richard Green Avatar asked Sep 12 '15 09:09

Richard Green


People also ask

Which permission is required to 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.

What is android permission Get_accounts?

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.


2 Answers

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:

  • right way - request permission at first.
  • lazy way - set targetSdk 22
like image 156
Yazazzello Avatar answered Nov 05 '22 01:11

Yazazzello


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.

like image 29
Dao Duc Duy Avatar answered Nov 05 '22 00:11

Dao Duc Duy