你的位置:首页 > 操作系统

[操作系统]Android 手机卫士7


1,黑名单数据库创建

三个字段(_id 自增长字段 phone 黑名单号码 mode 拦截类型)
创建表的sql语句
create table blacknumber (_id integer primary key autoincrement , phone varchar(20), mode varchar(5));
结合项目,去创建数据库,以及相应的表

2.BlackNumberDao 

 BlackNumberDao单例模式

 1 package com.itheima.mobilesafe74.db.dao; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 import android.content.ContentValues; 7 import android.content.Context; 8 import android.database.Cursor; 9 import android.database.sqlite.SQLiteDatabase; 10  11 import com.itheima.mobilesafe74.db.BlackNumberOpenHelper; 12 import com.itheima.mobilesafe74.db.domain.BlackNumberInfo; 13  14 public class BlackNumberDao { 15   private BlackNumberOpenHelper blackNumberOpenHelper; 16   //BlackNumberDao单例模式 17   //1,私有化构造方法 18   private BlackNumberDao(Context context){ 19     //创建数据库已经其表机构 20     blackNumberOpenHelper = new BlackNumberOpenHelper(context); 21   } 22   //2,声明一个当前类的对象 23   private static BlackNumberDao blackNumberDao = null; 24   //3,提供一个静态方法,如果当前类的对象为空,创建一个新的 25   public static BlackNumberDao getInstance(Context context){ 26     if(blackNumberDao == null){ 27       blackNumberDao = new BlackNumberDao(context); 28     } 29     return blackNumberDao; 30   } 31    32   /**增加一个条目 33    * @param phone  拦截的电话号码 34    * @param mode  拦截类型(1:短信  2:电话  3:拦截所有(短信+电话)) 35   */ 36   public void insert(String phone,String mode){ 37     //1,开启数据库,准备做写入操作 38     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase(); 39  40     ContentValues values = new ContentValues(); 41     values.put("phone", phone); 42     values.put("mode", mode); 43     db.insert("blacknumber", null, values); 44      45     db.close(); 46   } 47    48   /**从数据库中删除一条电话号码 49    * @param phone  删除电话号码 50   */ 51   public void delete(String phone){ 52     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase(); 53  54     db.delete("blacknumber", "phone = ?", new String[]{phone}); 55      56     db.close(); 57   } 58    59   /** 60    * 根据电话号码去,更新拦截模式 61    * @param phone  更新拦截模式的电话号码 62    * @param mode  要更新为的模式(1:短信  2:电话  3:拦截所有(短信+电话) 63   */ 64   public void update(String phone,String mode){ 65     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase(); 66  67     ContentValues contentValues = new ContentValues(); 68     contentValues.put("mode", mode); 69      70     db.update("blacknumber", contentValues, "phone = ?", new String[]{phone}); 71      72     db.close(); 73   } 74    75   /** 76    * @return  查询到数据库中所有的号码以及拦截类型所在的集合 77   */ 78   public List<BlackNumberInfo> findAll(){ 79     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase(); 80  81     Cursor cursor = db.query("blacknumber", new String[]{"phone","mode"}, null, null, null, null, "_id desc"); 82     List<BlackNumberInfo> blackNumberList = new ArrayList<BlackNumberInfo>(); 83     while(cursor.moveToNext()){ 84       BlackNumberInfo blackNumberInfo = new BlackNumberInfo(); 85       blackNumberInfo.phone = cursor.getString(0); 86       blackNumberInfo.mode = cursor.getString(1); 87       blackNumberList.add(blackNumberInfo); 88     } 89     cursor.close(); 90     db.close(); 91      92     return blackNumberList; 93   } 94    95   /** 96    * 每次查询20条数据 97    * @param index  查询的索引值 98   */ 99   public List<BlackNumberInfo> find(int index){100     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase();101 102     Cursor cursor = db.rawQuery("select phone,mode from blacknumber order by _id desc limit ?,20;", new String[]{index+""});103     104     List<BlackNumberInfo> blackNumberList = new ArrayList<BlackNumberInfo>();105     while(cursor.moveToNext()){106       BlackNumberInfo blackNumberInfo = new BlackNumberInfo();107       blackNumberInfo.phone = cursor.getString(0);108       blackNumberInfo.mode = cursor.getString(1);109       blackNumberList.add(blackNumberInfo);110     }111     cursor.close();112     db.close();113     114     return blackNumberList;115   }116   117   /**118    * @return  数据库中数据的总条目个数,返回0代表没有数据或异常119   */120   public int getCount(){121     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase();122     int count = 0;123     Cursor cursor = db.rawQuery("select count(*) from blacknumber;", null);124     if(cursor.moveToNext()){125       count = cursor.getInt(0);126     }127     128     cursor.close();129     db.close();130     return count;131   }132   133   /**134    * @param phone  作为查询条件的电话号码135    * @return  传入电话号码的拦截模式  1:短信  2:电话  3:所有  0:没有此条数据136   */137   public int getMode(String phone){138     SQLiteDatabase db = blackNumberOpenHelper.getWritableDatabase();139     int mode = 0;140     Cursor cursor = db.query("blacknumber", new String[]{"mode"}, "phone = ?", new String[]{phone}, null, null,null);141     if(cursor.moveToNext()){142       mode = cursor.getInt(0);143     }144     145     cursor.close();146     db.close();147     return mode;148   }149 }

BlackNumberDao

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

加载下一页数据完成后,需要添加到上一页数据的最后面 20 40 60 80 100

//监听其滚动状态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方法
iTelephony.endCall();

 1 package com.itheima.mobilesafe74.service; 2  3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5  6 import com.android.internal.telephony.ITelephony; 7 import com.itheima.mobilesafe74.db.dao.BlackNumberDao; 8 import com.itheima.mobilesafe74.service.AddressService.MyPhoneStateListener; 9 import android.app.Service; 10 import android.content.BroadcastReceiver; 11 import android.content.Context; 12 import android.content.Intent; 13 import android.content.IntentFilter; 14 import android.os.IBinder; 15 import android.telephony.PhoneStateListener; 16 import android.telephony.SmsMessage; 17 import android.telephony.TelephonyManager; 18 import android.util.Log; 19 import android.view.WindowManager; 20  21 public class BlackNumberService extends Service { 22   private InnerSmsReceiver mInnerSmsReceiver; 23   private BlackNumberDao mDao; 24   private TelephonyManager mTM; 25   private MyPhoneStateListener mPhoneStateListener; 26   @Override 27   public void onCreate() { 28     mDao = BlackNumberDao.getInstance(getApplicationContext()); 29      30     //拦截短信 31     IntentFilter intentFilter = new IntentFilter(); 32     intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED"); 33     intentFilter.setPriority(1000); 34      35     mInnerSmsReceiver = new InnerSmsReceiver(); 36     registerReceiver(mInnerSmsReceiver, intentFilter); 37      38     //监听电话的状态 39     //1,电话管理者对象 40     mTM = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 41     //2,监听电话状态 42     mPhoneStateListener = new MyPhoneStateListener(); 43     mTM.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); 44      45     super.onCreate(); 46   } 47    48   class MyPhoneStateListener extends PhoneStateListener{ 49     //3,手动重写,电话状态发生改变会触发的方法 50     @Override 51     public void onCallStateChanged(int state, String incomingNumber) { 52       switch (state) { 53       case TelephonyManager.CALL_STATE_IDLE: 54         break; 55       case TelephonyManager.CALL_STATE_OFFHOOK: 56         break; 57       case TelephonyManager.CALL_STATE_RINGING: 58         //挂断电话   aidl文件中去了 59 //        mTM.endCall(); 60         endCall(incomingNumber); 61         break; 62       } 63       super.onCallStateChanged(state, incomingNumber); 64     } 65   } 66   class InnerSmsReceiver extends BroadcastReceiver{ 67     @Override 68     public void onReceive(Context context, Intent intent) { 69       //获取短信内容,获取发送短信电话号码,如果此电话号码在黑名单中,并且拦截模式也为1(短信)或者3(所有),拦截短信 70       //1,获取短信内容 71       Object[] objects = (Object[]) intent.getExtras().get("pdus"); 72       //2,循环遍历短信过程 73       for (Object object : objects) { 74         //3,获取短信对象 75         SmsMessage sms = SmsMessage.createFromPdu((byte[])object); 76         //4,获取短信对象的基本信息 77         String originatingAddress = sms.getOriginatingAddress(); 78         String messageBody = sms.getMessageBody(); 79          80         int mode = mDao.getMode(originatingAddress); 81          82         if(mode == 1 || mode == 3){ 83           //拦截短信(android 4.4版本失效  短信数据库,删除) 84           abortBroadcast(); 85         } 86       } 87     } 88   } 89    90   @Override 91   public IBinder onBind(Intent arg0) { 92     return null; 93   } 94   public void endCall(String phone) { 95     int mode = mDao.getMode(phone); 96      97     if(mode == 2 || mode == 3){ 98 //      ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); 99       //ServiceManager此类android对开发者隐藏,所以不能去直接调用其方法,需要反射调用100       try {101         //1,获取ServiceManager字节码文件102         Class<?> clazz = Class.forName("android.os.ServiceManager");103         //2,获取方法104         Method method = clazz.getMethod("getService", String.class);105         //3,反射调用此方法106         IBinder iBinder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);107         //4,调用获取aidl文件对象方法108         ITelephony iTelephony = ITelephony.Stub.asInterface(iBinder);109         //5,调用在aidl中隐藏的endCall方法110         iTelephony.endCall();111       } catch (Exception e) {112         e.printStackTrace();113       }114     }115   }116   @Override117   public void onDestroy() {118     if(mInnerSmsReceiver!=null){119       unregisterReceiver(mInnerSmsReceiver);120     }121     super.onDestroy();122   }123 }

BlackNumberService