Android项目实现黑名单拦截效果

本文实例讲述了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,加载更多的触发条件

  1. 监听状态改变
  2. 滚动到最底部,最后一个listView的条目可见
  3. 滚动状态发生改变 滚动------>停止(空闲)

加载下一页数据完成后,需要添加到上一页数据的最后面

//监听其滚动状态

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();

}

}

以上是 Android项目实现黑名单拦截效果 的全部内容, 来源链接: utcz.com/z/329832.html

回到顶部