【问题标题】:How to Fetch a List of SMS Conversation/Thread? And Display Name Of Contact in ListView?如何获取 SMS 对话/线程列表?并在 ListView 中显示联系人姓名?
【发布时间】:2021-01-12 12:13:13
【问题描述】:

我正在开发一个 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 *

【问题讨论】:

  • @UsamaAltaf ,感谢您为我办理入住,但他的情况与我的情况不同,他正在尝试获取特定联系人的消息,例如:i.stack.imgur.com/ShnuX.jpg,但我正在尝试获取列表所有人的名字和他们最近的消息
  • ContentProvider 不接受 * 字符来获取所有列。改为传递 null ,它将起作用。 nullquery() 中作为projection,不像字符串数组项。并记住将光标移动到第一行,默认情况下它在最后一行。
  • @grabarz121,所以当我将 null 作为投影时,我在“列“正文”和“地址”不存在”上遇到错误
  • 在使用cursor.moveToNext()之前添加cursor.moveToFirst()

标签: java android listview sms android-contentresolver


【解决方案1】:

正如我在评论中提到的,在开始阅读之前,您应该将光标移动到第一行。下面的代码适用于我在 android 10 中。我在 if 语句中使用它,因为光标可能为空,所以方法将返回 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() 时,因为有时它可能为空,所以空字符串会引发异常。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-03-02
  • 2020-04-04
  • 2012-09-09
  • 2013-01-09
  • 2016-05-07
  • 2012-10-11
  • 1970-01-01
相关资源
最近更新 更多