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();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。