【问题标题】:ContentResolver.query() Security Exception While Accessing ContactsContentResolver.query() 访问联系人时出现安全异常
【发布时间】:2013-07-15 17:19:03
【问题描述】:

我有以下 Java 代码,用于根据特定 thread_id 访问参与对话的所有联系人。 UPDATE 此代码位于应用程序导入的库中。 完成更新

private ArrayList<Contact> getContactsFromThreadId(long threadId) {
    ArrayList<Contact> contacts = new ArrayList<Contact>();

    /** TODO set up projection this is inefficient */
    Cursor allCursor = mContext.getContentResolver().query(SMS_INBOX, null, null, null, null);
    String [] info = new String[allCursor.getColumnCount()];
    for( int i = 0; i < allCursor.getColumnCount(); i++) {
        info[i] = allCursor.getColumnName(i);
    }

    Cursor cursor = mContext.getContentResolver().query(SMS_INBOX, info, THREAD_ID + threadId, null, SORT_ORDER);
    if (cursor != null) {
        try {
            if (cursor.moveToFirst()) {
                do {
                    long id = cursor.getLong(0);
                    String[] projection = {Phone.NUMBER, ContactsContract.PhoneLookup.DISPLAY_NAME}; 
                    Cursor contactCursor = mContext.getContentResolver().query(PHONE_CONTACTS, projection, USER_ID + id, null, null);
                    String number = "";
                    String name = "";
                    if (contactCursor.moveToFirst()) {
                        int numberColumn = contactCursor.getColumnIndex(projection[0]);
                        number = contactCursor.getString(numberColumn);
                        int nameColumn = contactCursor.getColumnIndex(projection[1]);
                        name = contactCursor.getString(nameColumn);
                    }
                    contacts.add(new Contact(id, number, name));
                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        cursor.close();
    }

    return contacts;
}

运行上面的代码时,我从以下行捕获了一个 SecurityException:

// private final Uri PHONE_CONTACTS = Uri.parse("content://contacts");
Cursor contactCursor = mContext.getContentResolver().query(PHONE_CONTACTS, projection, USER_ID + id, null, null);

堆栈跟踪报告:

07-15 10:11:00.468: W/System.err(20527): java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://contacts from pid=20527, uid=10140 requires android.permission.READ_CONTACTS

所以我在主要活动声明之外的主要清单文件中添加了以下内容:

<!-- I ADDED THIS LINE -->
<uses-permission android:name="android.permission.READ_CONCACTS" />

更新

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="17" />

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

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

【问题讨论】:

  • 您是否也添加了“READ_EXTERNAL_STORAGE”权限?
  • @Jade Byfield 不,我没有,让我试试看是否能解决问题。我已经添加了它,但我仍然收到安全异常。
  • 另外,Application 标签内的 uses-permission 行是吗?
  • 不,不是。我将在上面发布相关部分,看看我缺少什么。

标签: android android-contacts android-permissions


【解决方案1】:

你有一个错字。

&lt;uses-permission android:name="android.permission.READ_CONCACTS" /&gt;

应该是

&lt;uses-permission android:name="android.permission.READ_CONTACTS" /&gt;

【讨论】:

    【解决方案2】:

    尝试更改 android:targetSdkVersion="14" 或低于 16

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="14" />
    

    【讨论】:

      【解决方案3】:

      解决问题的方法是改变:

      private final Uri PHONE_CONTACTS = Uri.parse("content://contacts");
      

      收件人:

      private final Uri PHONE_CONTACTS = CommonDataKinds.Phone.CONTENT_URI;
      

      查询来自:

      Cursor contactCursor = mContext.getContentResolver().query(PHONE_CONTACTS, projection, USER_ID + id, null, null);
      

      收件人:

      Cursor contactCursor = mContext.getContentResolver().query(PHONE_CONTACTS, null, CommonDataKinds.Phone.CONTACT_ID +" = "+id, null, SORT_ORDER);
      

      并按照 Karakuri 的建议更改我的清单文件中的错字。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-05
        • 2012-06-12
        • 2015-05-20
        • 1970-01-01
        相关资源
        最近更新 更多