我的Android心得(4)--监听电话和短信是否来自关注对象--contentObserver
2014-05-23 12:41
375 查看
目标:在做毕业设计,要实现当手机有未接短信或者未接来电,并且来源号码是特定的一个关注对象时,触发提醒。
一开始是想用BroadcastReceiver,有短信、来电时Android系统会发出广播,我们只要注册一个BroadcastReceiver接收这些广播,在onReceive方法里面判断一些是否来自关注对象即可。
关于BroadcastReceiver,这篇文章讲的很细致 /article/5705168.html
注意的是BroadcastReceiver在onReceive方法里不能进行耗时的操作,Receiver也要在manifest里面注册
BroadcastReceiver的广播事件不仅有系统的事件,还可以应用自定义的广播事件。
以下是我的实现
PhoneBroadcastReceiver.java 文件:
SMSBroadcastReceiver.java
AndroidManifest.xml要注册Receiver
要用到的permission
这样实现的结果是一有短信或者一有电话,就触发提醒,所以有时候来电话响铃了,我已经准备接了,但它还提醒,我不得不关了提醒才能接电话。我要的是我有电话忘记接了,而且这来电是关注对象的,软件才要提醒我。所以BroadcastReceiver实现是不够完美的。
知道了来电短信都记录在Android中的数据库中,我们只要关注未接来电、未读短信的数据库有变化时,去检查号码是否为关注对象的即可,这时候用ContentObserver
这里给出监测来电的代码 /article/7562114.html
这里关于ContentObserver讲的比较详细 /article/4997788.html
我的实现是,开启一个Service,在Service中注册ContentObserver,就可以在退出该软件之后仍然监视着。经过我的小米手机实测,当你手动杀掉进程,该Service会被kill掉,即这时候无法监测来电和短信,但是过几分钟后该Service又能够开启
MissedCallOrSMSService.java,为了让Service重新start时又能观察内容,我不断地register和unregister
在Manifest里面注册
还是感谢一开始想错方向,学到了不少BroadcastReceiver的东西
一开始是想用BroadcastReceiver,有短信、来电时Android系统会发出广播,我们只要注册一个BroadcastReceiver接收这些广播,在onReceive方法里面判断一些是否来自关注对象即可。
关于BroadcastReceiver,这篇文章讲的很细致 /article/5705168.html
注意的是BroadcastReceiver在onReceive方法里不能进行耗时的操作,Receiver也要在manifest里面注册
BroadcastReceiver的广播事件不仅有系统的事件,还可以应用自定义的广播事件。
以下是我的实现
PhoneBroadcastReceiver.java 文件:
public class PhoneBroadcastReceiver extends BroadcastReceiver { // broadcast intent位于主线程,不能再onReceive执行太多操作,太多操作要开个Service @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { // 有电话打出去 } else { // 有电话打进来 // 取得telephony服务 TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); // 监听电话 MyPhoneStateListener my = new MyPhoneStateListener(); my.mContext = context; telephonyManager.listen(my, PhoneStateListener.LISTEN_CALL_STATE); } } private class MyPhoneStateListener extends PhoneStateListener { Context mContext = null; public void onCallStateChanged(int state,String incomingNumber){ //关注对象的电话号码 String targetPhoneNumber = new Target(this.mContext).getInfo(Target.TargetPhoneNumber); if(state == TelephonyManager.CALL_STATE_RINGING && incomingNumber.equals(targetPhoneNumber)) { // 触发提醒功能,在这里添加代码 } super.onCallStateChanged(state, incomingNumber); } } }
SMSBroadcastReceiver.java
public class SMSBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub // 取出所有短信 Object[] pdusData = (Object[])intent.getExtras().get("pdus"); for(int i = 0; i<pdusData.length; ++i) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])pdusData[i]); String phoneNumber = smsMessage.getOriginatingAddress(); String targetPhoneNumber = new Target(context).getInfo(Target.TargetPhoneNumber);//关注对象的电话号码 if(phoneNumber != null && phoneNumber.equals(targetPhoneNumber)) { //触发提醒,在这里添加代码 } } } }
AndroidManifest.xml要注册Receiver
<span style="white-space:pre"> </span><receiver android:name="com.example.mytest.SMSBroadcastReceiver" > <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> <receiver android:name="com.example.mytest.PhoneBroadcastReceiver" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> <action android:name="android.intent.action.BOOT_COMPLETED" /> <!-- 定义开机即启动 --> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver>
要用到的permission
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
这样实现的结果是一有短信或者一有电话,就触发提醒,所以有时候来电话响铃了,我已经准备接了,但它还提醒,我不得不关了提醒才能接电话。我要的是我有电话忘记接了,而且这来电是关注对象的,软件才要提醒我。所以BroadcastReceiver实现是不够完美的。
知道了来电短信都记录在Android中的数据库中,我们只要关注未接来电、未读短信的数据库有变化时,去检查号码是否为关注对象的即可,这时候用ContentObserver
这里给出监测来电的代码 /article/7562114.html
这里关于ContentObserver讲的比较详细 /article/4997788.html
我的实现是,开启一个Service,在Service中注册ContentObserver,就可以在退出该软件之后仍然监视着。经过我的小米手机实测,当你手动杀掉进程,该Service会被kill掉,即这时候无法监测来电和短信,但是过几分钟后该Service又能够开启
MissedCallOrSMSService.java,为了让Service重新start时又能观察内容,我不断地register和unregister
public class MissedCallOrSMSService extends Service{ private MissedCallContentObserver call; private MissedSMSContentObserver sms; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); call = new MissedCallContentObserver(this, new Handler()); sms = new MissedSMSContentObserver(this, new Handler()); // 在服务创建的时候注册ContentObserver,之后就会一直存在 this.getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, false, call); // 发现uri为content://sms/inbox无效,true表示同时监听子目录变化 this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, sms); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub this.getContentResolver().unregisterContentObserver(call); this.getContentResolver().unregisterContentObserver(sms); this.getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, false, call); this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, sms); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); this.getContentResolver().unregisterContentObserver(call); this.getContentResolver().unregisterContentObserver(sms); } } //当有call log时,就会对这个类进行回调 class MissedCallContentObserver extends ContentObserver { private Context ctx; private Target target; public MissedCallContentObserver(Context context, Handler handler) { super(handler); ctx = context; target = new Target(ctx); } @Override public void onChange(boolean selfChange) { Cursor csr = ctx.getContentResolver().query(Calls.CONTENT_URI, new String[] {Calls.NUMBER, Calls.TYPE, Calls.NEW}, null, null, Calls.DEFAULT_SORT_ORDER); if (csr != null) { if (csr.moveToFirst()) { int type = csr.getInt(csr.getColumnIndex(Calls.TYPE)); switch (type) { case Calls.MISSED_TYPE: if (csr.getInt(csr.getColumnIndex(Calls.NEW)) == 1 && csr.getString(csr.getColumnIndex(Calls.NUMBER)).equals(target.getInfo(Target.TargetPhoneNumber))) { Log.e("eee", target.getInfo(Target.TargetName) + " 打来未接电话"); Intent intent = new Intent(ctx, RemindService.class); intent.putExtra("remind_kind", "有未接电话啊!"); ctx.startService(intent); } break; case Calls.INCOMING_TYPE: break; case Calls.OUTGOING_TYPE: break; } } // release resource csr.close(); } } @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } } class MissedSMSContentObserver extends ContentObserver { private Context ctx; private Target target; public MissedSMSContentObserver(Context context, Handler handler) { super(handler); ctx = context; target = new Target(ctx); } @Override public void onChange(boolean selfChange) { // select _id, address, read from Uri where read = 0, 0 是未读 Cursor csr = ctx.getContentResolver().query(Uri.parse("content://sms/inbox"), new String[]{"_id", "address", "read"}, "read=?", new String[]{"0"}, "date desc"); if (csr != null) { if (csr.moveToFirst()) { if(csr.getString(csr.getColumnIndex("address")).equals(target.getInfo(Target.TargetPhoneNumber))){ Log.e("eee", target.getInfo(Target.TargetName) + " 发来短信"); // 提醒响铃 Intent intent =new Intent(ctx, RemindService.class); intent.putExtra("remind_kind", "有未接短信啊!"); ctx.startService(intent); } } // release resource csr.close(); } } @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } }
在Manifest里面注册
<service android:name="com.example.mytest.MissedCallOrSMSService"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/> <uses-permission android:name="android.permission.READ_SMS"/>这时候效果能够与我们想要的一样了。
还是感谢一开始想错方向,学到了不少BroadcastReceiver的东西
相关文章推荐
- [Android]监听(获取)未读短信和未接电话(demo)
- Android 通过监听收信箱获取短信,Cursor对象字段的详细信息
- Android发送短信,并监听短信发送后是否发送成功的实现方法
- android发送短信带监听是否发送成功功能
- android监听短信并判断是否未读
- android 使用广播接收者监听短信和拦截外拨电话
- android 使用广播接收者监听短信和拦截外拨电话
- Android开发之电话服务、SMS短信监听
- android 使用广播接收者监听短信和拦截外拨电话
- android监听短信并判断是否未读
- android 使用广播接收者监听短信和拦截外拨电话
- Android电话监听与短信监听
- Android监听SMS发送状态并获取短信服务中心号码
- android拨打电话和发送短信核心代码
- android监听用户的拨打电话的状态
- Android Call Log and SMS Delete 电话记录和短信删除
- Android监听SMS发送状态并获取短信服务中心号码
- Android判断网络状态是否断开+Android完全关闭应用程序+ 本文讲述了Android中不同Activity之间的数据传递 — Bundle对象的实现(-)+Android中Bundle的使用示例
- Android手机上监听短信的两种方式【转】
- Ohone/android 监听电话