内容提供器

m内容提供器(Content Provider)主要用于不同应用程序之间实现数据共享的功能,提供一套完整的机制,允许一个程序访问另一个程序中的数据,同时还保证被访数据的安全性

1. 运行时权限

Android 中有上百种系统功能、传感器,当应用软件需要使用该功能时,需要获得其运行时权限

这里写图片描述

已拨打电话 ACTION_CALL为例

public class ProviderActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_provider);
        Button makeCall = findViewById(R.id.make_call);
        makeCall.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断用户是否已授权
                if(ContextCompat.checkSelfPermission(ProviderActivity.this, Manifest.permission.CALL_PHONE)!= PackageManager.PERMISSION_GRANTED){
                    ActivityCompat.requestPermissions(ProviderActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
                }else{
                    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();
        }
    }
    //调用完requestPermissions方法后,系统会弹出一个权限申请的对话框,无论用户拒绝或者同意我们的权限申请,都会回调onRequestPermissionsResult方法
    @Override
    public void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                    call();
                }else{
                    Toast.makeText(this,"您已拒绝同意该权限",Toast.LENGTH_LONG).show();
                }
        }
    }
}

 另外需要在AndroidManifest.xml中声明如下权限

<uses-permission android:name="android.permission.CALL_PHONE" />

2. 访问其他程序中的数据

其中ContentProvider负责

  • 组织应用程序的数据;
  • 向其他应用程序提供数据;

ContentResolver则负责

  • 获取ContentProvider提供的数据;
  • 修改/添加/删除更新数据等;

        对于每一个应用程序来说, 如果想要访问内容提供器中共享的数据, 就一定要借助ContentResolver类, 可以通过Context中的getContentResolver() 方法获取到该类的实例。

 ContentResolver中提供了一系列的方法用于对数据进行CRUD操作, 其中insert() 方法用于添加数据, update() 方法用于更新数据, delete() 方法用于删除数据, query() 方法用于查询数据。

查询如下方法所示

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

读取系统联系人

        //读取系统联系人
        ListView contactsView = findViewById(R.id.contacts_view);

        adapter = new ArrayAdapter<String>(this, android.R.layout. simple_list_item_1, contactsList);
        contactsView.setAdapter(adapter);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_CONTACTS }, 1);
        } else {
           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));
                    contactsList.add(displayName + "\n" + number);
                }
                adapter.notifyDataSetChanged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        }

 另外需要在AndroidManifest.xml中声明如下权限

<uses-permission android:name="android.permission.READ_CONTACTS" />


 3. 自定义内容提供器

databasetest项目上自定义的内容提供器

public class DatabaseProvider extends ContentProvider {

    public static final int USER_DIR = 0;
    public static final int USER_ITEM = 1;

    public static final String AUTHORITY = "com.example.databasetest.provider";

    private static UriMatcher uriMatcher;

    private MyDatabaseHelper dbHelper;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "user", USER_DIR);
        uriMatcher.addURI(AUTHORITY, "user/#", USER_ITEM);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new MyDatabaseHelper(getContext(), "database.db", null, 2);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        // 查询数据
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                cursor = db.query("User", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case USER_ITEM:
                String userId = uri.getPathSegments().get(1);
                cursor = db.query("User", projection, "id = ?", new String[] { userId }, null, null, sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // 添加数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
            case USER_ITEM:
                long newUserId = db.insert("User", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/user/" + newUserId);
                break;
            default:
                break;
        }
        return uriReturn;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        // 更新数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows = 0;
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                updatedRows = db.update("User", values, selection, selectionArgs);
                break;
            case USER_ITEM:
                String userId = uri.getPathSegments().get(1);
                updatedRows = db.update("User", values, "id = ?", new String[] { userId });
                break;
            default:
                break;
        }
        return updatedRows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // 删除数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                deletedRows = db.delete("User", selection, selectionArgs);
                break;
            case USER_ITEM:
                String bookId = uri.getPathSegments().get(1);
                deletedRows = db.delete("User", "id = ?", new String[] { bookId });
                break;
            default:
                break;
        }
        return deletedRows;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.user";
            case USER_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.user";

        }
        return null;
    }

MyProject项目上 实现ContentResolver对databasetest项目中内容进行提取

 Button addProvideData = (Button) findViewById(R.id.add_provide_data);
        addProvideData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 添加数据
                Uri uri = Uri.parse("content://com.example.databasetest.provider/user");
                ContentValues values = new ContentValues();
                values.put("username", "jjj");
                values.put("height", 55);
                values.put("age", 11);
                Uri newUri = getContentResolver().insert(uri, values);
                newId = newUri.getPathSegments().get(1);
            }
        });
        Button queryProvideData = (Button) findViewById(R.id.query_provide_data);
        queryProvideData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 查询数据
                Uri uri = Uri.parse("content://com.example.databasetest.provider/user");
                Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        String username = cursor.getString(cursor. getColumnIndex("username"));
                        double height = cursor.getDouble(cursor. getColumnIndex("height"));
                        int age = cursor.getInt(cursor.getColumnIndex ("age"));
                        Log.d("ProviderActivity", "姓名" + username);
                        Log.d("ProviderActivity", "身高" + height);
                        Log.d("ProviderActivity", "年龄 " + age);
                    }
                    cursor.close();
                }
            }
        });
        Button updateProvideData = (Button) findViewById(R.id.update_provide_data);
        updateProvideData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 更新数据
                Uri uri = Uri.parse("content://com.example.databasetest.provider/user/" + newId);
                ContentValues values = new ContentValues();
                values.put("age", 1216);
                getContentResolver().update(uri, values, null, null);
            }
        });
        Button deleteProvideData = (Button) findViewById(R.id.delete_provide_data);
        deleteProvideData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 删除数据
                Uri uri = Uri.parse("content://com.example.databasetest.provider/user/" + newId);
                getContentResolver().delete(uri, null, null);
            }
        });

由于 Android10版本过高

需要在两个项目中AndroidManifest.xml添加权限认可

  //内容提取项目这边
<queries>
        <package android:name="com.example.databasetest" />

        <!-- 也可以单独指定provider -->
        <!--        <provider android:authorities="com.example.databasetest.provider" />-->
    </queries>
 //内容提供项目侧   
<permission
        android:name="DatabaseProvider._WRITE_PERMISSION"
        android:protectionLevel="normal" />

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值