Java 为什么 Android 会忽略 READ_SMS 权限?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32814922/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:08:34  来源:igfitidea点击:

Why does Android ignore READ_SMS permission?

javaandroidpermissionssms

提问by michnovka

I am playing with reading inbox under Android API 15 and I am stuck on the following problem:

我正在 Android API 15 下阅读收件箱,但遇到以下问题:

My app has just one activity, main one launched by default. It has this onCreatecode

我的应用程序只有一项活动,主要是默认启动的一项活动。它有这个onCreate代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_unlock);


        // Create Inbox box URI
        Uri inboxURI = Uri.parse("content://sms/inbox");

        // List required columns
        String[] reqCols = new String[] { "_id", "address", "body" };

        // Get Content Resolver object, which will deal with Content Provider
        ContentResolver cr = getContentResolver();

        // Fetch Inbox SMS Message from Built-in Content Provider
        Cursor c = cr.query(inboxURI, reqCols, null, null, null);

    }

Now while this code does nothing useful, just fetches the data and prepares cursor so that I can iterate through them, it causes the following error:

现在虽然这段代码没有任何用处,只是获取数据并准备游标以便我可以遍历它们,但它会导致以下错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cryptail.stealthsms/com.cryptail.stealthsms.UnlockActivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.telephony.SmsProvider uri content://sms/inbox from pid=4362, uid=10059 requires android.permission.READ_SMS, or grantUriPermission()

The error occures on the line with Cursor c = cr.querycode, and urges me to use READ_SMS permission.

错误出现在Cursor c = cr.query代码行上,催我使用READ_SMS权限。

This is my manifest XML

这是我的清单 XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cryptail.stealthsms" >


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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >


        <activity
            android:name=".UnlockActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:naame="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

You can see the permission is included. What may be causing this?

您可以看到权限已包含在内。什么可能导致这种情况?

EDIT 28.9.2015- I did not specify I was working with Android Emulator in Android studio, concretely Android 6.0 (API 23). Under another emulated devices with different Android version (4.4.2) this code works. So maybe a bug in Android 6.0 or in the emulator itself? Are there any changes in A6.0 regarding SMS permissions?

编辑 28.9.2015- 我没有指定我在 Android Studio 中使用 Android Emulator,具体来说是 Android 6.0 (API 23)。在另一个具有不同 Android 版本 (4.4.2) 的模拟设备下,此代码有效。那么也许是 Android 6.0 或模拟器本身的错误?A6.0 在短信权限方面有什么变化吗?

采纳答案by michnovka

So the problem is, as mentioned by TDG, new permission model in Android M.

所以问题是,正如 TDG 提到的,Android M 中的新权限模型。

This articlehelped me to understand the issue in a more clear way than official android doc.

这篇文章帮助我以比官方 android doc更清晰的方式理解了这个问题。

Simply use

只需使用

 if(ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {

before any SMS permission related code is executed, and if the permission is not present, use

在执行任何短信权限相关代码之前,如果权限不存在,请使用

final int REQUEST_CODE_ASK_PERMISSIONS = 123;
ActivityCompat.requestPermissions(UnlockActivity.this, new String[]{"android.permission.READ_SMS"}, REQUEST_CODE_ASK_PERMISSIONS);

回答by Adil Farooq

You can use this code for any permission. Also declare that permission in Manifest file.

您可以将此代码用于任何权限。还要在 Manifest 文件中声明该权限。

/* code in OnCreate() method */ 

if (ContextCompat.checkSelfPermission(context,
                Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED)
        {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.SEND_SMS))
            {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[] {Manifest.permission.SEND_SMS}, 1);
            }
            else
            {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[] {Manifest.permission.SEND_SMS}, 1);
            }

        }
        else
        {
            /* do nothing */
            /* permission is granted */
        }


/* And a method to override */    
@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode)
        {
            case 1:
                if (grantResults.length > 0 &&
                        grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    if (ContextCompat.checkSelfPermission(MainActivity.this,
                            Manifest.permission.SEND_SMS) ==  PackageManager.PERMISSION_GRANTED)
                    {
                        Toast.makeText(context, "Permission granted", Toast.LENGTH_SHORT).show();
                    }
                }
                else
                {
                    Toast.makeText(context, "No Permission granted", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }