第8章Android内容提供者(ContentProvider)应用.ppt

上传人:花仙子 文档编号:373743 上传时间:2018-10-05 格式:PPT 页数:43 大小:2.10MB
下载 相关 举报
第8章Android内容提供者(ContentProvider)应用.ppt_第1页
第1页 / 共43页
第8章Android内容提供者(ContentProvider)应用.ppt_第2页
第2页 / 共43页
第8章Android内容提供者(ContentProvider)应用.ppt_第3页
第3页 / 共43页
第8章Android内容提供者(ContentProvider)应用.ppt_第4页
第4页 / 共43页
第8章Android内容提供者(ContentProvider)应用.ppt_第5页
第5页 / 共43页
亲,该文档总共43页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、第8章 Android内容提供者(ContentProvider)应用,网络资源:http:/ ContentProvider简介,ContentProvider是Android四大组件之一,如果要开发自己的ContentProvider必须实现Android系统提供的ContentProvider基类,并且需要在AndroidManifest.xml文件中进行配置。 1、继承ContentProvider并重写增、删、查、改等方法; 2、在AndroidManifest.xml使用对该ContentProvider进行配置。,注意:authorities是必备属性,如果没有authoriti

2、es 属性程序会报错。,ContentProvider基类的常用方法,public abstract boolean onCreate():该方法在ContentProvider创建后调用,当其他应用程序第一次访问ContentProvider时,ContentProvider会被创建,并立即调用该方法; public abstract Cursor query(Uri uri, String projection, String selection, String selectionArgs, String sortOrder):根据Uri查询符合条件的全部记录,其中projection是所

3、需要获取的数据列; public abstract int update(Uri uri,ContentValues values,String select,String selectArgs):根据Uri修改select所匹配的全部记录; public abstract int delete(Uri uri,String selection,String selectionArgs):根据Uri删除符合条件的全部记录; public abstract Uri insert(Uri uri, ContentValues values):根据Uri插入values对应的数据,ContentVa

4、lues类似于map,存放的是键值对; public abstract String getType(Uri uri):该方法返回当前Uri所代表的数据的MIME类型。如果该Uri对应的数据包含多条记录,则MIME类型字符串应该以vnd.android.curor.dir/开头,如果该Uri对应的数据只包含一条记录,则MIME类型字符串应该以vnd.android.cursor.item/开头。,8.2 ContentProvider操作常用类,Uri代表了要操作的数据,Uri主要包含了两部分信息:1、需要操作的ContentProvider;2、对ContentProvider中的什么数据进

5、行操作。 一个Uri由以下几部分组成:,scheme:ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content:/,8.2.1 URI基础,主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。路径(path)用于确定我们要操作该ContentProvider中的什么数据,一个ContentProvider内可能包含多种数据,路径的构建应根据业务而定,例如: 要操作person表中id为10的记录,可以构建这样的路径:/person/10 要操作person表中id为10

6、的记录的name字段,路径为:/person/10/name 要操作person表中的所有记录,可以构建这样的路径:/person 要操作xxx表中的记录,可以构建这样的路径:/xxx,注意:要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式。,ID:该部分是可选的,用于指定操作的具体是哪条记录,如果没有设置,则操作的是所有记录。,8.2.1 URI基础,如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,例如: Uri uri = Uri.parse(“content:/.android.providers.personprovider/person“

7、);,由于Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。,8.2.1 URI基础,UriMatcher类用于匹配Uri,它的用法如下:1、注册所有需要匹配的Uri路径:,2、注册完需要匹配的Uri后,就可以使用myUri.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content:/.providers.myprovider/person

8、路径,返回的匹配码为1。,UriMatcher myUri= new UriMatcher(UriMatcher.NO_MATCH); /创建UriMather对象,常量UriMatcher.NO_MATCH表示不匹配任何路径的 /返回码,该常量值为-1。 myUri.addURI(“.providers.myprovider”, “person”, 1);/添加需匹配的Uri,如果match()方法匹配 ontent:/.providers. /myprovider/person路径,返回匹配码为1。 myUri.addURI(“.providers.myprovider”, “person

9、/#”, 2);/添加需匹配的Uri,#号为通配符,表示匹配任何ID的Uri,如果匹配则返回2,/例如如果匹配content:/.providers.myprovider/person/230 /路径,返回匹配码为2,8.2.2 URI操作类UriMatcher和ContentUris,ContentUris类用于获取Uri路径后面的ID部分,它有两个比较实用的方法:withAppendedId(uri, id)用于为路径加上ID部分:Uri uri = Uri.parse(“content:/.personprovider/person”);Uri resultUri = ContentUr

10、is.withAppendedId(uri, 10); /生成的Uri:为content:/.personprovider/person /10parseId(uri)方法用于从路径中获取ID部分:Uri uri = Uri.parse(“content:/.personprovider/person /10”);long personid = ContentUris.parseId(uri);/获取的结果为:10,8.2.2 URI操作类UriMatcher和ContentUris,ContentProvider的作用是暴露可供操作的数据,其他应用程序主要通过ContentResolver来

11、操作ContentProvider所暴露的数据,ContentResolver相当于客户端。ContentResolver是一个抽象类,是不能直接实例化的,那么我们如何得到ContentResolver实例呢?Android中Context类提供了getContentResolver()方法用于获取ContentResolver对象。然后即可调用其增删查改方法进行数据操作。一般来说,ContentProvider是单例模式的,当多个应用程序通过ContentResolver来操作ContentProvider提供的数据时,ContentResolver调用的数据操作将会委托给同一个Conten

12、tProvider处理。 使用ContentResolver操作数据的步骤:调用Activity的getContentResolver()获取ContentResolver;根据需要调用ContentResolver的insert()、delete()、update()和query()方法操作数据。,8.2.3 ContentResolver类,ContentValues类和Java中的Hashtable类比较相似,都是负责存储一些键值对,但是它存储的键值对当中的键是一个String类型,往往是数据库的某一字段名,而值都是一些简单的数据类型。当我们向数据库中插入一条记录时,可以将这条信息的各个

13、字段值放入ContentValues,然后将该ContentValues直接插入数据库。而不用拼接SQL语句或使用占位符一一赋值。,8.2.3 ContentResolver类,8.3 ContentProvider应用案例,为备忘录添加ContentProvider,以一个具体的示例演示如何创建自己的ContentProvider,我们为备忘录示例创建ContentProvider,使得其他应用程序可以访问和修改它的数据。,向通讯录中添加联系人的事件处理代码,由于通讯录中用户名和号码存放于不同的表中,是根据联系人ID号关联起来的。因此,我们先向联系人中添加一个空的记录,产生新的ID号,然后根

14、据ID号分别在两张表中插入相应的数据。,public void addPerson() String nameStr = name.getText().toString();String numStr = num.getText().toString();ContentValues values = new ContentValues();Uri rawContactUri = resolver.insert(RawContacts.CONTENT_URI, values);long contactId = ContentUris.parseId(rawContactUri);System.o

15、ut.println(contactId);values.clear();,添加联系人,获取联系人姓名,创建一个空的ContentValues,向RawContacts.CONTENT_URI执行一个空值插入,目的是获取返回的ID号,得到新联系人的ID号,获取联系人号码,清空Values的内容,程序清单:AccessContactssrcietjxufecnandroidMainActivity.java,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,values.put(Data.RAW_CONTACT_ID, contactId);values

16、.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);values.put(StructuredName.GIVEN_NAME, nameStr);resolver.insert(android.provider.ContactsContract.Data.CONTENT_URI,values);values.clear();values.put(Data.RAW_CONTACT_ID, contactId);values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);values.put(Phon

17、e.NUMBER, numStr);values.put(Phone.TYPE, Phone.TYPE_MOBILE);resolver.insert(android.provider.ContactsContract.Data.CONTENT_URI,values);Toast.makeText(MainActivity.this, “联系人数据添加成功!“, 1000).show(); ,设置ID号,设置类型,设置姓名,向联系人Uri添加联系人名字,清空Values的内容,设置Id号,设置类型,设置号码,设置电话类型,向联系人电话号码Uri添加电话号码,程序清单:AccessContact

18、ssrcietjxufecnandroidMainActivity.java,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,获取通讯录中所有联系人的姓名和手机号时,首先查询出所有的联系人姓名和他的ID号,然后根据ID号查询电话号码表中的的号码,再将每个人的信息放在同一个map对象中,最后将这个map对象添加到列表中,作为结果返回。程序得到列表后将其与下拉列表控件相关联,从而将数据有规律的显示在我们的界面上。,public ArrayList queryPerson() ArrayList detail = new ArrayList();Curso

19、r cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);while (cursor.moveToNext() Map person = new HashMap();String personId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID);String name = cursor.getString(cursor.getColumnIndex(ContactsContract.

20、Contacts.DISPLAY_NAME);person.put(“id“, personId);person.put(“name“, name);,程序清单:AccessContactssrcietjxufecnandroidMainActivity.java,创建一个保存所有联系人信息的列表,每项是一个map对象,查询通讯录中所有联系人,循环遍历每一个联系人,获取联系人ID号,每个联系人信息用一个map对象存储,获取联系人姓名,将获取到的信息存入map对象中,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,Cursor nums = resol

21、ver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + “=“+ personId, null, null);if(nums.moveToNext()String num = nums.getString(nums.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);person.put(“num“,num);nums.close(); det

22、ail.add(person); cursor.close();System.out.println(detail);return detail;,程序清单:AccessContactssrcietjxufecnandroidMainActivity.java,根据ID号,查询手机号码,将手机号存入map对象中,关闭资源,关闭资源,返回查询列表,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,方法写好后,我们需要在相应的事件处理中调用该方法,代码如下。,MyOnClickListener myOnClickListener = new MyOnCli

23、ckListener();add.setOnClickListener(myOnClickListener);query.setOnClickListener(myOnClickListener);,程序清单:AccessContactssrcietjxufecnandroidMainActivity.java,创建事件监听器,注册事件监听器,注册事件监听器,自定义的事件处理器,针对不同事件调用不同的方法。代码如下。,private class MyOnClickListener implements OnClickListener public void onClick(View v) sw

24、itch (v.getId() case R.id.add:addPerson();break;case R.id.show:title.setVisibility(View.VISIBLE);,程序清单:AccessContacts/src/iet/jxufe/cn/android/MainActivity.java,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,自定义的事件处理器,针对不同事件调用不同的方法。代码如下。,ArrayList persons=queryPerson();SimpleAdapter adapter=new Simpl

25、eAdapter(MainActivity.this,persons, R.layout.result, new String“id“,“name“,“num“, new intR.id.personid,R.id.personname,R.id.personnum);result.setAdapter(adapter);break;default:break;,程序清单:AccessContactssrcietjxufecnandroidMainActivity.java,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,注意:,本程序需要读取、添加

26、联系人信息,因此需要在AndroidManifest.xml文件中为该应用程序授权,授权代码如下。,读的权限,写的权限,8.3.1 用ContentResolver操纵 ContentProvider提供的数据,下面我们继续学习如何开发自己的ContentProvider。即将自己的应用数据通过ContentProvider提供给其他应用。, 开发一个ContentProvider子类,该子类需要实现增,删,查,改等方法。, 在AndroidManifest.xml文件中配置该ContentProvider.,开发自己的ContentProvider主要经历两步:,下面以一个具体的示例演示如何

27、创建自己的ContentProvider,我们为备忘录示例创建ContentProvider,使得其他应用程序可以访问和修改它的数据。,首先我们定义一个常量类,把备忘录的相关信息以及Uri通过常量的形式进行公开,提供访问该ContentProvider的一些常用入口,代码如下。,8.3.2 开发自己的ContentProvider,程序清单:MementoContentsrcietjxufecnandroidMementos.java,public class Mementos public static final String AUTHORITY = “.providers.memento

28、“;public static final class Memento implements BaseColumns public static final String _ID = “_id“;public static final String SUBJECT = “subject“;public static final String BODY = “body“;public static final String DATE = “date“;public static final Uri MEMENTOS_CONTENT_URI= Uri.parse(“content:/“+ AUTH

29、ORITY + “/mementos“);public static final Uri MEMENTO_CONTENT_URI= Uri.parse(“content:/“+ AUTHORITY + “/memento“); ,memento_tb表中-id字段,memento_tb表中subject字段,memento_tb表中body字段,memento_tb表中date字段,提供操作mementos集合URI,提供操作单个mementoURI,8.3.2 开发自己的ContentProvider,然后为该应用添加ContentProvider,继承系统中的ContentProvider

30、基类,重写里面的抽象方法,具体代码如下。,程序清单:MementoContentsrcietjxufecnandroidMementoProvider.java,public class MementoProvider extends ContentProvider private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);private static final int MEMENTOS = 1;定义两个常量,用于匹配URI的返回值private static final int MEMENTO = 2;M

31、yDatabaseHelper dbHelper;SQLiteDatabase db;static 添加URI匹配规则,用于判断URI的类型matcher.addURI(Mementos.AUTHORITY, “mementos“, MEMENTOS);matcher.addURI(Mementos.AUTHORITY, “memento/#“, MEMENTO);public boolean onCreate() dbHelper = new MyDatabaseHelper(getContext(), “memento.db“, null,1);创建数据库工具类,并获取数据库实例db =

32、dbHelper.getReadableDatabase();return true; ,8.3.2 开发自己的ContentProvider,8.3 访问备忘录数据案例,public Uri insert(Uri uri, ContentValues values) /添加记录 long rowID = db.insert(“memento_tb“, Mementos.Memento._ID, values);if (rowID 0) 如果添加成功,则通知数据库记录发生更新Uri mementoUri = ContentUris.withAppendedId(uri, rowID);getC

33、ontext().getContentResolver().notifyChange(mementoUri, null);return mementoUri; return null; public int delete(Uri uri, String selection, String selectionArgs) int num = 0;删除记录,用于记录删除的记录数switch (matcher.match(uri) case MEMENTOS:删除多条记录num = db.delete(“memento_tb“, selection, selectionArgs);break;,程序清

34、单:MementoContentsrcietjxufecnandroidMementoProvider.java,8.3 访问备忘录数据案例,case MEMENTO:/删除指定ID对应的记录long id = ContentUris.parseId(uri);/获取IDString where = Mementos.Memento._ID + “=“ + id;ID字段需符合的条件if (selection != null ,程序清单:MementoContentsrcietjxufecnandroidMementoProvider.java,8.3 访问备忘录数据案例,public int

35、 update(Uri uri, ContentValues values, String selection,String selectionArgs) 更新记录int num = 0;switch (matcher.match(uri) case MEMENTOS:num = db.update(“memento_tb“, values, selection, selectionArgs);break;case MEMENTO:long id = ContentUris.parseId(uri);String where = Mementos.Memento._ID + “=“ + id;

36、if (selection != null ,程序清单:MementoContentsrcietjxufecnandroidMementoProvider.java,8.3 访问备忘录数据案例,public Cursor query(Uri uri, String projection, String selection,String selectionArgs, String sortOrder) switch (matcher.match(uri) case MEMENTOS:return db.query(“memento_tb“, projection, selection, sele

37、ctionArgs,null, null, sortOrder);case MEMENTO:long id = ContentUris.parseId(uri);String where = Mementos.Memento._ID + “=“ + id;if (selection != null ,程序清单:MementoContentsrcietjxufecnandroidMementoProvider.java,8.3 访问备忘录数据案例,public String getType(Uri uri) switch (matcher.match(uri) case MEMENTOS:ret

38、urn “vnd.android.cursor.dir/mementos“;case MEMENTO:return “vnd.android.cursor.item/memento“;default:throw new IllegalArgumentException(“未知Uri:“ + uri); ,程序清单:MementoContentsrcietjxufecnandroidMementoProvider.java,至此我们的ContentProvider就已经开发好了,下面我们在Manifest.xml中注册,代码如下。,程序清单:MementoContentAndroidManife

39、st.xml,8.3 访问备忘录数据案例,程序清单:MementoResolversrcietjxufecnandroidresolverMainActivity.java,在本应用程序中,并没有创建自己备忘录数据库,而是访问MementoContent通过ContentProvider所提供的数据,下面只列出事件处理的关键代码,代码如下。,add.setOnClickListener(new OnClickListener() public void onClick(View v) ContentValues values = new ContentValues();values.put(M

40、ementos.Memento.SUBJECT, subject.getText().toString();values.put(Mementos.Memento.BODY, body.getText().toString();values.put(Mementos.Memento.DATE, date.getText().toString();contentResolver.insert(Mementos.Memento.MEMENTOS_CONTENT_URI,values);Toast.makeText(MainActivity.this, “添加生词成功!“, Toast.LENGTH

41、_LONG).show(););,创建一个ContentValues对象,values中存值,8.3 访问备忘录数据案例,程序清单:MementoResolversrcietjxufecnandroidresolverMainActivity.java,show.setOnClickListener(new OnClickListener() public void onClick(View v) Cursor cursor = contentResolver.query(Mementos.Memento.MEMENTOS_CONTENT_URI, null, null,null, null)

42、;System.out.println(cursor);SimpleCursorAdapter resultAdapter = new SimpleCursorAdapter(MainActivity.this, R.layout.result, cursor,new String Mementos.Memento._ID,Mementos.Memento.SUBJECT,Mementos.Memento.BODY,Mementos.Memento.DATE ,new int R.id.memento_num, R.id.memento_subject,R.id.memento_body, R

43、.id.memento_date );result.setAdapter(resultAdapter););,查询所有记录,设置数据的显示方式,8.4 获取网路资源,由于手机的计算能力、存储能力都比较有限,它通常是作为移动终端来使用,具体的数据处理是交给网络服务器来进行的,而它主要的优势在于携带方便,因此,获取网络资源非常重要。Android完全支持JDK本身的TCP、UDP网络通信,也支持JDK提供的URL、URLConnection等通信API。除此之外,Android还内置了HttpClient,可方便地发送HTTP请求,并获取HTTP响应。,URL(Uniform Resource L

44、ocator)对象代表统一资源定位器,用于指定网络上某一资源,该资源既可以是简单的文件或目录,也可以是对复杂对象的引用。通常URL由协议名、主机、端口和资源组成。格式为:protocol:/host:port/resourceName, 如http:/ 获取网路资源,下面通过一个简单的例子,示范如何通过URL类读取远程资源。该示例用于获取网络上的一张图片,并显示在ImageView中。,8.4 获取网路资源,8.4 获取网络图片案例,程序清单:AccessURLsrccomexampleaccessurlMainActivity.java,public class MainActivity

45、extends Activity private ImageView myImg;private Handler myHandler;private Bitmap bitmap;public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myImg = (ImageView) findViewById(R.id.myImg);myHandler=new Handler()public void handleMes

46、sage(Message msg) if(msg.what=0x1122)myImg.setImageBitmap(bitmap); ;,8.4 获取网络图片案例,程序清单:AccessURLsrccomexampleaccessurlMainActivity.java,new Thread()public void run()tryURL url = new URL(“http:/ +“img/baidu_sylogo1.gif“);InputStream is = url.openStream();bitmap = BitmapFactory.decodeStream(is);is.clo

47、se();catch(Exception ex)ex.printStackTrace();myHandler.sendEmptyMessage(0x1122); .start();,获取百度首页图片,注意:Android2.3以后开始提供了一个新的类StrictMode,该类用于捕捉发生在应用程序主线程中耗时的磁盘、网络访问或函数调用,可以帮助开发者改进程序,使主线程处理UI和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞。而2.3以下版本则不支持该类的。如果直接在主程序中处理网络连接操作,在2.3以后版本中会抛出NetworkOnMainThreadException异常,而在之前的版本是则不会。因此,通常采用子线程来处理一些网络连接操作,这样所有版本都适用。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学课件 > 大学教育

copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1