Android项目实现黑名单拦截效果
本文实例讲述了Android编程中黑名单的实现方法。分享给大家供大家参考,具体如下:
1,黑名单数据库创建
三个字段(_id自增长字段phone黑名单号码mode拦截类型)
创建表的sql语句
createtableblacknumber(_idintegerprimarykeyautoincrement,phonevarchar(20),modevarchar(5));
结合项目,去创建数据库,以及相应的表
2.BlackNumberDao
BlackNumberDao单例模式
packagecom.itheima.mobilesafe74.db.dao; importjava.util.ArrayList; importjava.util.List; importandroid.content.ContentValues; importandroid.content.Context; importandroid.database.Cursor; importandroid.database.sqlite.SQLiteDatabase; importcom.itheima.mobilesafe74.db.BlackNumberOpenHelper; importcom.itheima.mobilesafe74.db.domain.BlackNumberInfo; publicclassBlackNumberDao{ privateBlackNumberOpenHelperblackNumberOpenHelper; //BlackNumberDao单例模式 //1,私有化构造方法 privateBlackNumberDao(Contextcontext){ //创建数据库已经其表机构 blackNumberOpenHelper=newBlackNumberOpenHelper(context); } //2,声明一个当前类的对象 privatestaticBlackNumberDaoblackNumberDao=null; //3,提供一个静态方法,如果当前类的对象为空,创建一个新的 publicstaticBlackNumberDaogetInstance(Contextcontext){ if(blackNumberDao==null){ blackNumberDao=newBlackNumberDao(context); } returnblackNumberDao; } /**增加一个条目 *@paramphone拦截的电话号码 *@parammode拦截类型(1:短信2:电话3:拦截所有(短信+电话)) */ publicvoidinsert(Stringphone,Stringmode){ //1,开启数据库,准备做写入操作 SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); ContentValuesvalues=newContentValues(); values.put("phone",phone); values.put("mode",mode); db.insert("blacknumber",null,values); db.close(); } /**从数据库中删除一条电话号码 *@paramphone删除电话号码 */ publicvoiddelete(Stringphone){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); db.delete("blacknumber","phone=?",newString[]{phone}); db.close(); } /** *根据电话号码去,更新拦截模式 *@paramphone更新拦截模式的电话号码 *@parammode要更新为的模式(1:短信2:电话3:拦截所有(短信+电话) */ publicvoidupdate(Stringphone,Stringmode){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); ContentValuescontentValues=newContentValues(); contentValues.put("mode",mode); db.update("blacknumber",contentValues,"phone=?",newString[]{phone}); db.close(); } /** *@return查询到数据库中所有的号码以及拦截类型所在的集合 */ publicList<BlackNumberInfo>findAll(){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); Cursorcursor=db.query("blacknumber",newString[]{"phone","mode"},null,null,null,null,"_iddesc"); List<BlackNumberInfo>blackNumberList=newArrayList<BlackNumberInfo>(); while(cursor.moveToNext()){ BlackNumberInfoblackNumberInfo=newBlackNumberInfo(); blackNumberInfo.phone=cursor.getString(0); blackNumberInfo.mode=cursor.getString(1); blackNumberList.add(blackNumberInfo); } cursor.close(); db.close(); returnblackNumberList; } /** *每次查询20条数据 *@paramindex查询的索引值 */ publicList<BlackNumberInfo>find(intindex){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); Cursorcursor=db.rawQuery("selectphone,modefromblacknumberorderby_iddesclimit?,20;",newString[]{index+""}); List<BlackNumberInfo>blackNumberList=newArrayList<BlackNumberInfo>(); while(cursor.moveToNext()){ BlackNumberInfoblackNumberInfo=newBlackNumberInfo(); blackNumberInfo.phone=cursor.getString(0); blackNumberInfo.mode=cursor.getString(1); blackNumberList.add(blackNumberInfo); } cursor.close(); db.close(); returnblackNumberList; } /** *@return数据库中数据的总条目个数,返回0代表没有数据或异常 */ publicintgetCount(){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); intcount=0; Cursorcursor=db.rawQuery("selectcount(*)fromblacknumber;",null); if(cursor.moveToNext()){ count=cursor.getInt(0); } cursor.close(); db.close(); returncount; } /** *@paramphone作为查询条件的电话号码 *@return传入电话号码的拦截模式1:短信2:电话3:所有0:没有此条数据 */ publicintgetMode(Stringphone){ SQLiteDatabasedb=blackNumberOpenHelper.getWritableDatabase(); intmode=0; Cursorcursor=db.query("blacknumber",newString[]{"mode"},"phone=?",newString[]{phone},null,null,null); if(cursor.moveToNext()){ mode=cursor.getInt(0); } cursor.close(); db.close(); returnmode; } }
3,加载更多的触发条件
- 监听状态改变
- 滚动到最底部,最后一个listView的条目可见
- 滚动状态发生改变滚动------>停止(空闲)
加载下一页数据完成后,需要添加到上一页数据的最后面
//监听其滚动状态 lv_blacknumber.setOnScrollListener(newOnScrollListener(){ //滚动过程中,状态发生改变调用方法() @Override publicvoidonScrollStateChanged(AbsListViewview,intscrollState){ //OnScrollListener.SCROLL_STATE_FLING飞速滚动 //OnScrollListener.SCROLL_STATE_IDLE空闲状态 //OnScrollListener.SCROLL_STATE_TOUCH_SCROLL拿手触摸着去滚动状态 if(mBlackNumberList!=null){ //条件一:滚动到停止状态 //条件二:最后一个条目可见(最后一个条目的索引值>=数据适配器中集合的总条目个数-1) if(scrollState==OnScrollListener.SCROLL_STATE_IDLE &&lv_blacknumber.getLastVisiblePosition()>=mBlackNumberList.size()-1 &&!mIsLoad){ /*mIsLoad防止重复加载的变量 如果当前正在加载mIsLoad就会为true,本次加载完毕后,再将mIsLoad改为false 如果下一次加载需要去做执行的时候,会判断上诉mIsLoad变量,是否为false,如果为true,就需要等待上一次加载完成,将其值 改为false后再去加载*/ //如果条目总数大于集合大小的时,才可以去继续加载更多 if(mCount>mBlackNumberList.size()){ //加载下一页数据 newThread(){ publicvoidrun(){ //1,获取操作黑名单数据库的对象 mDao=BlackNumberDao.getInstance(getApplicationContext()); //2,查询部分数据 List<BlackNumberInfo>moreData=mDao.find(mBlackNumberList.size()); //3,添加下一页数据的过程 mBlackNumberList.addAll(moreData); //4,通知数据适配器刷新 mHandler.sendEmptyMessage(0); } }.start(); } } } } //滚动过程中调用方法 @Override publicvoidonScroll(AbsListViewview,intfirstVisibleItem, intvisibleItemCount,inttotalItemCount){ } });
4.拦截短信
短信在接受的时候,广播发送,监听广播接受者,拦截短信(有序)
将广播的优先级级别提高到最高(1000)
5.拦截电话
有电话拨入,处于响铃状态,响铃状态通过代码去挂断电话(aidl,反射),拦截电话
挂断电话号码的方法,放置在了aidl文件中名称为endCall
在此处去查看TelePhoneManager源码,去查找获取ITelephony对象的方法
ServiceManager此类android对开发者隐藏,所以不能去直接调用其方法,所以需要反射调用
ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); <uses-permissionandroid:name="android.permission.CALL_PHONE"/> //1,获取ServiceManager字节码文件 Class<?>clazz=Class.forName("android.os.ServiceManager"); //2,获取方法 Methodmethod=clazz.getMethod("getService",String.class); //3,反射调用此方法 IBinderiBinder=(IBinder)method.invoke(null,Context.TELEPHONY_SERVICE); //4,调用获取aidl文件对象方法 ITelephonyiTelephony=ITelephony.Stub.asInterface(iBinder); //5,调用在aidl中隐藏的endCall方法
BlackNumberService
iTelephony.endCall(); packagecom.itheima.mobilesafe74.service; importjava.lang.reflect.InvocationTargetException; importjava.lang.reflect.Method; importcom.android.internal.telephony.ITelephony; importcom.itheima.mobilesafe74.db.dao.BlackNumberDao; importcom.itheima.mobilesafe74.service.AddressService.MyPhoneStateListener; importandroid.app.Service; importandroid.content.BroadcastReceiver; importandroid.content.Context; importandroid.content.Intent; importandroid.content.IntentFilter; importandroid.os.IBinder; importandroid.telephony.PhoneStateListener; importandroid.telephony.SmsMessage; importandroid.telephony.TelephonyManager; importandroid.util.Log; importandroid.view.WindowManager; publicclassBlackNumberServiceextendsService{ privateInnerSmsReceivermInnerSmsReceiver; privateBlackNumberDaomDao; privateTelephonyManagermTM; privateMyPhoneStateListenermPhoneStateListener; @Override publicvoidonCreate(){ mDao=BlackNumberDao.getInstance(getApplicationContext()); //拦截短信 IntentFilterintentFilter=newIntentFilter(); intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED"); intentFilter.setPriority(1000); mInnerSmsReceiver=newInnerSmsReceiver(); registerReceiver(mInnerSmsReceiver,intentFilter); //监听电话的状态 //1,电话管理者对象 mTM=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //2,监听电话状态 mPhoneStateListener=newMyPhoneStateListener(); mTM.listen(mPhoneStateListener,PhoneStateListener.LISTEN_CALL_STATE); super.onCreate(); } classMyPhoneStateListenerextendsPhoneStateListener{ //3,手动重写,电话状态发生改变会触发的方法 @Override publicvoidonCallStateChanged(intstate,StringincomingNumber){ switch(state){ caseTelephonyManager.CALL_STATE_IDLE: break; caseTelephonyManager.CALL_STATE_OFFHOOK: break; caseTelephonyManager.CALL_STATE_RINGING: //挂断电话aidl文件中去了 //mTM.endCall(); endCall(incomingNumber); break; } super.onCallStateChanged(state,incomingNumber); } } classInnerSmsReceiverextendsBroadcastReceiver{ @Override publicvoidonReceive(Contextcontext,Intentintent){ //获取短信内容,获取发送短信电话号码,如果此电话号码在黑名单中,并且拦截模式也为1(短信)或者3(所有),拦截短信 //1,获取短信内容 Object[]objects=(Object[])intent.getExtras().get("pdus"); //2,循环遍历短信过程 for(Objectobject:objects){ //3,获取短信对象 SmsMessagesms=SmsMessage.createFromPdu((byte[])object); //4,获取短信对象的基本信息 StringoriginatingAddress=sms.getOriginatingAddress(); StringmessageBody=sms.getMessageBody(); intmode=mDao.getMode(originatingAddress); if(mode==1||mode==3){ //拦截短信(android4.4版本失效短信数据库,删除) abortBroadcast(); } } } } @Override publicIBinderonBind(Intentarg0){ returnnull; } publicvoidendCall(Stringphone){ intmode=mDao.getMode(phone); if(mode==2||mode==3){ //ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); //ServiceManager此类android对开发者隐藏,所以不能去直接调用其方法,需要反射调用 try{ //1,获取ServiceManager字节码文件 Class<?>clazz=Class.forName("android.os.ServiceManager"); //2,获取方法 Methodmethod=clazz.getMethod("getService",String.class); //3,反射调用此方法 IBinderiBinder=(IBinder)method.invoke(null,Context.TELEPHONY_SERVICE); //4,调用获取aidl文件对象方法 ITelephonyiTelephony=ITelephony.Stub.asInterface(iBinder); //5,调用在aidl中隐藏的endCall方法 iTelephony.endCall(); }catch(Exceptione){ e.printStackTrace(); } } } @Override publicvoidonDestroy(){ if(mInnerSmsReceiver!=null){ unregisterReceiver(mInnerSmsReceiver); } super.onDestroy(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。