目录

第7章 跨程序共享数据——探究内容提供器

简介

内容提供器(Content Provider):在不同应用程序之间,实现数据共享的功能。允许一个程序访问另一个程序的数据,还能保证被访问数据的安全性。

运行时权限

在程序运行时申请权限

首先在MainActivity中添加call():

private void call() {
    try {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:10086"));
        startActivity(intent);
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

然后在按钮onClick()中添加:

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{ Manifest.permission.CALL_PHONE }, 1);
} else {
    call();
}

ContextCompat.checkSelfPermission()判断用户是否已经授权过,Manifest.permission.CALL_PHONE是具体的权限名。PackageManager.PERMISSION_GRANTED表示已授权。
ActivityCompat.requestPermissions()向用户申请授权。第二个参数是String数组,第三个是权限码,唯一即可。
最后在MainActivity中添加:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                call();
            } else {
                Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
            }
            break;
        default:
    }
}

访问其他程序中的数据

ContentResolver的基本用法

内容URI格式
content://com.example.app.provider/table1
解析成Uri对象

Uri uri = Uri.parse("content://com.example.app.provider/table1");

query()

Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);

查询完后进行遍历

if (cursor != null) {
    while (cursor.moveToNext()) {
        String column1 = cursor.getString(cursor.getColumnIndex("column1"));
        int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
    }
    cursor.close();
}

insert()

ContentValues values= new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);

update()

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[]{ "text", "1" });

delete()

getContentResolver().delete(uri, "column2 = ?", new String[]{ "1" });

读取系统联系人

读取联系人方法:

private void readContacts() {
    Cursor cursor = null;
    try {
        // 查询联系人数据
        cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
        if(cursor != null) {
            while (cursor.moveToNext()) {
                //获取联系人姓名
                String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                //获取联系人手机号
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

判断是否有权限和读取:

if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_CONTACTS }, 1);
} else {
    readContacts();
}

创建自己的内容提供器

创建内容提供器步骤

TBD