1.ContentProvider简介
客户端操作contentResolver和操作ContentProvider是 一样的
Uri的辅助操作类ContentUris
2.ContentProvider数据库操作
项目类结构
1、创建元数据MetaData
2、定义一个SQLiteOpenHelper类的子类,用于创建和删除member表
3、
先放弃一下下
3.利用ContentProvider访问联系人
1、创建动态访问联系人权限(或许可以省略)
创建 PermisionUtils 类
public class PermisionUtils {
private static final int REQUEST_READ_CONTACTS = 1;
private static String[] PERMISSIONS_CONTACTS = {
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS};
public static void verifyContactsPermissions(Activity activity) {//检查权限
int permission = ActivityCompat.checkSelfPermission(activity,
Manifest.permission.WRITE_CONTACTS);
if (permission != PackageManager.PERMISSION_GRANTED) {//无权限
ActivityCompat.requestPermissions(activity, PERMISSIONS_CONTACTS,
REQUEST_READ_CONTACTS);//动态赋权
}
}
}
2、创建listview布局页面contacts.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/_id"
android:layout_marginLeft="10dp"
android:textSize="14sp"
android:layout_width="30sp"
android:layout_height="35dp"/>
<TextView
android:id="@+id/name"
android:text="联系人"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="35dp"/>
</LinearLayout>
3、Manifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fengray.myex004contactperson">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
</manifest>
4、主布局页面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手机联系人列表" />
<ListView
android:id="@+id/contactsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
5、activity页面
public class MainActivity extends AppCompatActivity {
private ListView contactsList=null;
private List<Map<String,Object>> allContacts=null;
private SimpleAdapter simpleadpter=null;
private Cursor result=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//PermisionUtils.verifyContactsPermissions(this);
contactsList=findViewById(R.id.contactsList);
//查询
result=getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);
//将结果集交给容器管理
startManagingCursor(result);
//实例化List集合
allContacts=new ArrayList<Map<String, Object>>();
//循环读取结果集中的数据并put到map中,最后添加到list表中
for (result.moveToFirst();!result.isAfterLast();result.moveToNext()){
Map<String,Object> map=new HashMap<String,Object>();
//以上取出结果集中的每一个内容
map.put("_id",result.getInt(result.getColumnIndex(ContactsContract.Contacts._ID)));
map.put("name",result.getString(result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
allContacts.add(map);
}
//创建adapter
simpleadpter=new SimpleAdapter(this,allContacts,R.layout.contacts,new String[]{"_id","name"},new int[]{R.id._id,R.id.name});
contactsList.setAdapter(simpleadpter);//设置adpate
registerForContextMenu(this.contactsList);
}
//创建操作上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
//super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("操作");
menu.add(menu.NONE, Menu.FIRST+1,1,"查看信息");
menu.add(menu.NONE, Menu.FIRST+2,1,"删除信息");
}
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
AdapterView.AdapterContextMenuInfo info= (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position=info.position;//取得上下文操作菜单的位置
String contactsID=allContacts.get(position).get("_id").toString();
switch (item.getItemId()){
case Menu.FIRST+1:
String phoneSelection= ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=?";
String [] phoneSelectionArgs=new String[]{contactsID};
Cursor cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
phoneSelection,phoneSelectionArgs,null);
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append("电话号码:");
for (cursor.moveToFirst(); !cursor.isAfterLast();cursor.moveToNext()){
stringBuffer.append(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
Toast.makeText(this, stringBuffer, Toast.LENGTH_SHORT).show();
break;
case Menu.FIRST+2:
getContentResolver().delete(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI,contactsID),null,null);
allContacts.remove(position);//输出集合数据项
simpleadpter.notifyDataSetChanged();//通知改变
Toast.makeText(this, "数据已删除", Toast.LENGTH_SHORT).show();
break;
}
return super.onContextItemSelected(item);
}
}
结果:
4.利用ContentProvider访问通话记录
1、创建动态访问联系人通话CALL_LOG权限(或许可以省略)
创建PermisionUtils 类
首次执行被询问
public class PermisionUtils {
private static final int REQUEST_CALLLOG = 1;
private static String[] PERMISSIONS_CALLLOG = {
Manifest.permission.READ_CALL_LOG,
Manifest.permission.WRITE_CALL_LOG};
public static void verifyCallLogPermissions(Activity activity) {//检查权限
int permission = ActivityCompat.checkSelfPermission(activity,
Manifest.permission.WRITE_CALL_LOG);
if (permission != PackageManager.PERMISSION_GRANTED) {//无权限
ActivityCompat.requestPermissions(activity, PERMISSIONS_CALLLOG,
REQUEST_CALLLOG);//动态赋权
}
}
}
2、adapter布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/_id"
android:layout_marginLeft="10dp"
android:textSize="14sp"
android:layout_width="15sp"
android:layout_height="35dp"/>
<TextView
android:id="@+id/name"
android:text="联系人"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="35dp"/>
<TextView
android:id="@+id/number"
android:text="电话号码"
android:textSize="14sp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="35dp"/>
</LinearLayout>
3、主布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/callist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
4、Manifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fengray.myex005tonghua">
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
5、主activity文件
public class MainActivity extends AppCompatActivity {
private ListView callist;
private Cursor result = null;//结果指针
private List<Map<String, Object>> allCalls = null;
private SimpleAdapter adapter = null;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PermisionUtils.verifyCallLogPermissions(this);
callist = findViewById(R.id.callist);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
return;
}
result = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null,null);//查询通话记录
startManagingCursor(result);//将结果集交给管理器执行
//创建List
allCalls=new ArrayList<>();
for (result.moveToFirst();!result.isAfterLast();result.moveToNext()){
Map<String ,Object> contact=new HashMap<>();
contact.put("_id",result.getInt(result.getColumnIndex(CallLog.Calls._ID)));
String tempString=result.getString(result.getColumnIndex(CallLog.Calls.CACHED_NAME));//实操中没有取到这个值
Log.d("jian", "onCreate: "+tempString);
if (tempString==null || "".equals(tempString)){
tempString="未知";
}
contact.put("name",tempString);
contact.put("number",result.getInt(result.getColumnIndex(CallLog.Calls.NUMBER)));
allCalls.add(contact);
}
adapter=new SimpleAdapter(this,allCalls,R.layout.contacts,new String[]{"_id","name","number"},new int[]{R.id._id,R.id.name,R.id.number});
callist.setAdapter(adapter);
}
}
结果:始终未能读取到name,不知道为什么
4.SimpleCursorAdapter
创建PermisionUtils 类
首次执行被询问
public class PermisionUtils {
private static final int REQUEST_CALLLOG = 1;
private static String[] PERMISSIONS_CALLLOG = {
Manifest.permission.READ_CALL_LOG,
Manifest.permission.WRITE_CALL_LOG};
public static void verifyCallLogPermissions(Activity activity) {//检查权限
int permission = ActivityCompat.checkSelfPermission(activity,
Manifest.permission.WRITE_CALL_LOG);
if (permission != PackageManager.PERMISSION_GRANTED) {//无权限
ActivityCompat.requestPermissions(activity, PERMISSIONS_CALLLOG,
REQUEST_CALLLOG);//动态赋权
}
}
}
2、adapter布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/_id"
android:layout_marginLeft="10dp"
android:textSize="14sp"
android:layout_width="15sp"
android:layout_height="35dp"/>
<TextView
android:id="@+id/name"
android:text="联系人"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="35dp"/>
<TextView
android:id="@+id/number"
android:text="电话号码"
android:textSize="14sp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="35dp"/>
</LinearLayout>
3、主布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/callist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
4、Manifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fengray.myex005tonghua">
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
5、主activity文件
public class MainActivity extends AppCompatActivity {
private ListView callist;
private Cursor result = null;//结果指针
private ListAdapter listAdapter=null;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PermisionUtils.verifyCallLogPermissions(this);
callist = findViewById(R.id.callist);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
return;
}
result = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null,null);//查询通话记录
startManagingCursor(result);//将结果集交给管理器执行
String [] columns=new String[] {CallLog.Calls._ID, CallLog.Calls.CACHED_NAME, CallLog.Calls.NUMBER};
int [] entries=new int[]{R.id._id,R.id.name,R.id.number};
listAdapter=new SimpleCursorAdapter(this,R.layout.contacts,result,columns,entries);//将adpater变成直接可以显示的数据
callist.setAdapter(listAdapter);
}
}
结果:依然无法读取name属性