[关闭]
@excavator 2015-05-28T12:58:11.000000Z 字数 9924 阅读 1298

四大组件

Activity ContentProvider BroadcastReceiver Service


一. ContentProvider

1. 如何实现ContentProvider

  1. 继承自抽象类ContentProvider实现一系列针对于数据的增、删、改、查等方法。
  2. 需要在AndroidMainfest.xml中完成对ContentProvider的注册
  1. <provider
  2. android:name=".MyProvider"
  3. android:authorities:"com.excavator.myprovider.provider">
  4. </provider>

注:注册的authorities属性值是全局唯一的。

2.何为URI

URI指通用资源标识符

  • content://com.excavator.myprovider.provider/contacts/#
    第一部分:前缀表明数据受控于一个内容提供者。它从不修改,也就是schema
    第二部分:是指在AndroidMainfest.xml中我们注册的provider中的android:authorities属性所对应的。
    第三部分:具体操作于哪个条目
    第四部分:具体指定到哪个条目下的哪条记录(#标识通配符)

3.UriMatcher类

  • UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
    UriMatcher.NO_MATCH表示不匹配任何路径的返回码
  • mathcher.addURI("com.excavator.myprovider.provider","table1",1);
    UriMatcher为一个Uri的容器,容器里面包含着我们即将可能要操作的Uri
    如果通过match()方法匹配成功就返回code值
  • matcher.match(uri)
    首先通过addURI()方法添加进来的Uri匹配
    匹配成功则返回设置的code值,反之,返回一个UriMatcher.NO_MATCH常量(-1)

4.ContentResolver

  • 使用ContentResolver操作ContentProvider中的数据
    当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询时,可以使用ContentResolver类来完成
    使用Activity提供的getContentResolver()方法获取ContentResolver对象
  • ContentResolver类提供了与ContentProvider类相同签名的方法
    • public Uri insert(Uri uri,ContentValues values)
      该方法用于往ContentProvider添加数据
    • public int delete(Uri uri,String selection,String[] selectionArgs)
      该方法用于从ContentProvider删除数据
    • public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs)
      该方法用于更新ContentProvider中的数据
    • public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder)
      该方法用于从ContentProvider中获取数据
  1. 使用系统提供的ContentProvider
    • 查询联系人
    • 增加联系人
    • 短信的读取
    • 通话记录
    • 多媒体 图片 视频 音频
    • 。。。
  2. 使用自定义的ContentProvider
    • 自定义

源代码

  1. package com.excavator.contentproviderdemo;
  2. import android.app.Activity;
  3. import android.content.ContentResolver;
  4. import android.database.Cursor;
  5. import android.os.Bundle;
  6. import android.provider.ContactsContract.CommonDataKinds.Email;
  7. import android.provider.ContactsContract.CommonDataKinds.Phone;
  8. import android.provider.ContactsContract.Contacts;
  9. import android.util.Log;
  10. public class MainActivity extends Activity {
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. ContentResolver contentResolver = getContentResolver();
  16. Cursor cursor=contentResolver.query(Contacts.CONTENT_URI, new String[]{Contacts._ID, Contacts.DISPLAY_NAME}, null, null, null);
  17. if (cursor!=null){
  18. while (cursor.moveToNext()) {
  19. int id=cursor.getInt(cursor.getColumnIndex(Contacts._ID));
  20. Log.i("info", "_id:" + id);
  21. Log.i("info", "name:" + cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)));
  22. Cursor cursor1=contentResolver.query(Phone.CONTENT_URI, new String[]{Phone.NUMBER, Phone.TYPE}, Phone.CONTACT_ID + "=" + id, null, null);
  23. //根据联系人ID查询出联系人的电话号码
  24. if (cursor1!=null){
  25. while (cursor1.moveToNext()) {
  26. int type=cursor1.getInt(cursor1.getColumnIndex(Phone.TYPE));
  27. if (type==Phone.TYPE_HOME) {
  28. Log.i("info", "家庭电话:" + cursor1.getString(cursor1.getColumnIndex(Phone.NUMBER)));
  29. }else if (type==Phone.TYPE_MOBILE){
  30. Log.i("info", "手机号:" + cursor1.getString(cursor1.getColumnIndex(Phone.NUMBER)));
  31. }
  32. }
  33. cursor1.close();
  34. }
  35. //根据联系人的ID去查询联系人的邮箱地址
  36. Cursor cursor2 = contentResolver.query(Email.CONTENT_URI, new String[]{Email.DATA, Email.TYPE}, Email.CONTACT_ID + "=" + id, null, null);
  37. if (cursor2!=null){
  38. while (cursor2.moveToNext()) {
  39. int type = cursor2.getInt(cursor2.getColumnIndex(Email.DATA));
  40. if (type==Email.TYPE_WORK){
  41. Log.i("info", "工作邮箱:" + cursor2.getString(cursor2.getColumnIndex(Email.DATA)));
  42. }
  43. }
  44. cursor2.close();
  45. }
  46. }
  47. cursor.close();
  48. }
  49. }
  50. }
  1. package com.excavator.contentproviderdemo2;
  2. import android.app.Activity;
  3. import android.content.ContentResolver;
  4. import android.content.ContentUris;
  5. import android.content.ContentValues;
  6. import android.net.Uri;
  7. import android.os.Bundle;
  8. import android.provider.ContactsContract.CommonDataKinds.Phone;
  9. import android.provider.ContactsContract.Data;
  10. import android.provider.ContactsContract.CommonDataKinds.StructuredName;
  11. import android.provider.ContactsContract.RawContacts;
  12. public class MainActivity extends Activity {
  13. Uri uri;
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. ContentResolver contentResolver = getContentResolver();
  19. //向联系人中插入一行数据
  20. ContentValues contentValues = new ContentValues();
  21. uri = contentResolver.insert(RawContacts.CONTENT_URI, contentValues);
  22. Long raw_contact_id = ContentUris.parseId(uri);
  23. contentValues.clear();
  24. //插入人名
  25. contentValues.put(StructuredName.RAW_CONTACT_ID, raw_contact_id);
  26. contentValues.put(StructuredName.DISPLAY_NAME,"张三");
  27. contentValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
  28. uri = contentResolver.insert(Data.CONTENT_URI,contentValues);
  29. //插入电话信息
  30. contentValues.clear();
  31. contentValues.put(Phone.RAW_CONTACT_ID, raw_contact_id);
  32. contentValues.put(Phone.NUMBER, "123456789");
  33. contentValues.put(Phone.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  34. uri = contentResolver.insert(Data.CONTENT_URI, contentValues);
  35. }
  36. }

二. BroadcastReceiver

Broadcast(广播): 是一种广泛运用在应用程序之间传输信息的机制。
BroadcastReceiver(广播接收器): 是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。

1.使用方法


注意!!!

2.广播的种类及使用

发送标准广播代码:

  1. Intent intent = new Intent();
  2. intent.putExtra("msg","这是一条普通广播");
  3. intent.setAction("BC_One");
  4. sendBroadcast(intent);

接收器代码实现:

  1. package com.excavator.broadcastreceiverdemo;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. public class BC1 extends BroadcastReceiver {
  6. public BC1() {
  7. }
  8. @Override
  9. public void onReceive(Context context, Intent intent) {
  10. // TODO: This method is called when the BroadcastReceiver is receiving
  11. // an Intent broadcast.
  12. String s = intent.getStringExtra("msg");
  13. System.out.println("receiver1接收到消息:"+s);
  14. }
  15. }

静态注册代码:

  1. <receiver
  2. android:name=".BC1"
  3. android:enabled="true"
  4. android:exported="true" >
  5. <intent-filter>
  6. <action android:name="BC_One" />
  7. </intent-filter>
  8. </receiver>

动态注册代码:

  1. IntentFilter intentFilter = new IntentFilter("BC_One");
  2. BC2 bc2 = new BC2();
  3. registerReceiver(bc2, intentFilter);

注意:动态注册的最后需要在onDestroy()方法中调用unregisterReceiver()方法卸载掉
发送有序广播:

  1. Intent intent2 = new Intent();
  2. intent2.putExtra("msg","这是一条有序广播");
  3. intent2.setAction("BC_One");
  4. sendOrderedBroadcast(intent2, null);

发送异步广播:

  1. Intent intent3 = new Intent();
  2. intent3.putExtra("msg", "这是一条有序广播");
  3. intent3.setAction("BC_Three");
  4. sendStickyBroadcast(intent3);
  5. //先发送后注册
  6. IntentFilter intentFilter = new IntentFilter("BC_Three");
  7. BC3 bc3 = new BC3();
  8. registerReceiver(bc3,intentFilter);

最后需要在清单文件中加权限

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

三. Service

定义:

  • 后台运行,不可见,没有界面
  • 优先级高于Activity

用途:

  • 播放音乐、记录地理信息位置的改变、监听某种动作

注意:

  • 运行在主线程,不能用来做耗时的请求或者动作
  • 可以在服务中开一个线程,在线程中做耗时动作

类型:

  • 本地服务(Local Service)
    • 应用程序内部
    • startService stopService stopSelf stopSelfResult
    • bindService unbingService
  • 远程服务(Remote Service)
    • Android系统内部的应用程序之间
    • 定义IBind接口

Service生命周期:

Service-lifecycle

Start方式特点:

Bind方式特点:

MyStartService.java

  1. public class MyStartService extends Service {
  2. public MyStartService() {
  3. }
  4. @Override
  5. public IBinder onBind(Intent intent) {
  6. // TODO: Return the communication channel to the service.
  7. Log.i("info","Service--onBind");
  8. return null;
  9. }
  10. @Override
  11. public void onCreate() {
  12. Log.i("info","Service--onCreate");
  13. super.onCreate();
  14. }
  15. @Override
  16. public void onDestroy() {
  17. Log.i("info","Service--onDestroy");
  18. super.onDestroy();
  19. }
  20. @Override
  21. public int onStartCommand(Intent intent, int flags, int startId) {
  22. Log.i("info","Service--onStartCommand");
  23. return super.onStartCommand(intent, flags, startId);
  24. }
  25. }

注意:onCreate()方法是在服务第一创建时调用,而onStartCommand()方法则在每次启动服务时都会调用,第一次启动服务时,由于服务此时还未创建,所以两个方法都会执行,之后启动服务只会有onSartCommand()方法得到执行。

MyBindService.java

  1. public class MyBindService extends Service {
  2. public MyBindService() {
  3. }
  4. //在活动新建一个继承自Binder的类,然后在里面提供各种方法
  5. public class MyBinder extends Binder{
  6. public MyBindService getService() {
  7. return MyBindService.this;
  8. }
  9. }
  10. //在onBind()中返回实例
  11. @Override
  12. public IBinder onBind(Intent intent) {
  13. Log.i("info", "BindService--onBind");
  14. return new MyBinder();
  15. }
  16. @Override
  17. public void onCreate() {
  18. Log.i("info","BindService--onCreate");
  19. super.onCreate();
  20. }
  21. @Override
  22. public void onDestroy() {
  23. Log.i("info","BindService--onDestroy");
  24. super.onDestroy();
  25. }
  26. @Override
  27. public boolean onUnbind(Intent intent) {
  28. Log.i("info", "BindService--onUnbind");
  29. return super.onUnbind(intent);
  30. }
  31. public void Play() {
  32. Log.i("info","播放");
  33. }
  34. public void Pause() {
  35. Log.i("info","暂停");
  36. }
  37. public void Previous() {
  38. Log.i("info","上一首");
  39. }
  40. public void Next() {
  41. Log.i("info","下一首");
  42. }
  43. }

MainActivity.java

  1. public class MainActivity extends Activity {
  2. Intent intent1;
  3. Intent intent2;
  4. MyBindService service;
  5. ServiceConnection conn=new ServiceConnection() {
  6. //当启动源跟Service成功连接之后会自动调用这个方法
  7. @Override
  8. public void onServiceConnected(ComponentName name, IBinder binder) {
  9. service=((MyBindService.MyBinder) binder).getService();
  10. }
  11. //当启动源跟Service连接意外丢失会调用这个方法
  12. //比如Service崩溃或者被强行杀死
  13. @Override
  14. public void onServiceDisconnected(ComponentName name) {
  15. }
  16. };
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_main);
  21. }
  22. public void doClick(View v){
  23. switch (v.getId()){
  24. case R.id.start:
  25. intent1 = new Intent(MainActivity.this, MyStartService.class);
  26. startService(intent1);
  27. break;
  28. case R.id.stop:
  29. stopService(intent1);
  30. break;
  31. case R.id.bind:
  32. intent2 = new Intent(MainActivity.this,MyBindService.class);
  33. bindService(intent2,conn,Service.BIND_AUTO_CREATE);
  34. break;
  35. case R.id.play:
  36. service.Play();
  37. break;
  38. case R.id.pause:
  39. service.Pause();
  40. break;
  41. case R.id.next:
  42. service.Next();
  43. break;
  44. case R.id.previous:
  45. service.Previous();
  46. break;
  47. case R.id.unbind:
  48. unbindService(conn);
  49. break;
  50. default:
  51. break;
  52. }
  53. }
  54. }

四.Activity

Activity

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注