如何获取短信列表 Conversation/Thread?并在 ListView 中显示联系人姓名?

How to Fetch a List of SMS Conversation/Thread? And Display Name Of Contact in ListView?

我正在开发一个 SMS 应用程序,我能够获取 SMS 列表,但我想将它们显示为对话,我是初学者,如何轻松实现它。

MyChatFragment.java;

    public class AwayFragment extends Fragment {
    public AwayFragment() {
    // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.MyChatFragment, container, false);

    // Inflate the layout for this fragment

    int permissioncheck = ContextCompat.checkSelfPermission(getActivity(), 
    Manifest.permission.READ_SMS);
    ListView lv = (ListView) view.findViewById(R.id.listView2);
    final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;

    ArrayList<String> smsList;
    smsList = new ArrayList<>();


    Uri inboxUri = Uri.parse("content://sms/sent/");
    final String[] projection = new String[]{"*"};
    ContentResolver contentResolver = getActivity().getContentResolver();

    Cursor cursor = contentResolver.query(inboxUri, projection, null, null, null);

    if(permissioncheck == PackageManager.PERMISSION_GRANTED){
        ArrayAdapter<String> lva = new ArrayAdapter<String>(
                getActivity(), android.R.layout.simple_list_item_1, smsList);
        lv.setAdapter(lva);
    } else{
        ActivityCompat.requestPermissions(getActivity(), new String[]{ Manifest.permission.READ_SMS}, 
    PERMISSIONS_REQUEST_READ_CONTACTS);
    }
     final String TAG = FetchingInboxActivity.class.getSimpleName();

     while (cursor.moveToNext()) {

        String number = cursor.getString(cursor.getColumnIndexOrThrow("address")).toString();
        String thread_id = cursor.getString(cursor.getColumnIndexOrThrow("thread_id")).toString();
        String body = cursor.getString(cursor.getColumnIndexOrThrow("body")).toString();
        smsList.add("Number: " + number + "\n" + "Body: " + body + "\n" + "Thread_ID: " + thread_id);
        Log.d(TAG, "showcontacts: ");

        final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) 
     view.findViewById(R.id.fragment_away);

        mSwipeRefreshLayout.setOnRefreshListener(
                () -> {
                    ((MainActivity) getActivity()).refreshNow();
                    Toast.makeText(getContext(), "Refresh Layout working", Toast.LENGTH_LONG).show();
                }
        );

    }
    return view;
       }
    }

此外,当我尝试 'content://sms/conversations/' 而不是 'content://sms/' 时,我显示错误

    java.lang.IllegalArgumentException: Invalid column *

正如我在评论中提到的,您应该将光标移动到第一行,然后才能开始阅读。下面的代码在 android 10 中对我有用。我在 if 语句中使用它,因为光标可能为空,所以方法将 return false.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.MyChatFragment, container, false);

    // Inflate the layout for this fragment

    int permissioncheck = ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.READ_SMS);
    ListView lv = (ListView) view.findViewById(R.id.listView2);
    final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;

    ArrayList<String> smsList;
    smsList = new ArrayList<>();


    Uri inboxUri = Uri.parse("content://sms/sent/");
    final String[] projection = new String[]{"*"};
    ContentResolver contentResolver = getActivity().getContentResolver();

    Cursor cursor = contentResolver.query(inboxUri, projection, null, null, null);

    if(permissioncheck == PackageManager.PERMISSION_GRANTED){
        ArrayAdapter<String> lva = new ArrayAdapter<String>(
                getActivity(), android.R.layout.simple_list_item_1, smsList);
        lv.setAdapter(lva);
    } else{
        ActivityCompat.requestPermissions(getActivity(), new String[]{ Manifest.permission.READ_SMS},
                PERMISSIONS_REQUEST_READ_CONTACTS);
    }
    final String TAG = FetchingInboxActivity.class.getSimpleName();

    if (cursor.moveToFirst()) {
        while (cursor.moveToNext()) {

            String number = cursor.getString(cursor.getColumnIndexOrThrow("address"));
            String thread_id = cursor.getString(cursor.getColumnIndexOrThrow("thread_id"));
            String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
            smsList.add("Number: " + number + "\n" + "Body: " + body + "\n" + "Thread_ID: " + thread_id);
            Log.d(TAG, "showcontacts: ");

            final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout)
                    view.findViewById(R.id.fragment_away);

            mSwipeRefreshLayout.setOnRefreshListener(
                    () -> {
                        ((MainActivity) getActivity()).refreshNow();
                        Toast.makeText(getContext(), "Refresh Layout working", Toast.LENGTH_LONG).show();
                    }
            );

        }
    }
    return view;
}

小心,当你对数据库中的一些数据使用toString()时,因为有时它可能是空的,所以null到字符串会抛出异常。