在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中,如下图所示。
系统询问是否始终允许应用获取权限
读取通话记录并展示在ListView中
android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。
作者: 大鸟科创空间, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-3949041.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
文章评论(0条评论)
登录后参与讨论