无法在 class 而非 MainActivity 中声明 Cursor

Can't declare Cursor in class not MainActivity

我有 class 控件通过 Cursor 获取短信数据,但是当我在 class MainActivity 中调用 ReadSMS 时出现问题,但我将所有代码从 ReadSMS 复制到 MainActivity 和 运行,会运行正常。

public class ReadSMS extends AppCompatActivity {

public ReadSMS() {
}

public TreeMap getListSMS() {
    ArrayList<SMS> listSMS = new ArrayList<>();
    TreeMap<String, ArrayList<SMS>> tm = new TreeMap();
    Uri smsUri = Uri.parse("content://sms/sent");

    Cursor cur = getContentResolver().query(smsUri, null, null, null, null);
    if (!cur.moveToFirst()) { /* false = cursor is empty */
        return null;
    }

    String temp = "";
    for (int i = 0; i < cur.getCount(); i++) {
        String _id = cur.getString(0);
        String _thread_id = cur.getString(1);
        temp = _thread_id;
        String _address = cur.getString(2);
        String person = getContactName(getApplicationContext(), _address);
        String date = cur.getString(4);
        String date_send = cur.getString(5);
        String protocol = cur.getString(6);
        String read = cur.getString(7);
        String status = cur.getString(8);
        String type = cur.getString(9);
        String reply_path_present = cur.getString(10);
        String subject = cur.getString(11);
        String body = cur.getString(12);
        String service_center = cur.getString(13);
        String locked = cur.getString(14);
        String error_code = cur.getString(15);
        String seen = cur.getString(16);
        long timeDate = Long.valueOf(date);
        date = new SimpleDateFormat("HH:mm yyyy/MM/dd").format(new Date(timeDate));

        SMS sms = new SMS(_id, _thread_id, _address, person, date, date_send, protocol,
                read, status, type, reply_path_present, subject, body, service_center,
                locked, error_code, seen);


        if (!tm.containsKey(sms.get_thread_id())) {
            listSMS.add(sms);
            tm.put(sms.get_thread_id(), listSMS);
        } else {
            listSMS = tm.get(sms.get_thread_id());
            listSMS.add(sms);
            tm.put(sms.get_thread_id(), listSMS);
        }
        listSMS = new ArrayList<>();
        cur.moveToNext();
    }
    cur.close();

    return tm;
}

public String getContactName(Context context, String phoneNumber) {
    ContentResolver cr = context.getContentResolver();
    Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
            Uri.encode(phoneNumber));
    Cursor cursor = cr.query(uri,
            new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
    if (cursor == null) {
        return null;
    }
    String contactName = null;
    if (cursor.moveToFirst()) {
        contactName = cursor.getString(cursor
                .getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
    }
    return contactName;
}

}

它注意到第一个问题:

 Cursor cur = getContentResolver().query(smsUri, null, null, null, null);

更新:Mike M.'下面的答案解决了我的问题

您显然已将 ReadSMS 设为 AppCompatActivity 子 class,以便 getContentResolver() 方法将在您的 IDE 中解析。这是行不通的,因为您可能正在使用 newMainActivity 中创建 ReadSMS 的实例,而您不能使用 Activity,因为它的 Context 将无法正确创建。

如果您想将查询移动到单独的 class,请不要使 class 成为 Activity 的后代。相反,在可以调用 getContentResolver()getListSMS() 方法中传递一个 Context,就像您在 getContactName() 方法中所做的那样。然后,您还可以创建这两个方法 static,因此您无需创建 class 的实例来调用这些方法。

public class ReadSMS {

    public static TreeMap getListSMS(Context context) {
        ...

        Cursor cur = context.getContentResolver().query(smsUri,
                                                        null,
                                                        null,
                                                        null,
                                                        null);
        ...
    }

    public static String getContactName(Context context, String phoneNumber) {
        ...
    }
}

然后,在您的 MainActivity 中,您可以这样称呼它们:

Map messages = ReadSMS.getListSMS(MainActivity.this);

...

String name = ReadSMS.getContactName(MainActivity.this, phoneNumber);