Android API 15で受信トレイを読んで遊んでいますが、次の問題が発生します。
私のアプリにはアクティビティが1つだけあり、メインのアクティビティはデフォルトで起動されます。この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);
}
このコードは何の役にも立ちませんが、データをフェッチしてカーソルを準備するだけで、データを反復処理できますが、次のエラーが発生します。
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()
エラーはCursor c = cr.query
コードの行で発生し、READ_SMS権限を使用するように促します。
これは私のマニフェスト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>
許可が含まれていることがわかります。何が原因でしょうか?
EDIT 28.9.2015 -AndroidスタジオでAndroidエミュレーター、具体的にはAndroid 6.0(API 23 )。異なるAndroidバージョン(4.4.2)の別のエミュレートされたデバイスでは、このコードは機能します。では、Android 6.0またはエミュレータ自体のバグでしょうか? SMS権限に関してA6.0に変更はありますか?
したがって、問題は、TDGが述べたように、Android Mの新しい権限モデルです。
この記事 問題をより明確に理解するのに役立ちました 公式Androidドキュメント 。
単に使用する
if(ContextCompat.checkSelfPermission(getBaseContext(), "Android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {
SMSパーミッション関連のコードが実行される前、パーミッションが存在しない場合は、
final int REQUEST_CODE_ASK_PERMISSIONS = 123;
ActivityCompat.requestPermissions(UnlockActivity.this, new String[]{"Android.permission.READ_SMS"}, REQUEST_CODE_ASK_PERMISSIONS);
このコードは、任意の権限に使用できます。また、マニフェストファイルでその権限を宣言します。
/* 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;
}
}