一、使用内容提供器读取联系人
1、申明权限
2、读取联系人
public class GetContent extends AppCompatActivity {
List list=new ArrayList<>();
ArrayAdapter adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_content);
ListView listView=(ListView)findViewById(R.id.list_view);
adapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);
listView.setAdapter(adapter);
Button get=(Button)findViewById(R.id.get);
get.setOnClickListener(
view->{
/**
* 使用ContextCompat.checkSelfPermission()来判断是否有读取联系人的权限,返回值为PackageManager.PERMISSION_GRANTED表示用户已授权
* 如果没有该权限,则使用ActivityCompat.requestPermissions()来请求相关权限
* 如果有该权限,则读取联系人
*/
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS},1);
}else {
read();
}
}
);
}
//读取联系人
public void read(){
Cursor cursor=null;
try {
//getContentResolver()获得ContentResolver对象,通过该对象可以进行CRUD操作,类似于SQLiteDatabase,这里是查询
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
if(cursor!=null){
while (cursor.moveToNext()){
//读取人名
String name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//读取电话号码
String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
list.add(name+"的电话号码:"+number);
}
//更新ListView
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor!=null){
cursor.close();
}
}
}
//申请权限后,无论用户是否同意都会执行该方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
/**
* 用户授权结果在grantResults中
* 如果用户同意,则读取联系人;否则提示权限不足
*/
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
read();
}else {
Toast.makeText(this,"权限不足",Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
}
二、自定义内容提供器
注册:
内容提供器类:
//自定义的内容提供器需要继承ContentProvider,并实现其6个抽象方法
public class MyProvider extends ContentProvider {
private DataHelper dataHelper;
SQLiteDatabase sqLiteDatabase;
public static final String AUTHORITY="com.example.content.provider";
/**
* 标准的内容URI:
* 1、content://com.example.app.provider/table
* 2、content://com.example.app.provider/table/1,最后的id表示期望访问该表中相应id的数据
* 通配符:
* 1、*,表示匹配任意长度的任意字符
* 2、#,表示匹配任意长度的数字
*/
public static final int TABLE_DIR=0;
public static final int TABLE_ITEM=1;
private static UriMatcher uriMatcher;
/**
* addURI(),参数1指定authority,参数2指定path,参数3是自定义代码
* 当调用UriMatcher的match()时,返回传入Uri相对应的自定义代码
* 利用这个代码,就可以判断调用方法期望访问的表
*/
static {
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.example.content.provider","info",TABLE_DIR);
uriMatcher.addURI("com.example.content.provider","info/#",TABLE_ITEM);
}
//初始化内容提供器的时候调用,返回值表示初始化成功与否
@Override
public boolean onCreate() {
dataHelper=new DataHelper(getContext(),"student.db",null,1);
sqLiteDatabase=dataHelper.getReadableDatabase();
return true;
}
//参数1指定表,参数2指定字段,参数3、参数4指定行,参数5指定结果排序方式
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
Cursor cursor=null;
switch (uriMatcher.match(uri)){
case TABLE_DIR:
cursor=sqLiteDatabase.query("info",strings,s,strings1,null,null,s1);
break;
case TABLE_ITEM:
//下标0存储的是路径,下标1存储的是id
String id=uri.getPathSegments().get(1);
cursor=sqLiteDatabase.query("info",strings,"id = ?",new String[]{id},null,null,s1);
break;
default:
break;
}
return cursor;
}
/**
* 根据传入的内容URI返回相应的MIME,其由3部分组成:
* 1、以vnd开头
* 2、如果内容URI以路径结尾,则后接android.cursor.dir/;如果以id结尾,则后接android.cursor.item/
* 3、最后接vnd..
*/
@Nullable
@Override
public String getType(@NonNull Uri uri) {
switch (uriMatcher.match(uri)){
case TABLE_DIR:
return "vnd.android.cursor.dir/vnd."+AUTHORITY+".info";
case TABLE_ITEM:
return "vnd.android.cursor.item/vnd."+AUTHORITY+".info";
default:
break;
}
return null;
}
//参数1指定表,参数2指定数据
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
Uri returnUri=null;
switch (uriMatcher.match(uri)){
case TABLE_DIR:
case TABLE_ITEM:
long id=sqLiteDatabase.insert("info",null,contentValues);
returnUri=Uri.parse("content://"+AUTHORITY+"/info/"+id);
default:
break;
}
return returnUri;
}
//参数1指定表,参数2、参数3指定行,返回值是被删除的行数
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
int row;
switch (uriMatcher.match(uri)){
case TABLE_DIR:
row=sqLiteDatabase.delete("info",s,strings);
break;
case TABLE_ITEM:
String id=uri.getPathSegments().get(1);
row=sqLiteDatabase.delete("info","id = ?",new String[]{id});
}
return 0;
}
//参数1指定表,参数2指定数据,参数3、参数4指定行
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
int row=0;
switch (uriMatcher.match(uri)){
case TABLE_DIR:
row=sqLiteDatabase.update("info",contentValues,s,strings);
break;
case TABLE_ITEM:
String id=uri.getPathSegments().get(1);
row=sqLiteDatabase.update("info",contentValues,"id = ?",new String[]{id});
break;
default:
break;
}
return 0;
}
}
使用自定义内容提供器:
新建一个app,来操作数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button add=(Button)findViewById(R.id.add);
Button delete=(Button)findViewById(R.id.delete);
Button update=(Button)findViewById(R.id.update);
Button query=(Button)findViewById(R.id.query);
//只有数据添加与查询操作
add.setOnClickListener(
view->{
Uri uri=Uri.parse("content://com.example.content.provider/info");
ContentValues contentValues=new ContentValues();
contentValues.put("name","若风");
contentValues.put("id","0000");
contentValues.put("class","wulian");
getContentResolver().insert(uri, contentValues);
Toast.makeText(this,"add",Toast.LENGTH_SHORT).show();
}
);
query.setOnClickListener(
view -> {
Uri uri=Uri.parse("content://com.example.content.provider/info");
Cursor cursor=getContentResolver().query(uri,null,null,null,null);
if(cursor!=null){
while (cursor.moveToNext()){
Log.d("text", cursor.getString(cursor.getColumnIndex("name"))+"+"+cursor.getString(cursor.getColumnIndex("class")));
}
cursor.close();
}
Toast.makeText(this,"query",Toast.LENGTH_SHORT).show();
}
);
}