导读

1.ContentProvide简介
2.生成ContentProvider文件
3.不同程序的信息交互
4.从系统获取联系人信息的实例
5.面试问题

ContentProvide简介

⚠️四大组件公有的特点就是1。 需要继承,因为它们是抽象类
2。要在配置文件中进行配置,需要唯一标示

生成ContentProvider文件

也是java文件

⚠️URL 是配置文件中那个唯一标示
Exported表示能否被其他应用使用数据
Enabled表示能否使用其他应用数据

在同一个工程中建两个module,模拟两个应用程序

配置后dataproviderdemo的配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.hala.dataproviderdemo"><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><!--这里就是新注册的providerandroid:authorities 这个是唯一标示的属性--><provider
            android:name=".MyContentProvider"android:authorities="com.hala.myprovide"android:enabled="true"android:exported="true"></provider></application></manifest>

ContentProvider与 ContentResolver 是配套使用的 后者在一个程序里用相关方法和url写出一些操作请求,在前者的ContentProvider 中有相应的方法响应这些请求,以实现数据的跨应用流通

不同程序的信息交互

dataproviderdemo 模块的配置文件 Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.hala.dataproviderdemo"><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><!--这里就是新注册的providerandroid:authorities 这个是唯一标示的属性--><provider
            android:name=".MyContentProvider"android:authorities="com.hala.myprovide"android:enabled="true"android:exported="true"></provider></application></manifest>

provider文件 MyContentProvider.java

package com.hala.dataproviderdemo;import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;public class MyContentProvider extends ContentProvider {//URI的解析://1。UriMatcher:在ContentProvider创建时,制订好匹配规则,当调用了//ContentProvider中的操作方法时,利用匹配类去匹配传的uri,根据不同的uri给出不同的处理//2。uri自带解析方法public MyContentProvider() {}SQLiteDatabase db;UriMatcher matcher;/*** 在ContentProvider(dataproviderdemo第一次启动)创建时调用* @return*/@Overridepublic boolean onCreate() {// TODO: Implement this to initialize your content provider on startup.SQLiteOpenHelper helper=new SQLiteOpenHelper(getContext(),"stu.db",null,1) {@Overridepublic void onCreate(SQLiteDatabase db) {String sql="create table info_tb (_id integer primary key autoincrement, "+"name varchar(20),"+"age integer,"+"gender varchar(2))";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}};db=helper.getReadableDatabase();//此处参数表示无法匹配matcher=new UriMatcher(UriMatcher.NO_MATCH);//参数一:uri//参数二:自定义的路径的名称//参数三:返回的码matcher.addURI("com.hala.provide","helloworld",1000);matcher.addURI("com.hala.provide","helloworld/abc",1001);//#表示可以是任意数字的内容matcher.addURI("com.hala.provide","helloworld/#",1002);//*表示可以是任意字符的内容matcher.addURI("com.hala.provide","helloworld/*",1003);return true;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {// Implement this to handle requests to delete one or more rows.int result=0;int code=matcher.match(uri);switch (code) {case 1000:Log.e("TAG","匹配到的路径是helloworld");break;case 1001:Log.e("TAG","匹配到的路径是helloworld/abc");break;case 1002:Log.e("TAG","匹配到的路径是helloworld/任意数字内容");break;case 1003:Log.e("TAG","匹配到的路径是helloworld/任意字符内容");break;default:Log.e("TAG","这里会执行删除操作的方法");result = db.delete("info_tb", selection, selectionArgs);break;}return result;}@Overridepublic String getType(Uri uri) {// TODO: Implement this to handle requests for the MIME type of the data// at the given URI.throw new UnsupportedOperationException("Not yet implemented");}@Overridepublic Uri insert(Uri uri, ContentValues values) {// TODO: Implement this to handle requests to insert a new row.Log.e("TAG","调用了dataprovider中的insert方法");long id=0;if(values.size()>0) {id = db.insert("info_db", null, values);}else{String authority=uri.getAuthority();String path=uri.getPath();String query=uri.getQuery();String name=uri.getQueryParameter("name");String age=uri.getQueryParameter("age");String gender=uri.getQueryParameter("gender");Log.e("TAG","主机名:"+authority+",路径:"+path+",查询数据:"+query+",姓名:"+name+",年龄"+age+",性别:"+gender);values.put("name",name);values.put("age",age);values.put("gender",gender);id=db.insert("info_tb",null,values);}//将id追加到uri后边,这个id就是数据库中那个主键_idreturn ContentUris.withAppendedId(uri, id);}/**** @param uri* @param projection 所要查询的列* @param selection 查询条件* @param selectionArgs 查询条件值* @param sortOrder 排序* @return*/@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {// TODO: Implement this to handle query requests from clients.Cursor c=db.query("info_tb",projection,selection,selectionArgs,null,null,sortOrder);return c;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {// TODO: Implement this to handle requests to update one or more rows.int result=db.update("info_tb",values,selection,selectionArgs);return result;}
}

dataresoverdemo 模块 主页面布局文件 activity_main2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="10dp"><EditText
        android:id="@+id/name"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="姓名:"/><EditText
        android:id="@+id/age"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="年龄:"android:numeric="integer"/><RadioGroup
        android:id="@+id/gender"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="性别"android:layout_marginLeft="5dp"/><RadioButton
            android:id="@+id/male"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="男"android:layout_marginLeft="15dp"android:checked="true"/><RadioButton
            android:id="@+id/female"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="女"android:layout_marginLeft="15dp"/></RadioGroup><EditText
        android:id="@+id/id"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="编号"/><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Button
            android:id="@+id/insert"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="添加"android:onClick="operate"/><Button
            android:id="@+id/select"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="查询"android:onClick="operate"/><Button
            android:id="@+id/delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="删除"android:onClick="operate"/><Button
            android:id="@+id/update"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="修改"android:onClick="operate"/></LinearLayout><Button
        android:id="@+id/matcher"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="利用UriMatcher去解析Uri"android:onClick="operate"/><Button
        android:id="@+id/uri"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="利用Uri自带的方法去解析Uri"android:onClick="operate"/><ListView
        android:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"></ListView>
</LinearLayout>

ListView每个条目的布局文件 item.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="match_parent"><TextView
        android:id="@+id/id_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /><TextView
        android:id="@+id/name_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"/><TextView
        android:id="@+id/age_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /><TextView
        android:id="@+id/gender_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /></LinearLayout>

java文件 Main2Activity.java

package com.hala.dataresoverdemo;import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.IdRes;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;public class Main2Activity extends AppCompatActivity {ContentResolver resolver;private EditText name,age,id;private RadioGroup radioGroup;private ListView stuList;private String gender;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);//没有这句的话,会空指针异常resolver=getContentResolver();name=(EditText)findViewById(R.id.name);age=(EditText)findViewById(R.id.age);id=(EditText)findViewById(R.id.id);radioGroup=(RadioGroup)findViewById(R.id.gender);stuList=(ListView)findViewById(R.id.lv);radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {if(checkedId==R.id.male){gender="男";}else{gender="女";}}});}public void operate(View v){Uri uri=Uri.parse("content://com.hala.myprovide");String mname=name.getText().toString();String mage=age.getText().toString();String mid=id.getText().toString();switch (v.getId()){case R.id.insert://参数一:URI(统一资源定位符)//参数二:valuesContentValues values=new ContentValues();values.put("name",mname);values.put("age",mage);values.put("gender",gender);//这里的uri就是ContentProvider中insert方法的返回值,可以从这里获得idLog.e("TAG", String.valueOf(values));Uri muri=resolver.insert(uri,values);long id= ContentUris.parseId(muri);Toast.makeText(this, "添加成功,新学生的学号是:"+id, Toast.LENGTH_SHORT).show();break;case R.id.select:Cursor c=resolver.query(uri,null,null,null,null);//参数二:每一个学员信息所显示的样式布局//参数三:数据源//参数四:查询结果中所有列的列名//参数五:数据未来要加载到的对应的id数组//参数六:与数据刷新有关的参数SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.item,c,new String[]{"_id","name","age","gender"},new int[]{R.id.id,R.id.name,R.id.age,R.id.gender},CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);stuList.setAdapter(adapter);break;case R.id.delete:int result=resolver.delete(uri,"_id=?",new String[]{mid});if(result>0){Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();}else{Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show();}break;case R.id.update:ContentValues values2=new ContentValues();values2.put("name",mname);values2.put("age",mage);values2.put("gender",gender);int result2=resolver.update(uri,values2,"_id=?",new String[]{mid});if(result2>0){Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();}else {Toast.makeText(this, "修改失败", Toast.LENGTH_SHORT).show();}break;case R.id.matcher:resolver.delete(Uri.parse("content://com.hala.provide/helloworld"),null,null);resolver.delete(Uri.parse("content://com.hala.provide/helloworld/abc"),null,null);resolver.delete(Uri.parse("content://com.hala.provide/helloworld/123"),null,null);resolver.delete(Uri.parse("content://com.hala.provide/helloworld/23ii"),null,null);break;case R.id.uri:Uri uri2=resolver.insert(Uri.parse("content://com.hala.myprovide/whatever?name=张三&age=23&gender=男"),new ContentValues());long id2=ContentUris.parseId(uri2);Toast.makeText(this, "添加成功,也意味着uri解析成功,新学员学号是:"+id2, Toast.LENGTH_SHORT).show();break;}}
}

从系统获取联系人信息的实例

配置文件 Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.hala.getdatafromsystemdemo"><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_SMS"/><uses-permission android:name="android.permission.READ_CONTACTS"/><uses-permission android:name="android.permission.WRITE_CONTACTS"/>
</manifest>

主页面 布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.hala.getdatafromsystemdemo.MainActivity"><Button
       android:id="@+id/sms"android:layout_width="88dp"android:layout_height="wrap_content"android:text="点击访问短信箱"app:layout_constraintTop_toTopOf="parent"android:layout_marginTop="8dp"app:layout_constraintBottom_toBottomOf="parent"android:layout_marginBottom="8dp"android:layout_marginLeft="8dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toLeftOf="@+id/guideline"android:layout_marginRight="8dp"android:onClick="click"/><Button
        android:layout_width="88dp"android:layout_height="wrap_content"android:text="点击读取联系人"app:layout_constraintBottom_toBottomOf="parent"android:layout_marginBottom="8dp"android:id="@+id/read"android:layout_marginRight="8dp"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginTop="8dp"app:layout_constraintVertical_bias="0.501"android:layout_marginLeft="8dp"app:layout_constraintLeft_toLeftOf="@+id/guideline"android:onClick="click"/><Button
        android:id="@+id/add"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="点击添加联系人"android:layout_marginRight="8dp"app:layout_constraintRight_toRightOf="parent"android:layout_marginLeft="8dp"app:layout_constraintLeft_toLeftOf="parent"android:layout_marginTop="8dp"app:layout_constraintTop_toBottomOf="@+id/read"android:onClick="click"/><android.support.constraint.Guideline
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/guideline"android:orientation="vertical"app:layout_constraintGuide_percent="0.5" /></android.support.constraint.ConstraintLayout>

java文件 MainActivity.java

package com.hala.getdatafromsystemdemo;import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {private static final int MY_PERMISSION_REQUEST_CODE =101 ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.sms).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//1。获取内容处理者ContentResolver resolver = getContentResolver();//2。查询方法//content://sms//content://sms/inbox 收件箱//content://sms/sent  发件箱//content://sms/draft 草稿箱Uri uri = Uri.parse("content://sms");Cursor c = resolver.query(uri, null, null, null, null);//3。解析Cursor//遍历Cursorwhile(c.moveToNext()) {String msg = "";//这里用for循环遍历的方法会输出所有信息,比较杂乱/*//遍历该行的列for (int i = 0; i < c.getColumnCount(); i++) {//参数:列的索引msg += c.getString(i) + "  ";}*/String address = c.getString(c.getColumnIndex("address"));String body = c.getString(c.getColumnIndex("body"));msg += address + ":" + body;Log.e("TAG", msg);}}});findViewById(R.id.read).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//1。获取内容处理者ContentResolver resolver = getContentResolver();//2。查询方法Cursor c1=resolver.query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);while (c1.moveToNext()){String msg="";/*对于联系人而言,他们的存储方式是将姓名和其他内容(电话号码)由不同的ContentProvider操作的姓名与其他内容在不同的表,姓名为主表,其他为从表主表的主键会在其他表中作为外键来使用ContactsContract.Contacts.DISPLAY_NAME 姓名ContactsContract.Contacts._ID 主键*/String name=c1.getString(c1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));String _id=c1.getString(c1.getColumnIndex(ContactsContract.Contacts._ID));Log.e("TAG","姓名是:"+name+",id是:"+_id);String selections=ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=?";Cursor c2=resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,selections,new String[]{_id},null);while(c2.moveToNext()){String number=c2.getString(c2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));name+=" "+number;}Log.e("TAG",name);}}});findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ContentResolver resolver=getContentResolver();//1.往一个ContentProvider中插入一条空数据,获取新生成的id//2.利用刚生成的id分别组合姓名和电话号码往另一个ContentProvider中插入数据ContentValues values=new ContentValues();Uri uri=resolver.insert(ContactsContract.RawContacts.CONTENT_URI,values);long id= ContentUris.parseId(uri);//插入数据(姓名)values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,"Emilia");//指定和姓名关联的编号列的内容values.put(ContactsContract.Data.RAW_CONTACT_ID,id);//指定插入类型values.put(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);resolver.insert(ContactsContract.Data.CONTENT_URI,values);//插入电话号码values.clear();values.put(ContactsContract.CommonDataKinds.Phone.NUMBER,"13223346728");values.put(ContactsContract.Data.RAW_CONTACT_ID,id);values.put(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);//指定手机还是固话,这里为手机values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);resolver.insert(ContactsContract.Data.CONTENT_URI,values);}});}public void click(View view){boolean isAllGranted=checkPermissionAllGranted(new String[]{Manifest.permission.READ_SMS,Manifest.permission.READ_CONTACTS,Manifest.permission.WRITE_CONTACTS});if(isAllGranted){doBackup();return;}ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS,Manifest.permission.READ_CONTACTS,Manifest.permission.WRITE_CONTACTS},MY_PERMISSION_REQUEST_CODE);}private boolean checkPermissionAllGranted(String[] strings) {for(String permission:strings){if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED){return false;}}return true;}public void onRequestPermissionResult(int requestCode,String[] permissions,int[] grantResults){super.onRequestPermissionsResult(requestCode,permissions,grantResults);if(requestCode==MY_PERMISSION_REQUEST_CODE){boolean isAllGranted=true;for(int grant:grantResults){if(grant!=PackageManager.PERMISSION_GRANTED){isAllGranted=false;break;}}if(isAllGranted){doBackup();}else {openAppDetails();}}}private void openAppDetails() {AlertDialog.Builder builder=new AlertDialog.Builder(this);builder.setMessage("备份通讯录需要访问'通讯录'和'外部存储器',请到'应用信息->权限'中授予!");builder.setPositiveButton("去手动授权", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Intent intent=new Intent();intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setData(Uri.parse("package:"+getPackageName()));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);startActivity(intent);}});builder.setNegativeButton("取消",null);builder.show();}private void doBackup() {Toast.makeText(this, "正在备份通讯录...", Toast.LENGTH_SHORT).show();}}

面试问题

Android 之路44---四大组件之ContentProvider相关推荐

  1. 【Monica的android学习之路】四大组件的生命周期

    [Monica的android学习之路]四大组件的生命周期 1. Service 1.1 启动service 1.1.1 startService 1.1.2 bindService 1.2 死亡回调 ...

  2. Android基础再回首——四大组件之Activity、Service俩兄弟

    Android基础再回首--四大组件之Activity.Service俩兄弟 偶尔的回首过去,总是有不一样的收获.今天就来回顾下Activity和service吧,不用嫌弃太基础了,打好基础是取得成功 ...

  3. 戏说Android四大组件之ContentProvider

    戏说江湖静如水,游荡江湖才有情.我就是江湖中的一个戏子. 俗话说,入行先入门.作为一名android学习者,四大组件是android中的核心组件,岂有不学之理.然而,本人才疏学浅,叙述略有不当之处,敬 ...

  4. Android四大组件之ContentProvider详解

    1. 为什么需要内容提供者contentProvider? 为不同的应用之间数据共享提供统一的访问接口,内容提供者的作用 把私有的数据给暴露出来 2. 内容提供者原理? 原理:可以把ContentPr ...

  5. 【Android】四大组件之 ContentProvider

    前言 ContentProvider 是 Android 的四大组件之一,有时候我们需要操作其他应用程序的一些数据,就会用到 ContentProvider,ContentProvider 本质上是一 ...

  6. Android四大组件之ContentProvider 全面解析,ContentResolver源码解析如何调用其它APP的ContentProvider

    今天来总结下Android中的ContentProvider(以下简称CP),具体代码请见https://github.com/Mangosir/ContentProviderReview/tree/ ...

  7. Android四大组件之ContentProvider

    1.ContentProvider定义 这里通过一个实际的例子来说明ContentProvider(内容提供者)是什么,作用是什么 短信应用要访问通讯录应用中的数据,是不能直接访问的,应用通讯录的中的 ...

  8. Android开发基础(四大组件及Intent)

    一.Android开发的四大组件: 1.Activity:(通常展现一个可视化的用户界面) (1)一个Activity通常就是一个单独的屏幕(窗口). (2)Activity之间通过Intent进行通 ...

  9. 四大组件之ContentProvider(一)-使用系统提供的ContentProvider

    更新时间 修改意见 2016-08-02 陈敏 第1节 ContentProvider介绍 ContentProvider是安卓系统的四大组件之一,可以向其他组件提供数据访问的能力.它就像是一个网站, ...

最新文章

  1. 同步和异步, 阻塞和非阻塞, Reactor和Proactor
  2. [20150805]提升scn4.txt
  3. 深入理解Java main方法
  4. [Unity脚本运行时更新]C#4新特性
  5. wordpress页面里可不可以写php,WordPress开发中如何在html中包含php
  6. qt unicode转gbk_Qt中文编码和QString类Unicode编码转换
  7. php读取excel文件_如何用PHP读取excel文件内容、获取单元格数据
  8. TCP交互式游戏《基于TCP的C/S程序设计》
  9. linux中如何查看本机ip,Linux中如何查看本机IP地址呢?
  10. c #点击按钮下载excel文件
  11. html的style不起作用,css样式不起作用是什么原因?
  12. Pr 电影开场帷幕拉开效果和轨道遮罩的应用
  13. 【Docker】基于CentOS 8:Docker使用基础
  14. php pdo oracle 乱码,php pdo 乱码怎么办
  15. USACO--Broken Necklace(C语言)beads
  16. 2021年4月总结5月计划
  17. Python 调用谷歌翻译(2021年3月测试可用)
  18. 常见的java面试知识点
  19. 东北大学软件项目管理与过程改进复习提纲(2020)——中英文对照表(按首字母排序)
  20. Nacos高级特性Raft算法以及原理和源码分析

热门文章

  1. Python学习必备:10个奇妙的Python库,看完后我惊呆了
  2. oracle数据库控制器,Oracle网格控制器OMA安装和配置指南
  3. 签名证书keystore,jks,pk8,x509.pem
  4. 2021-07-17【普及组】模拟赛C组
  5. 视频关键帧inceptionV3Xception特征提取
  6. Vue-1-实例、渲染、监听事件
  7. 【Open Search产品评测】-- 淘点点:基于OpenSearch,轻松实现一整套O2O类搜索解决方案...
  8. 卓越员工对“怠惰”说不
  9. 6代u笔记本完美支持win7_华硕飞行堡垒六代笔记本安装win7系统的操作教程
  10. HTML网页设计制作大作业(div+css)---浩瀚天文 (13页有二级菜单)