原创 Android之读取通话记录实例

2021-9-14 15:25 259 0 分类: 软件与OS 文集: android studio

Android 中提供了很多系统ContextProvider,通话记录就是其中的一个典型代表。下面我们以读取通话记录为例,展示如何读取系统自带的 ContextProvider 以及动态权限的处理和操作自定义的ContexProvider一样,操作系统的ContextProvider 也是使用ContentResolver 类。本实例中主要是读取通话记录,因此只需调用query()方法,传入URI即可。

为了实现读取通话记录的功能,在 Activiy 对应的布局文件 activity_main.xml 中添加了一个ListView,代码如下

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context=".MainActivity">
  8. <LinearLayout
  9. android:layout_width="match_parent"
  10. android:layout_height="50dp"
  11. android:orientation="horizontal">
  12. <TextView
  13. android:text="号码"
  14. android:layout_width="0dp"
  15. android:layout_height="match_parent"
  16. android:layout_weight="1"
  17. android:gravity="center"
  18. android:textSize="26sp"/>
  19. <TextView
  20. android:text="时间"
  21. android:layout_width="0dp"
  22. android:layout_height="match_parent"
  23. android:layout_weight="1"
  24. android:gravity="center"
  25. android:textSize="26sp"/>
  26. </LinearLayout>
  27. <ListView
  28. android:id="@+id/call_list"
  29. android:layout_width="match_parent"
  30. android:layout_height="wrap_content">
  31. </ListView>
  32. </LinearLayout>

同时,实现一个展示条目的布局文件call_item.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal">
  6. <TextView
  7. android:id="@+id/call_mobile"
  8. android:layout_width="0dp"
  9. android:layout_height="match_parent"
  10. android:layout_weight="1"
  11. android:gravity="center"
  12. android:textSize="24dp"/>
  13. <TextView
  14. android:id="@+id/call_date"
  15. android:layout_width="0dp"
  16. android:layout_height="match_parent"
  17. android:layout_weight="1"
  18. android:gravity="center"
  19. android:textSize="24dp"/>
  20. </LinearLayout>

Activity中获取ListView并将从ContentProvider中读取的数据传入ListView中。在处理过程中实现动态的申请权限,代码如下:

  1. package com.rfstar.contextprovider2;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import androidx.core.app.ActivityCompat;
  4. import androidx.core.content.ContextCompat;
  5. import android.Manifest;
  6. import android.app.Activity;
  7. import android.content.ContentResolver;
  8. import android.content.pm.PackageManager;
  9. import android.database.Cursor;
  10. import android.os.Build;
  11. import android.os.Bundle;
  12. import android.provider.CallLog;
  13. import android.widget.ListView;
  14. import android.widget.SimpleAdapter;
  15. import android.widget.Toast;
  16. import java.text.SimpleDateFormat;
  17. import java.util.ArrayList;
  18. import java.util.Date;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. public class MainActivity extends AppCompatActivity {
  23. private ListView listcalls;
  24. private List<Map<String,Object>> mapList;
  25. //权限申请的请求码
  26. private static final int REQUEST_CODE=0;
  27. @Override
  28. protected void onCreate(Bundle savedInstanceState) {
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31. onShowCallLog();
  32. }
  33. private void initView()
  34. {
  35. listcalls=(ListView)super.findViewById(R.id.call_list);
  36. SimpleAdapter simpleAdapter=new SimpleAdapter(this,mapList,R.layout.call_item,new String[]{CallLog.Calls.NUMBER,
  37. CallLog.Calls.DATE}, new int[]{R.id.call_mobile,R.id.call_date});
  38. listcalls.setAdapter(simpleAdapter);
  39. }
  40. private void initData()
  41. {
  42. ContentResolver contentResolver=getContentResolver();
  43. //调用query方法,传入URI参数,即CallLog.Calls.CONTENT_URI
  44. //本节希望读取电话号码与事件两个字段,传入一个包含字段名的数组
  45. Cursor cursor=contentResolver.query(CallLog.Calls.CONTENT_URI,new String[]{CallLog.Calls.NUMBER,CallLog.Calls.DATE},null,
  46. null,null);
  47. mapList=new ArrayList<>();
  48. SimpleDateFormat dateFormat=new SimpleDateFormat("yyy-MM-dd");
  49. while(cursor.moveToNext())
  50. {
  51. Map<String,Object> map=new HashMap<>();
  52. map.put(CallLog.Calls.NUMBER,cursor.getString(0));
  53. map.put(CallLog.Calls.DATE,dateFormat.format(new Date(cursor.getLong(1))));
  54. mapList.add(map);
  55. }
  56. }
  57. private void onShowCallLog() {
  58. if(Build.VERSION.SDK_INT>=23)
  59. {
  60. int checkCALL_LOGPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG);
  61. if(checkCALL_LOGPermission!= PackageManager.PERMISSION_GRANTED){
  62. //用以申请权限的方法,此时使用ActivityCompat类的该方法,以便于版本兼容
  63. ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CALL_LOG},REQUEST_CODE);
  64. }else
  65. {
  66. //如果已经获取了相关权限,调用initData()与initview()方法
  67. initData();
  68. initView();
  69. }
  70. }else{
  71. //如果api版本低于23,直接调用initData()与initView()方法
  72. initData();
  73. initView();
  74. }
  75. }
  76. //申请权限做出响应后的回调函数
  77. public void OnRequestPermissionsResult(int requesCode,String[] permission,int[] grantResults)
  78. {
  79. switch (requesCode)
  80. {
  81. case REQUEST_CODE:
  82. if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
  83. Toast.makeText(this,"获取权限成功",Toast.LENGTH_SHORT).show();
  84. //获取权限成功,调用initData()与initView()方法
  85. initData();
  86. initView();
  87. }else{
  88. Toast.makeText(this,"获取权限失败",Toast.LENGTH_SHORT).show();
  89. //获取权限失败,退出Activity
  90. this.finish();
  91. }
  92. break;
  93. default:
  94. super.onRequestPermissionsResult(requesCode,permission,grantResults);
  95. }
  96. }
  97. }

同时,还需要在AndroidManifest.xml中加入一条读取通话记录的用户权限:

  1. <uses-permission android:name="android.permission.READ_CALL_LOG"/>

此时,运行应用,会提示用户是否授予通话记录的权限,,如果点击“始终允许”,应用就能获取相关的权限,读取通话记录并展示在ListView中,如下图所示。

系统询问是否始终允许应用获取权限

读取通话记录并展示在ListView

android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。



作者: 大鸟科创空间, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-3949041.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论0条评论)

登录后参与讨论
相关推荐阅读
大鸟科创空间 2021-09-27 13:24
Android之Service 介绍
Service(服务)是一个没有用户界面、在后台运行、执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到其他应用场景时,Service 将持续在后台运行。另外,一个组件能够绑...
大鸟科创空间 2021-09-02 15:01
Android之自定义 ContentProvider
在学习了ContentProvider 的几个常用类和如何创建一个内容提供者的方法之后,下面我们用一个实例来进一步加深理解。通过一个完整的实例来展示如何用ContentProvider类进行数据库操作...
大鸟科创空间 2021-08-27 12:30
Android之ContentProvider
在Android开发中,有时用户确实需要在应用之间进行数据的交换。我们知道通过指定文件的操作模式为 Context.MODE_WORLD_READABLE或 Context.MODE_WORLD_WR...
大鸟科创空间 2021-08-13 14:01
Android之SQLite 操作实例
下面通过一个完整的实例来展示如何进行数据库操作。由于实例中使用的方法在上一篇博文中都已经讲述过,因此不再对具体的方法进行分析,主要通过完整的实例让读者有一个宏观的认知实例将通过创建 100条模拟数据,...
大鸟科创空间 2021-07-26 17:01
SQLite操作的核心类 SQLiteDatabase 与 SQLiteOpenHelper
在 Android 中,操作SQLite主要依靠SQLiteDatabase与 SQLiteOpenHelper 这两个类,其中 SQLiteDatabase 是用于执行数据库操作的类,SQLiteO...
广告
我要评论
0
0
1
2
3
4
5
6
7
8
9
0
广告
关闭 热点推荐上一条 /3 下一条