Android项目实现黑名单拦截效果
程序员文章站
2024-03-04 19:30:42
本文实例讲述了android编程中黑名单的实现方法。分享给大家供大家参考,具体如下:
1,黑名单数据库创建
三个字段(_id 自增长字段 phone 黑名单号码...
本文实例讲述了android编程中黑名单的实现方法。分享给大家供大家参考,具体如下:
1,黑名单数据库创建
三个字段(_id 自增长字段 phone 黑名单号码 mode 拦截类型)
创建表的sql语句
create table blacknumber (_id integer primary key autoincrement , phone varchar(20), mode varchar(5));
结合项目,去创建数据库,以及相应的表
2.blacknumberdao
blacknumberdao单例模式
package com.itheima.mobilesafe74.db.dao; import java.util.arraylist; import java.util.list; import android.content.contentvalues; import android.content.context; import android.database.cursor; import android.database.sqlite.sqlitedatabase; import com.itheima.mobilesafe74.db.blacknumberopenhelper; import com.itheima.mobilesafe74.db.domain.blacknumberinfo; public class blacknumberdao { private blacknumberopenhelper blacknumberopenhelper; //blacknumberdao单例模式 //1,私有化构造方法 private blacknumberdao(context context){ //创建数据库已经其表机构 blacknumberopenhelper = new blacknumberopenhelper(context); } //2,声明一个当前类的对象 private static blacknumberdao blacknumberdao = null; //3,提供一个静态方法,如果当前类的对象为空,创建一个新的 public static blacknumberdao getinstance(context context){ if(blacknumberdao == null){ blacknumberdao = new blacknumberdao(context); } return blacknumberdao; } /**增加一个条目 * @param phone 拦截的电话号码 * @param mode 拦截类型(1:短信 2:电话 3:拦截所有(短信+电话)) */ public void insert(string phone,string mode){ //1,开启数据库,准备做写入操作 sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); contentvalues values = new contentvalues(); values.put("phone", phone); values.put("mode", mode); db.insert("blacknumber", null, values); db.close(); } /**从数据库中删除一条电话号码 * @param phone 删除电话号码 */ public void delete(string phone){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); db.delete("blacknumber", "phone = ?", new string[]{phone}); db.close(); } /** * 根据电话号码去,更新拦截模式 * @param phone 更新拦截模式的电话号码 * @param mode 要更新为的模式(1:短信 2:电话 3:拦截所有(短信+电话) */ public void update(string phone,string mode){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); contentvalues contentvalues = new contentvalues(); contentvalues.put("mode", mode); db.update("blacknumber", contentvalues, "phone = ?", new string[]{phone}); db.close(); } /** * @return 查询到数据库中所有的号码以及拦截类型所在的集合 */ public list<blacknumberinfo> findall(){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); cursor cursor = db.query("blacknumber", new string[]{"phone","mode"}, null, null, null, null, "_id desc"); list<blacknumberinfo> blacknumberlist = new arraylist<blacknumberinfo>(); while(cursor.movetonext()){ blacknumberinfo blacknumberinfo = new blacknumberinfo(); blacknumberinfo.phone = cursor.getstring(0); blacknumberinfo.mode = cursor.getstring(1); blacknumberlist.add(blacknumberinfo); } cursor.close(); db.close(); return blacknumberlist; } /** * 每次查询20条数据 * @param index 查询的索引值 */ public list<blacknumberinfo> find(int index){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); cursor cursor = db.rawquery("select phone,mode from blacknumber order by _id desc limit ?,20;", new string[]{index+""}); list<blacknumberinfo> blacknumberlist = new arraylist<blacknumberinfo>(); while(cursor.movetonext()){ blacknumberinfo blacknumberinfo = new blacknumberinfo(); blacknumberinfo.phone = cursor.getstring(0); blacknumberinfo.mode = cursor.getstring(1); blacknumberlist.add(blacknumberinfo); } cursor.close(); db.close(); return blacknumberlist; } /** * @return 数据库中数据的总条目个数,返回0代表没有数据或异常 */ public int getcount(){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); int count = 0; cursor cursor = db.rawquery("select count(*) from blacknumber;", null); if(cursor.movetonext()){ count = cursor.getint(0); } cursor.close(); db.close(); return count; } /** * @param phone 作为查询条件的电话号码 * @return 传入电话号码的拦截模式 1:短信 2:电话 3:所有 0:没有此条数据 */ public int getmode(string phone){ sqlitedatabase db = blacknumberopenhelper.getwritabledatabase(); int mode = 0; cursor cursor = db.query("blacknumber", new string[]{"mode"}, "phone = ?", new string[]{phone}, null, null,null); if(cursor.movetonext()){ mode = cursor.getint(0); } cursor.close(); db.close(); return mode; } }
3,加载更多的触发条件
- 监听状态改变
- 滚动到最底部,最后一个listview的条目可见
- 滚动状态发生改变 滚动------>停止(空闲)
加载下一页数据完成后,需要添加到上一页数据的最后面
//监听其滚动状态 lv_blacknumber.setonscrolllistener(new onscrolllistener() { //滚动过程中,状态发生改变调用方法() @override public void onscrollstatechanged(abslistview view, int scrollstate) { // 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()){ //加载下一页数据 new thread(){ public void run() { //1,获取操作黑名单数据库的对象 mdao = blacknumberdao.getinstance(getapplicationcontext()); //2,查询部分数据 list<blacknumberinfo> moredata = mdao.find(mblacknumberlist.size()); //3,添加下一页数据的过程 mblacknumberlist.addall(moredata); //4,通知数据适配器刷新 mhandler.sendemptymessage(0); } }.start(); } } } } //滚动过程中调用方法 @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { } });
4.拦截短信
短信在接受的时候,广播发送,监听广播接受者,拦截短信(有序)
将广播的优先级级别提高到最高 (1000)
5.拦截电话
有电话拨入,处于响铃状态,响铃状态通过代码去挂断电话(aidl,反射),拦截电话
挂断电话号码的方法,放置在了aidl文件中名称为endcall
在此处去查看telephonemanager源码,去查找获取itelephony对象的方法
servicemanager此类android对开发者隐藏,所以不能去直接调用其方法,所以需要反射调用
itelephony.stub.asinterface(servicemanager.getservice(context.telephony_service)); <uses-permission android:name="android.permission.call_phone"/> //1,获取servicemanager字节码文件 class<?> clazz = class.forname("android.os.servicemanager"); //2,获取方法 method method = clazz.getmethod("getservice", string.class); //3,反射调用此方法 ibinder ibinder = (ibinder) method.invoke(null, context.telephony_service); //4,调用获取aidl文件对象方法 itelephony itelephony = itelephony.stub.asinterface(ibinder); //5,调用在aidl中隐藏的endcall方法
blacknumberservice
itelephony.endcall(); package com.itheima.mobilesafe74.service; import java.lang.reflect.invocationtargetexception; import java.lang.reflect.method; import com.android.internal.telephony.itelephony; import com.itheima.mobilesafe74.db.dao.blacknumberdao; import com.itheima.mobilesafe74.service.addressservice.myphonestatelistener; import android.app.service; import android.content.broadcastreceiver; import android.content.context; import android.content.intent; import android.content.intentfilter; import android.os.ibinder; import android.telephony.phonestatelistener; import android.telephony.smsmessage; import android.telephony.telephonymanager; import android.util.log; import android.view.windowmanager; public class blacknumberservice extends service { private innersmsreceiver minnersmsreceiver; private blacknumberdao mdao; private telephonymanager mtm; private myphonestatelistener mphonestatelistener; @override public void oncreate() { mdao = blacknumberdao.getinstance(getapplicationcontext()); //拦截短信 intentfilter intentfilter = new intentfilter(); intentfilter.addaction("android.provider.telephony.sms_received"); intentfilter.setpriority(1000); minnersmsreceiver = new innersmsreceiver(); registerreceiver(minnersmsreceiver, intentfilter); //监听电话的状态 //1,电话管理者对象 mtm = (telephonymanager) getsystemservice(context.telephony_service); //2,监听电话状态 mphonestatelistener = new myphonestatelistener(); mtm.listen(mphonestatelistener, phonestatelistener.listen_call_state); super.oncreate(); } class myphonestatelistener extends phonestatelistener{ //3,手动重写,电话状态发生改变会触发的方法 @override public void oncallstatechanged(int state, string incomingnumber) { switch (state) { case telephonymanager.call_state_idle: break; case telephonymanager.call_state_offhook: break; case telephonymanager.call_state_ringing: //挂断电话 aidl文件中去了 // mtm.endcall(); endcall(incomingnumber); break; } super.oncallstatechanged(state, incomingnumber); } } class innersmsreceiver extends broadcastreceiver{ @override public void onreceive(context context, intent intent) { //获取短信内容,获取发送短信电话号码,如果此电话号码在黑名单中,并且拦截模式也为1(短信)或者3(所有),拦截短信 //1,获取短信内容 object[] objects = (object[]) intent.getextras().get("pdus"); //2,循环遍历短信过程 for (object object : objects) { //3,获取短信对象 smsmessage sms = smsmessage.createfrompdu((byte[])object); //4,获取短信对象的基本信息 string originatingaddress = sms.getoriginatingaddress(); string messagebody = sms.getmessagebody(); int mode = mdao.getmode(originatingaddress); if(mode == 1 || mode == 3){ //拦截短信(android 4.4版本失效 短信数据库,删除) abortbroadcast(); } } } } @override public ibinder onbind(intent arg0) { return null; } public void endcall(string phone) { int mode = 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,获取方法 method method = clazz.getmethod("getservice", string.class); //3,反射调用此方法 ibinder ibinder = (ibinder) method.invoke(null, context.telephony_service); //4,调用获取aidl文件对象方法 itelephony itelephony = itelephony.stub.asinterface(ibinder); //5,调用在aidl中隐藏的endcall方法 itelephony.endcall(); } catch (exception e) { e.printstacktrace(); } } } @override public void ondestroy() { if(minnersmsreceiver!=null){ unregisterreceiver(minnersmsreceiver); } super.ondestroy(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Ajax异步无刷新对局部数据更新