本文實例講述了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,加載更多的觸發條件
加載下一頁數據完成后,需要添加到上一頁數據的最后面
//監聽其滾動狀態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(); }}以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答