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
Why does Android ignore READ_SMS permission?
提问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 onCreate
code
我的应用程序只有一项活动,主要是默认启动的一项活动。它有这个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.query
code, 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;
}
}