AndroidManifest.xml中有短信接收权限的基本错误

5

我知道这个问题已经被问了很多次,但是我仍然因为这个xml配置而得到权限错误。我已经在其他答案中搜索过了。我正在使用API 23级别。有人能指出我的错误吗?错误很明显:

09-12 09:13:40.016 1295-1309/? W/BroadcastQueue﹕ 权限拒绝: 接收意图 { act=android.provider.Telephony.SMS_RECEIVED flg=0x8000010 (has extras) } 到 com.example.richard.simplesmstoast /.SmsReceiver 需要 android.permission.RECEIVE_SMS,由发送方com.android.phone(uid1001)。

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


请将<uses-permission android:name="android.permission.RECEIVE_SMS"/>标签放置在<application>标签之前。 - Vaibhav Barad
@Vaibhav..尝试过了...我把它放在各种地方:-/ - Richard Green
尝试对您的接收器进行以下更改,如果您正在阅读短信,则可能还想添加以下内容:同时 - Vaibhav Barad
@Vaibhav ... 没有 :-( - Richard Green
@RichardGreen 你试过我的答案了吗? - Yazazzello
2
嘿,我的权限去哪了?:https://commonsware.com/blog/2015/08/31/hey-where-did-my-permission-go.html - CommonsWare
7个回答

17

问题出在Android M (api 23)的新权限模型上:

概览:

  • 如果您的应用程序目标是M预览SDK,则会提示用户在运行时而不是安装时授予权限。
  • 用户可以随时从应用程序设置屏幕中撤销权限。
  • 每次运行时,您的应用程序需要检查它是否具有所需的权限。

对于SMS案例文档,举个例子:

例如,假设某个应用程序在其清单中列出需要SEND_SMS和RECEIVE_SMS权限,这两个权限都属于android.permission-group.SMS。当应用程序需要发送消息时,它请求SEND_SMS权限。系统显示一个对话框,询问用户是否可以访问SMS。如果用户同意,则系统授予应用程序所请求的SEND_SMS权限。稍后,应用程序请求RECEIVE_SMS。由于用户已经批准了同一权限组中的权限,因此系统会自动授予此权限。

解决方案:

  • 正确的方法 - 首先请求权限。
  • 懒惰的方法 - 设置targetSdk为22。

我通常不会在答案上评论+1,但由于开放的赏金,我必须说这是正确的答案。我不确定Android在发布M时如何管理与旧应用程序的兼容性,但长期的解决方案需要在您的代码中添加权限检查。 - Paulo Avelar

5
首先,在AndroidManifest.xml中必须声明RECEIVE_SMS权限。
...
<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>

从API级别23开始,我们需要在运行时请求RECEIVE_SMS权限。这一点很重要。 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
        }
    }
}

希望这能帮到你。

1
首先,这不是一个糟糕的第一篇帖子回答。我想指出的是,发帖者确实正确设置了权限,问题在于API23。无需重复。此外,现在也是将问题标记为重复的绝佳时机。但是,该问题已经在九月份得到了正确的回答,所以可能并不是重复的。无论如何,有人授予了悬赏,所以除非你有什么真正令人兴奋的内容要添加,否则最好放手不管。 - Roy Falk
1
感谢@Roy Falk,当我遇到API23时,这是我的一个坑。花了一段时间四处寻找解决方案,所以我在这里分享,希望能帮助其他人。 - Dao Duc Duy
@DaoDucDuy 完美 - ravi

2

@Richard Green : 您的Logcat信息显示

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

权限是限制对代码或设备上数据的访问的一种约束。这种限制是为了保护重要的数据和代码,防止它们被误用从而影响用户体验。

我认为这是一个权限问题。

请在Application标签之前添加以下Manifest-Permissions

   <uses-permission android:name="INTERNET"/>
   <uses-permission android:name="ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.WRITE_SMS" />
   <uses-permission android:name="android.permission.READ_SMS" />
   <uses-permission android:name="android.permission.RECEIVE_SMS" />

我希望能对你有所帮助。

0
  • 如果您的目标是Marshmallow,则必须除了清单外还要请求运行时权限。

清单 -

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS" />

Java Activity类 -
 final int REQ_CODE = 100;
void requestPermission(){
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
        CTLogs.printLogs( "Permission is not granted, requesting");
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS,Manifest.permission.READ_SMS,Manifest.permission.RECEIVE_SMS}, REQ_CODE);

    } else {
        CTLogs.printLogs("Permission has been granted");
        readSMS();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == REQ_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            CTLogs.printLogs("Permission has been granted");
            readSMS();
        } else {
            CTLogs.printLogs("Permission denied !!!");
        }
    }
}

0

您的权限应该放在应用程序标签之外和之前:

<uses-permission android:name="android.permission.RECEIVE_SMS" />

相当确定我几天前已经尝试过那个了;今晚将在安装有 SDK 的 PC 上重新尝试。 - Richard Green

-1
//Requesting permission
private void requestWritePermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SMS) == PackageManager.PERMISSION_GRANTED)
        return;

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_SMS)) {
        //If the user has denied the permission previously your code will come to this block
        //Here you can explain why you need this permission
        //Explain here why you need this permission
    }
    //And finally ask for the permission
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_SMS}, WRITE_SMS_PERMISSION_CODE);
}

WRTIE_SMS 权限错误


1
请您能否详细说明一下您的答案?现在还不太清楚理解。 - Shashanth

-1

这对我有用... 看看这个,也许能帮到你

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Holo.Light.DarkActionBar" >
    <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="packageName" >
        <intent-filter >

            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>

    </receiver>
</application>


<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />enter code here <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> - khushal rasali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接