Android --- 共享数据 -- ContentResolver

来源:互联网 发布:淘宝vip课程免费下载 编辑:程序博客网 时间:2024/06/05 04:41

简介:

ContentProvider 是内容提供者
ContentResolver 内容解析者

ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE 或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。
那么,这里为何要使用ContentProvider 对外共享数据呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。 使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
ContentProvider的原理是按照一定规则暴露自己的接口给其它应用来访问自己应用的数据(其实就是自定义增删改查接口并暴露出去,让别的应用访问自己的数据)。
ContentResolver就是按照一定规则访问内容提供者的数据(其实就是调用内容提供者自定义的接口来操作它的数据)。

系统中提供的 ContentProvider 都需要使用 ContentResolver 来操作,操作方式,
在任何一个 Context 环境下均可以使用 getContentResolver() 拿到ContentResolver 对象

查询:

private void readSms(){    // 短信的 Uri    Uri uri = Uri.parse("content://sms");    // 查询的字段    String[] columns = {"_id","address","type","body"};    // 查询    Cursor c = getContentResolver().query(uri,columns,null,null,null);    StringBuilder sb = new StringBuilder();    while(c.moveToNext()){        int id = c.getInt(0);        String address = c.getString(1);        int type = c.getInt(2);        String body = c.getString(3);        sb.append(id).append("\t").append(address).append("\t")            .append(type).append("\t").append(body).append("\n");    }    c.close();    tvResult.setText(sb.toString());}

注意: 6.0 以上针对部分数据(联系人,短信)需要动态申请权限

动态申请权限

1 、检测权限是否被授权

// 检测是否授权int permissionState = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);    if(permissionState == PackageManager.PERMISSION_GRANTED){    //已授权}

2 、如果未授权则需要申请权限

requestPermissions(new String[]{Manifest.permission.READ_SMS},REQUST_READ_SMS);

3 、处理申请结果,需要在 Activity 中重写 onRequestPermissionsResult 方法

以申请读短信为例

检测和申请// 检测当前系统是否是 6.0 以上if(Build.VERSION.SDK_INT >= 23){    // 检测是否授权    int permissionState = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);    if(permissionState == PackageManager.PERMISSION_GRANTED){        // 表示已经授权        readSms();    } else {        // 申请权限        requestPermissions(new String[]{Manifest.permission.READ_SMS},REQUST_READ_SMS);    }} else {    readSms();}结果处理@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {    if(requestCode == REQUST_READ_SMS){    if(grantResults[0] == PackageManager.PERMISSION_GRANTED){        // 授权成功        readSms();    }else{        // 是否需要跟用户解释为什么要申请该权限        if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_SMS)){            // 解释一下            AlertDialog.Builder b = new AlertDialog.Builder(this);            b.setTitle(" 警告 ");            b.setMessage(" 不授权将无法显示数据 ");            b.setPositiveButton(" 确认 ", new DialogInterface.OnClickListener() {                @Override                public void onClick(DialogInterface dialog, int which) {                    if(Build.VERSION.SDK_INT >= 23){                        requestPermissions(new String[]{Manifest.permission.READ_SMS}                        ,REQUST_READ_SMS);                    }                }            });            b.setNegativeButton(" 取消 ",null);            b.show();            }        }    }}

[ 附 ]

Android6.0 之后需要单独申请的权限

共分为 9 组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了

group:android.permission-group.CONTACTS    permission:android.permission.WRITE_CONTACTS    permission:android.permission.GET_ACCOUNTS    permission:android.permission.READ_CONTACTSgroup:android.permission-group.PHONE    permission:android.permission.READ_CALL_LOG    permission:android.permission.READ_PHONE_STATE    permission:android.permission.CALL_PHONE    permission:android.permission.WRITE_CALL_LOG    permission:android.permission.USE_SIP    permission:com.android.voicemail.permission.ADD_VOICEMAILgroup:android.permission-group.CALENDAR    permission:android.permission.READ_CALENDAR    permission:android.permission.WRITE_CALENDARgroup:android.permission-group.CAMERA    permission:android.permission.CAMERAgroup:android.permission-group.SENSORS    permission:android.permission.BODY_SENSORSgroup:android.permission-group.LOCATION    permission:android.permission.ACCESS_FINE_LOCATION    permission:android.permission.ACCESS_COARSE_LOCATIONgroup:android.permission-group.STORAGE    permission:android.permission.READ_EXTERNAL_STORAGE    permission:android.permission.WRITE_EXTERNAL_STORAGEgroup:android.permission-group.MICROPHONE    permission:android.permission.RECORD_AUDIOgroup:android.permission-group.SMS    permission:android.permission.READ_SMS    permission:android.permission.RECEIVE_WAP_PUSH    permission:android.permission.RECEIVE_MMS    permission:android.permission.RECEIVE_SMS    permission:android.permission.SEND_SMS    permission:android.permission.READ_CELL_BROADCASTS

Android 普通权限,只需要在 AndroidManifest.xml 中声明即可

android.permission.ACCESS_LOCATION_EXTRA_COMMANDSandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_NOTIFICATION_POLICYandroid.permission.ACCESS_WIFI_STATEandroid.permission.ACCESS_WIMAX_STATEandroid.permission.BLUETOOTHandroid.permission.BLUETOOTH_ADMINandroid.permission.BROADCAST_STICKYandroid.permission.CHANGE_NETWORK_STATEandroid.permission.CHANGE_WIFI_MULTICAST_STATEandroid.permission.CHANGE_WIFI_STATEandroid.permission.CHANGE_WIMAX_STATEandroid.permission.DISABLE_KEYGUARDandroid.permission.EXPAND_STATUS_BARandroid.permission.FLASHLIGHTandroid.permission.GET_ACCOUNTSandroid.permission.GET_PACKAGE_SIZEandroid.permission.INTERNETandroid.permission.KILL_BACKGROUND_PROCESSESandroid.permission.MODIFY_AUDIO_SETTINGSandroid.permission.NFCandroid.permission.READ_SYNC_SETTINGSandroid.permission.READ_SYNC_STATSandroid.permission.RECEIVE_BOOT_COMPLETEDandroid.permission.REORDER_TASKSandroid.permission.REQUEST_INSTALL_PACKAGESandroid.permission.SET_TIME_ZONEandroid.permission.SET_WALLPAPERandroid.permission.SET_WALLPAPER_HINTSandroid.permission.SUBSCRIBED_FEEDS_READandroid.permission.TRANSMIT_IRandroid.permission.USE_FINGERPRINTandroid.permission.VIBRATEandroid.permission.WAKE_LOCKandroid.permission.WRITE_SYNC_SETTINGScom.android.alarm.permission.SET_ALARMcom.android.launcher.permission.INSTALL_SHORTCUTcom.android.launcher.permission.UNINSTALL_SHORTCUT

加载所有的图片

private void readImages() {    Cursor c = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI        ,null, null, null, null);    StringBuilder sb = new StringBuilder();    while (c.moveToNext()) {        int id = c.getInt(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));        String title = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE));        String data = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));        sb.append(id).append("\t").append(title).append("\t").append(data).append("\n");        // 获取缩略图        //Bitmap thumb = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver()        , id, MediaStore.Images.Thumbnails.MICRO_KIND, null);    }    c.close();    tvResult.setText(sb.toString());}

说明: ActivityCompat 继承自 ContextCompat 均属于 v4 包中的兼容类, ActivityCompat 向低版本提供高版本 Activity 的新功能方法, ContextCompat 向低版本提
供高版本中的 Context 的新功能方法

加载视频

private void readVideo(){    Cursor c = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI        , null, null, null, null);    StringBuilder sb = new StringBuilder();    while (c.moveToNext()) {        int id = c.getInt(c.getColumnIndexOrThrow(MediaStore.Video.Media._ID));        String title = c.getString(c.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));        String data = c.getString(c.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));        sb.append(id).append("\t").append(title).append("\t").append(data).append("\n");        // 获取缩略图        //if(Build.VERSION.SDK_INT >=10){            // MediaMetadataRetriever mr = new MediaMetadataRetriever();            // mr.setDataSource(data);            // Bitmap b = mr.getFrameAtTime();        //}else{            // Bitmap thumb = ThumbnailUtils.createVideoThumbnail(data            ,MediaStore.Images.Thumbnails.MICRO_KIND);        // }    }    c.close();    tvResult.setText(sb.toString());}

加载所有音频

private void readAudio(){    Cursor c = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI        , null, null, null, null);    StringBuilder sb = new StringBuilder();    while (c.moveToNext()) {        int id = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));        String title = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));        String data = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));        sb.append(id).append("\t").append(title).append("\t").append(data).append("\n");    }    c.close();    tvResult.setText(sb.toString());}
阅读全文
0 0
原创粉丝点击