Android編程中黑名單的實(shí)現(xiàn)方法
本文實(shí)例講述了Android編程中黑名單的實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:
說(shuō)明:由于掛斷電話android api不是對(duì)外開(kāi)放的,所以需要使用反射的方法得到撥打電話的服務(wù)。
1.將android源代碼中的"aidl"文件拷貝到項(xiàng)目中
這樣項(xiàng)目中會(huì)生成兩個(gè)包:android.telephony;此包中文件為:NeighboringCellInfo.aidl
com.android.internal.telephony;此包中文件為:ITelephony.aidl
2.通過(guò)反射掛斷電話;代碼如下:
/** * 掛斷電話 */ public void endCall() { try { Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class); IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE}); ITelephony telephony = ITelephony.Stub.asInterface(binder); telephony.endCall(); } catch (Exception e) { e.printStackTrace(); } }
3.刪除通話記錄中的記錄
/** * 刪除呼叫記錄 */ public void deleteCallLog(String incomingNumber) { ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null,"number=?", new String[]{incomingNumber}, null); if(cursor.moveToNext()){ String id = cursor.getString(cursor.getColumnIndex("_id")); resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?", new String[]{id}); } }
4.直接這樣調(diào)用是不能刪除電話記錄的,因?yàn)樯呻娫捰涗浀倪^(guò)程是一個(gè)異步的過(guò)程,在掛斷電話之后不能立即刪除電話記錄,所以這里要使用ContentObserver(內(nèi)容觀察者)
private class MyObserver extends ContentObserver{ private String incomingNumber; public MyObserver(Handler handler,String incomingNumber) { super(handler); this.incomingNumber = incomingNumber; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); deleteCallLog(incomingNumber); getContentResolver().unregisterContentObserver(this); } }
6.最后把整個(gè)service代碼貼到下面
public class AddressService extends Service{ private static final String TAG = "AddressService"; private TelephonyManager manager; private MyPhoneListener listener; private WindowManager wManager; private View view; private SharedPreferences sp; long startTime = 0; long endTime = 0; private BlackNumberDao dao; @Override public IBinder onBind(Intent arg0) { return null; } /** * 服務(wù)第一次被創(chuàng)建的時(shí)候調(diào)用的方法 * 服務(wù)被初始化時(shí)調(diào)用的方法 */ @Override public void onCreate() { super.onCreate(); listener = new MyPhoneListener(); manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); wManager = (WindowManager) this.getSystemService(WINDOW_SERVICE); manager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); sp = getSharedPreferences("config", MODE_PRIVATE); dao = new BlackNumberDao(this); // if(3000>(endTime - startTime)){ // String ns = Context.NOTIFICATION_SERVICE; // NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); // //定義通知欄展現(xiàn)的內(nèi)容信息 // int icon = R.drawable.icon5; // CharSequence tickerText = "我的通知欄標(biāo)題"; // long when = System.currentTimeMillis(); // Notification notification = new Notification(icon, tickerText, when); // //定義下拉通知欄時(shí)要展現(xiàn)的內(nèi)容信息 // Context context = getApplicationContext(); // CharSequence contentTitle = "我的通知欄標(biāo)展開(kāi)標(biāo)題"; // CharSequence contentText = "我的通知欄展開(kāi)詳細(xì)內(nèi)容"; // Intent notificationIntent = new Intent(AddressService.this,BootStartDemo.class); // PendingIntent contentIntent = PendingIntent.getActivity(AddressService.this, 0,notificationIntent, 0); // notification.setLatestEventInfo(context, contentTitle, contentText,contentIntent); // //用mNotificationManager的notify方法通知用戶(hù)生成標(biāo)題欄消息通知 // mNotificationManager.notify(1, notification); // } } /** * 服務(wù)停止的時(shí)候調(diào)用 */ @Override public void onDestroy() { super.onDestroy(); manager.listen(listener, PhoneStateListener.LISTEN_NONE); listener = null; } private class MyPhoneListener extends PhoneStateListener{ /** * 電話狀態(tài)發(fā)生改變的時(shí)候調(diào)用的方法 */ @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { case TelephonyManager.CALL_STATE_IDLE: if(null != view){ wManager.removeView(view); view = null; } endTime = System.currentTimeMillis(); break; case TelephonyManager.CALL_STATE_RINGING: // 零響狀態(tài) //判斷number是否在黑名單中 if(dao.find(incomingNumber)){ //掛斷電話 endCall(); //刪除呼叫記錄 // deleteCallLog(incomingNumber); ContentResolver resolver = getContentResolver(); resolver.registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler(),incomingNumber)); } Log.i(TAG,"來(lái)電號(hào)碼為"+ incomingNumber); String address = NumberAddressService.getAddress(incomingNumber); Log.i(TAG,"歸屬地為"+ address); showLocation(address); //獲取當(dāng)前系統(tǒng)的時(shí)間 startTime = System.currentTimeMillis(); break; case TelephonyManager.CALL_STATE_OFFHOOK: //接通電話狀態(tài) break; } } } /** * 在窗體上顯示出來(lái)位置信息 * @param address */ public void showLocation(String address) { WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.type = WindowManager.LayoutParams.TYPE_TOAST; params.setTitle("Toast"); params.gravity = Gravity.LEFT | Gravity.TOP; int x = sp.getInt("lastx", 0); int y = sp.getInt("lasty", 0); params.x = x; params.y = y; view = View.inflate(getApplicationContext(), R.layout.show_location, null); LinearLayout ll_location = (LinearLayout) view.findViewById(R.id.ll_location); TextView tv_location = (TextView) view.findViewById(R.id.tv_location); int background = sp.getInt("background", 0); if(0 == background){ ll_location.setBackgroundResource(R.drawable.call_locate_gray); }else if(1 == background){ ll_location.setBackgroundResource(R.drawable.call_locate_orange); }else { ll_location.setBackgroundResource(R.drawable.call_locate_green); } tv_location.setText(address); tv_location.setTextSize(24); wManager.addView(view, params); } /** * 刪除呼叫記錄 */ public void deleteCallLog(String incomingNumber) { ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null,"number=?", new String[]{incomingNumber}, null); if(cursor.moveToNext()){ String id = cursor.getString(cursor.getColumnIndex("_id")); resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?", new String[]{id}); } } /** * 掛斷電話 */ public void endCall() { try { Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class); IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE}); ITelephony telephony = ITelephony.Stub.asInterface(binder); telephony.endCall(); } catch (Exception e) { e.printStackTrace(); } } private class MyObserver extends ContentObserver{ private String incomingNumber; public MyObserver(Handler handler,String incomingNumber) { super(handler); this.incomingNumber = incomingNumber; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); deleteCallLog(incomingNumber); getContentResolver().unregisterContentObserver(this); } } }
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Android開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android通信方式總結(jié)》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android動(dòng)態(tài)人臉檢測(cè)的示例代碼(臉數(shù)可調(diào))
本篇文章主要介紹了Android動(dòng)態(tài)人臉檢測(cè)的示例代碼(臉數(shù)可調(diào)),具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08Android如何在App中啟動(dòng)系統(tǒng)鬧鐘
這篇文章主要為大家詳細(xì)介紹了Android如何在App中啟動(dòng)系統(tǒng)鬧鐘,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Android開(kāi)發(fā)之Activity管理工具類(lèi)完整示例
這篇文章主要介紹了Android開(kāi)發(fā)之Activity管理工具類(lèi),集合完整實(shí)例形式分析了Android操作Activity創(chuàng)建、添加、獲取、移除等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01Android裁剪圖片為圓形圖片的實(shí)現(xiàn)原理與代碼
這個(gè)方法是根據(jù)傳入的圖片的高度(height)和寬度(width)決定的,如果是 width <= height時(shí),則會(huì)裁剪高度,裁剪的區(qū)域是寬度不變高度從頂部到寬度width的長(zhǎng)度2013-01-01Android實(shí)現(xiàn)TCP客戶(hù)端接收數(shù)據(jù)的方法
這篇文章主要介紹了Android實(shí)現(xiàn)TCP客戶(hù)端接收數(shù)據(jù)的方法,較為詳細(xì)的分析了Android基于TCP實(shí)現(xiàn)客戶(hù)端接收數(shù)據(jù)的相關(guān)技巧與注意事項(xiàng),需要的朋友可以參考下2016-04-04Android編程實(shí)現(xiàn)調(diào)用相冊(cè)、相機(jī)及拍照后直接裁剪的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)調(diào)用相冊(cè)、相機(jī)及拍照后直接裁剪的方法,涉及Android拍照及圖形處理相關(guān)操作技巧,需要的朋友可以參考下2017-02-02深入解析Android中View創(chuàng)建的全過(guò)程
這篇文章主要給大家深入的解析了關(guān)于Android中View創(chuàng)建的全過(guò)程,文中介紹的非常詳細(xì),相信對(duì)大家會(huì)有一定的參考借鑒,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-03-03實(shí)現(xiàn)Android studio設(shè)置自動(dòng)導(dǎo)包及自動(dòng)導(dǎo)包快捷鍵
這篇文章主要介紹了實(shí)現(xiàn)Android studio設(shè)置自動(dòng)導(dǎo)包及自動(dòng)導(dǎo)包快捷鍵的相關(guān)資料,需要的朋友可以參考下2017-05-05Android OnCreate()中獲取控件高度與寬度兩種方法詳解
這篇文章主要介紹了Android OnCreate()中獲取控件高度與寬度兩種方法詳解的相關(guān)資料,這里提供了兩種方法,大家可以都看下,需要的朋友可以參考下2016-12-12