@excavator
2015-05-28T12:58:11.000000Z
字数 9924
阅读 1465
Activity ContentProvider BroadcastReceiver Service
- 继承自抽象类ContentProvider实现一系列针对于数据的增、删、改、查等方法。
- 需要在AndroidMainfest.xml中完成对ContentProvider的注册
<providerandroid:name=".MyProvider"android:authorities:"com.excavator.myprovider.provider"></provider>
注:注册的authorities属性值是全局唯一的。
URI指通用资源标识符
- content://com.excavator.myprovider.provider/contacts/#
第一部分:前缀表明数据受控于一个内容提供者。它从不修改,也就是schema
第二部分:是指在AndroidMainfest.xml中我们注册的provider中的android:authorities属性所对应的。
第三部分:具体操作于哪个条目
第四部分:具体指定到哪个条目下的哪条记录(#标识通配符)
- 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)
- 使用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中获取数据
源代码
package com.excavator.contentproviderdemo;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.os.Bundle;import android.provider.ContactsContract.CommonDataKinds.Email;import android.provider.ContactsContract.CommonDataKinds.Phone;import android.provider.ContactsContract.Contacts;import android.util.Log;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ContentResolver contentResolver = getContentResolver();Cursor cursor=contentResolver.query(Contacts.CONTENT_URI, new String[]{Contacts._ID, Contacts.DISPLAY_NAME}, null, null, null);if (cursor!=null){while (cursor.moveToNext()) {int id=cursor.getInt(cursor.getColumnIndex(Contacts._ID));Log.i("info", "_id:" + id);Log.i("info", "name:" + cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)));Cursor cursor1=contentResolver.query(Phone.CONTENT_URI, new String[]{Phone.NUMBER, Phone.TYPE}, Phone.CONTACT_ID + "=" + id, null, null);//根据联系人ID查询出联系人的电话号码if (cursor1!=null){while (cursor1.moveToNext()) {int type=cursor1.getInt(cursor1.getColumnIndex(Phone.TYPE));if (type==Phone.TYPE_HOME) {Log.i("info", "家庭电话:" + cursor1.getString(cursor1.getColumnIndex(Phone.NUMBER)));}else if (type==Phone.TYPE_MOBILE){Log.i("info", "手机号:" + cursor1.getString(cursor1.getColumnIndex(Phone.NUMBER)));}}cursor1.close();}//根据联系人的ID去查询联系人的邮箱地址Cursor cursor2 = contentResolver.query(Email.CONTENT_URI, new String[]{Email.DATA, Email.TYPE}, Email.CONTACT_ID + "=" + id, null, null);if (cursor2!=null){while (cursor2.moveToNext()) {int type = cursor2.getInt(cursor2.getColumnIndex(Email.DATA));if (type==Email.TYPE_WORK){Log.i("info", "工作邮箱:" + cursor2.getString(cursor2.getColumnIndex(Email.DATA)));}}cursor2.close();}}cursor.close();}}}
package com.excavator.contentproviderdemo2;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentUris;import android.content.ContentValues;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract.CommonDataKinds.Phone;import android.provider.ContactsContract.Data;import android.provider.ContactsContract.CommonDataKinds.StructuredName;import android.provider.ContactsContract.RawContacts;public class MainActivity extends Activity {Uri uri;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ContentResolver contentResolver = getContentResolver();//向联系人中插入一行数据ContentValues contentValues = new ContentValues();uri = contentResolver.insert(RawContacts.CONTENT_URI, contentValues);Long raw_contact_id = ContentUris.parseId(uri);contentValues.clear();//插入人名contentValues.put(StructuredName.RAW_CONTACT_ID, raw_contact_id);contentValues.put(StructuredName.DISPLAY_NAME,"张三");contentValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);uri = contentResolver.insert(Data.CONTENT_URI,contentValues);//插入电话信息contentValues.clear();contentValues.put(Phone.RAW_CONTACT_ID, raw_contact_id);contentValues.put(Phone.NUMBER, "123456789");contentValues.put(Phone.MIMETYPE, Phone.CONTENT_ITEM_TYPE);uri = contentResolver.insert(Data.CONTENT_URI, contentValues);}}
Broadcast(广播): 是一种广泛运用在应用程序之间传输信息的机制。
BroadcastReceiver(广播接收器): 是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。
当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent匹配,若匹配则就会调用BroadcastReceiver的onReceive()方法。所以当我们定义一个BroadcastReceiver时,都需要实现onReceive()方法。
注意:
BroadcastReceiver需要注册
静态注册
代码注册
发送标准广播代码:
Intent intent = new Intent();intent.putExtra("msg","这是一条普通广播");intent.setAction("BC_One");sendBroadcast(intent);
接收器代码实现:
package com.excavator.broadcastreceiverdemo;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class BC1 extends BroadcastReceiver {public BC1() {}@Overridepublic void onReceive(Context context, Intent intent) {// TODO: This method is called when the BroadcastReceiver is receiving// an Intent broadcast.String s = intent.getStringExtra("msg");System.out.println("receiver1接收到消息:"+s);}}
静态注册代码:
<receiverandroid:name=".BC1"android:enabled="true"android:exported="true" ><intent-filter><action android:name="BC_One" /></intent-filter></receiver>
动态注册代码:
IntentFilter intentFilter = new IntentFilter("BC_One");BC2 bc2 = new BC2();registerReceiver(bc2, intentFilter);
注意:动态注册的最后需要在onDestroy()方法中调用unregisterReceiver()方法卸载掉
发送有序广播:
Intent intent2 = new Intent();intent2.putExtra("msg","这是一条有序广播");intent2.setAction("BC_One");sendOrderedBroadcast(intent2, null);
发送异步广播:
Intent intent3 = new Intent();intent3.putExtra("msg", "这是一条有序广播");intent3.setAction("BC_Three");sendStickyBroadcast(intent3);//先发送后注册IntentFilter intentFilter = new IntentFilter("BC_Three");BC3 bc3 = new BC3();registerReceiver(bc3,intentFilter);
最后需要在清单文件中加权限
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
定义:
- 后台运行,不可见,没有界面
- 优先级高于Activity
用途:
- 播放音乐、记录地理信息位置的改变、监听某种动作
注意:
- 运行在主线程,不能用来做耗时的请求或者动作
- 可以在服务中开一个线程,在线程中做耗时动作
类型:
- 本地服务(Local Service)
- 应用程序内部
- startService stopService stopSelf stopSelfResult
- bindService unbingService
- 远程服务(Remote Service)
- Android系统内部的应用程序之间
- 定义IBind接口
Service生命周期:

Start方式特点:
Bind方式特点:
MyStartService.java
public class MyStartService extends Service {public MyStartService() {}@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.Log.i("info","Service--onBind");return null;}@Overridepublic void onCreate() {Log.i("info","Service--onCreate");super.onCreate();}@Overridepublic void onDestroy() {Log.i("info","Service--onDestroy");super.onDestroy();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i("info","Service--onStartCommand");return super.onStartCommand(intent, flags, startId);}}
注意:onCreate()方法是在服务第一创建时调用,而onStartCommand()方法则在每次启动服务时都会调用,第一次启动服务时,由于服务此时还未创建,所以两个方法都会执行,之后启动服务只会有onSartCommand()方法得到执行。
MyBindService.java
public class MyBindService extends Service {public MyBindService() {}//在活动新建一个继承自Binder的类,然后在里面提供各种方法public class MyBinder extends Binder{public MyBindService getService() {return MyBindService.this;}}//在onBind()中返回实例@Overridepublic IBinder onBind(Intent intent) {Log.i("info", "BindService--onBind");return new MyBinder();}@Overridepublic void onCreate() {Log.i("info","BindService--onCreate");super.onCreate();}@Overridepublic void onDestroy() {Log.i("info","BindService--onDestroy");super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {Log.i("info", "BindService--onUnbind");return super.onUnbind(intent);}public void Play() {Log.i("info","播放");}public void Pause() {Log.i("info","暂停");}public void Previous() {Log.i("info","上一首");}public void Next() {Log.i("info","下一首");}}
MainActivity.java
public class MainActivity extends Activity {Intent intent1;Intent intent2;MyBindService service;ServiceConnection conn=new ServiceConnection() {//当启动源跟Service成功连接之后会自动调用这个方法@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {service=((MyBindService.MyBinder) binder).getService();}//当启动源跟Service连接意外丢失会调用这个方法//比如Service崩溃或者被强行杀死@Overridepublic void onServiceDisconnected(ComponentName name) {}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void doClick(View v){switch (v.getId()){case R.id.start:intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;case R.id.bind:intent2 = new Intent(MainActivity.this,MyBindService.class);bindService(intent2,conn,Service.BIND_AUTO_CREATE);break;case R.id.play:service.Play();break;case R.id.pause:service.Pause();break;case R.id.next:service.Next();break;case R.id.previous:service.Previous();break;case R.id.unbind:unbindService(conn);break;default:break;}}}