在Android 中提供了很多系统ContextProvider,通话记录就是其中的一个典型代表。下面我们以读取通话记录为例,展示如何读取系统自带的 ContextProvider 以及动态权限的处理和操作自定义的ContexProvider一样,操作系统的ContextProvider 也是使用ContentResolver 类。本实例中主要是读取通话记录,因此只需调用query()方法,传入URI即可。
为了实现读取通话记录的功能,在 Activiy 对应的布局文件 activity_main.xml 中添加了一个ListView,代码如下∶
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:text="号码" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="26sp"/> <TextView android:text="时间" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="26sp"/> </LinearLayout> <ListView android:id="@+id/call_list" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView></LinearLayout>复制代码同时,实现一个展示条目的布局文件call_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/call_mobile" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="24dp"/> <TextView android:id="@+id/call_date" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:textSize="24dp"/></LinearLayout>复制代码在Activity中获取ListView并将从ContentProvider中读取的数据传入ListView中。在处理过程中实现动态的申请权限,代码如下:
package com.rfstar.contextprovider2;
import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.app.Activity;import android.content.ContentResolver;import android.content.pm.PackageManager;import android.database.Cursor;import android.os.Build;import android.os.Bundle;import android.provider.CallLog;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;public class MainActivity extends AppCompatActivity { private ListView listcalls; private List<Map<String,Object>> mapList; //权限申请的请求码 private static final int REQUEST_CODE=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); onShowCallLog(); } private void initView() { listcalls=(ListView)super.findViewById(R.id.call_list); SimpleAdapter simpleAdapter=new SimpleAdapter(this,mapList,R.layout.call_item,new String[]{CallLog.Calls.NUMBER, CallLog.Calls.DATE}, new int[]{R.id.call_mobile,R.id.call_date}); listcalls.setAdapter(simpleAdapter); } private void initData() { ContentResolver contentResolver=getContentResolver(); //调用query方法,传入URI参数,即CallLog.Calls.CONTENT_URI //本节希望读取电话号码与事件两个字段,传入一个包含字段名的数组 Cursor cursor=contentResolver.query(CallLog.Calls.CONTENT_URI,new String[]{CallLog.Calls.NUMBER,CallLog.Calls.DATE},null, null,null); mapList=new ArrayList<>(); SimpleDateFormat dateFormat=new SimpleDateFormat("yyy-MM-dd"); while(cursor.moveToNext()) { Map<String,Object> map=new HashMap<>(); map.put(CallLog.Calls.NUMBER,cursor.getString(0)); map.put(CallLog.Calls.DATE,dateFormat.format(new Date(cursor.getLong(1)))); mapList.add(map); } } private void onShowCallLog() { if(Build.VERSION.SDK_INT>=23) { int checkCALL_LOGPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG); if(checkCALL_LOGPermission!= PackageManager.PERMISSION_GRANTED){ //用以申请权限的方法,此时使用ActivityCompat类的该方法,以便于版本兼容 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CALL_LOG},REQUEST_CODE); }else { //如果已经获取了相关权限,调用initData()与initview()方法 initData(); initView(); } }else{ //如果api版本低于23,直接调用initData()与initView()方法 initData(); initView(); } } //申请权限做出响应后的回调函数 public void OnRequestPermissionsResult(int requesCode,String[] permission,int[] grantResults) { switch (requesCode) { case REQUEST_CODE: if(grantResults[0]==PackageManager.PERMISSION_GRANTED){ Toast.makeText(this,"获取权限成功",Toast.LENGTH_SHORT).show(); //获取权限成功,调用initData()与initView()方法 initData(); initView(); }else{ Toast.makeText(this,"获取权限失败",Toast.LENGTH_SHORT).show(); //获取权限失败,退出Activity this.finish(); } break; default: super.onRequestPermissionsResult(requesCode,permission,grantResults); } }}复制代码同时,还需要在AndroidManifest.xml中加入一条读取通话记录的用户权限:
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
复制代码此时,运行应用,会提示用户是否授予通话记录的权限,,如果点击“始终允许”,应用就能获取相关的权限,读取通话记录并展示在ListView中,如下图所示。
![](https://static.assets-stash.eet-china.com/album/202109/14/152154r78b5d766uucb7bk.jpg)
系统询问是否始终允许应用获取权限
![](https://static.assets-stash.eet-china.com/album/202109/14/152231iqa69b54zn8n3uz8.png)
读取通话记录并展示在ListView中
android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。
文章评论(0条评论)
登录后参与讨论