Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android項目 之 來電管家(5) ----- 添加監聽服務

android項目 之 來電管家(5) ----- 添加監聽服務

編輯:關於Android編程

上面四節,已經實現了界面設計,黑名單(白名單的添加與刪除與黑名單同理,不再贅述),啟用監聽開關,定時攔截開關,及攔截模式選擇等功能,下面就要實現來電管家最核心的功能,也就是攔截功能。

主要思路

1. 制定攔截模式,這裡主要有兩個,一個是黑名單模式,也就是只攔截在黑名單中的號碼;另一個就是白名單模式,攔截除了白名單以外的號碼。

2. 根據用戶自定義設置信息,制定正則表達式,判斷攔截的標准。

3. 使用對應的類實現掛斷電話的功能。

監聽模塊主要是利用service實現功能,為了實現電話掛斷功能,這裡需要調用遠程的AIDL Service,大多數書上都介紹要將Android源代碼中如下兩個文件復制到項目的相應位置:

com.android.internal.telephony包下的ITelephony.aidl

android.telephony包下的NeighboringCellinfo.aidl

但是下載源碼需要翻牆,有點麻煩,其實做這些的目的就是為了在根目錄下自動生成ITelephony.java源文件,因此沒有源碼也可以,具體做法如下:

1)在項目的src目錄下,新建package:com.android.internal.telephony

2) 在剛新建的package下,新建一個名為ITelephony.aidl的文件。

3) 將以下代碼拷到剛新建的文件中。

  package com.android.internal.telephony;  
        interface ITelephony{  
            boolean endCall();  
            void answerRingingCall();  
        }  

這樣,ADT會在根目錄下自動生成ITelephony.java源文件了。

service的整個代碼如下,裡面也有解釋:

ListenService.java

package com.example.callmanager;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.AudioManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;

import com.android.internal.telephony.ITelephony;

public class ListenService extends Service {
	TelephonyManager tManager;
	private SQLiteDatabase db;
	private SharedPreferences spf;
	private CustomPhoneCallListener callListener;
	
	

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		
	    System.out.println("create");
	}
	
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		tManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
		
	    callListener = new CustomPhoneCallListener();
		spf = this.getSharedPreferences("setting", Activity.MODE_PRIVATE);
		tManager.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
		System.out.println("start");
		return super.onStartCommand(intent, flags, startId);
	}

	
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		callListener = null;
		tManager = null;
		System.out.println("destory");
		stopSelf();
	}

	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		return super.onUnbind(intent);
		
	}
	
	//創建或打開數據庫
    public void create_db(){
    	//創建或打開數據庫
    	db = SQLiteDatabase.openOrCreateDatabase(ListenService.this.getFilesDir().toString()+"/list.db3", null);

    	if(db == null){
    		Toast.makeText(ListenService.this,"數據庫創建不成功",Toast.LENGTH_LONG).show();
    	}
    	else{
    		
    		/*//創建另一個表,用於存放來電信息
    		db.execSQL("create table if not exists callInfo(_id integer primary key autoincrement," +
    				"name varchar(50)," +
    				"number varchar(15),"+
    				"callTimes varchar(20));");*/
    	
    	}	
    }
	
   //插入 
    public void insert_callInfo(String name,String number,String time){
    	Cursor cursor = db.rawQuery("select * from callInfo where callTimes = '"+time+"';",null);
    	if(cursor.getCount() == 0){
    		db.execSQL("insert into callInfo(name,number,callTimes) values('"+ name+ "','" + number +"','" + time + "');");
    	}
    	cursor.close();
    	
    }
	
	 public class CustomPhoneCallListener extends PhoneStateListener{
	    	@Override
	    	public void onCallStateChanged(int state, String incomingNumber) {
	    		super.onCallStateChanged(state, incomingNumber);
	    		
	    			if(spf.getBoolean("isStartListen", false)){
		    			//判斷該電話是否在黑名單中
	    				create_db();
	    				boolean callEnd_flag = false;
	    				String incomingName = null;
	    				SimpleDateFormat   formatter   =   new   SimpleDateFormat   ("MM-dd HH:mm");  
				        Date   curDate   =   new   Date(System.currentTimeMillis());//獲取當前時間 
				        String   strTime   =   formatter.format(curDate);
	    				//如果啟用白名單模式
	    				if(spf.getBoolean("isWhiteList",false)){
	    					System.out.println("whiteList");
	    					callEnd_flag = !isInWhiteList(incomingNumber);
	    					
	    					//根據號碼找到聯系人姓名
	    					incomingName = getContactsNameByNumber(incomingNumber);
	    					
	    				}
	    				//如果是黑名單模式
	    				else{
	    					incomingName = isInBalckList(incomingNumber);
	    					if(incomingName == null)
	    						callEnd_flag = false;
	    					else
	    						callEnd_flag = true;
	    				}
	    				
	    				//如果啟用時間段,則判斷當前撥打電話時間是否在設定時間段中
	    				if(spf.getBoolean("isTime", false)){
	    					System.out.println("inTime");
	    					callEnd_flag = callEnd_flag && isInterceptTime(strTime);
	    				}
		    			
		    			
		    			switch(state){
		    			case TelephonyManager.CALL_STATE_IDLE:
		    				break;
		    			case TelephonyManager.CALL_STATE_OFFHOOK :
		    				break;
		    			//當電話呼入時
		    			case TelephonyManager.CALL_STATE_RINGING :
		    				toggleRingerMute(getApplicationContext());
		    				
		    				if(callEnd_flag){
		    					
		    			        
		    					try {
									Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
									//獲取遠程telephony_service的IBindler對象的代理
									IBinder binder = (IBinder)method.invoke(null, new Object[]{TELEPHONY_SERVICE});
									//將IBinder對象的代理轉換為ITelephony對象 
									ITelephony telephony = ITelephony.Stub.asInterface(binder);
									//掛斷電話 
									telephony.endCall();
		    					} catch (NoSuchMethodException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (ClassNotFoundException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (IllegalAccessException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (IllegalArgumentException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (InvocationTargetException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (RemoteException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
		    					
		    					//將該號碼插入來電信息數據庫中
		    					//獲得當前的時間 
		    					if(incomingName == null){
		    						incomingName = "陌生號碼";
		    					}
		    			        insert_callInfo(incomingName, incomingNumber, strTime);
		    			        
		    				}
		    				System.out.println("bindListen");
		    				
		    				break;
		    			}
		    		}
	    		
	    		db.close();
	    	}
	    }
          //通過電話號碼查找聯系人的姓名,如果查找到,則返回聯系人的姓名,否則,返回null	 
	 public String getContactsNameByNumber(String number){
		 Cursor c = getContentResolver().query(Uri.withAppendedPath(
	             PhoneLookup.CONTENT_FILTER_URI, number), new String[] {
	             PhoneLookup._ID,
	             PhoneLookup.NUMBER,
	             PhoneLookup.DISPLAY_NAME,
	             PhoneLookup.TYPE, PhoneLookup.LABEL }, null, null,   null );


		 if(c.getCount() == 0){
			 return null;
		 } 
		 else {
	         c.moveToFirst();
	         return c.getString(2); //獲取姓名
	         
	     }
		 
	 }
	 
	 private static int previousMuteMode = -1;

	 /**
	  * 來電靜音
	  * 
	  * @param context
	  */
	 private void toggleRingerMute(Context context)
	 {
	     AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
	     if (previousMuteMode == -1)
	     {
	         previousMuteMode = am.getRingerMode();
	         am.setRingerMode(0);
	     }
	     am.setRingerMode(previousMuteMode);
	     previousMuteMode = -1;
	 }

 
	 

	 
	 
	 
	 
	 //判斷當前撥打時間 是否在攔截時間段裡
	 public boolean isInterceptTime(String time){
		 //如果啟用時間段 
		 if(spf.getBoolean("isTime", false)){
			 String startTime = spf.getString("startTime", "");
			 String endTime = spf.getString("endTime", "");
			//比較當前時間是否在攔截時間段內
			if(time.compareTo(startTime) >= 0 && time.compareTo(endTime) <= 0){
				 return true;
		    }
		 }
		 return false;
	 }

	 
	 
	 
	 //判斷給定號碼是否在白名單中 
	 public boolean isInWhiteList(String phone){
		 Cursor cursor = db.rawQuery("select * from whiteList where number='"+phone+"';", null);
		 cursor.moveToFirst();
		 //如果該號碼在白名單中,則返回true
		 if(cursor.getCount() > 0){
			 cursor.close();
			 return true;
		 }
		 return false;
	 }
	 
	 

	//判斷給定號碼是否在黑名單中 
	public String isInBalckList(String phone){
	    	Cursor cursor = db.rawQuery("select * from blackList where number='"+phone+"';", null);
	    	String name = null;
	    	cursor.moveToFirst();
	    	if(cursor.getCount()>0)
	    		name = cursor.getString(cursor.getColumnIndex("name"));
	    	cursor.close();
	    	return name;
	}


		@Override
		public IBinder onBind(Intent intent) {
			// TODO Auto-generated method stub
			return null;
		}
	
	
	

}

代碼很長,但核心的就是CustomPhoneCallListener這一部分,裡面的主要思路就是通過讀取用戶的設置信息,判斷是否攔截。

這裡同時也實現了,將攔截信息寫入數據庫,所以也就有了上述代碼中的數據庫的相關代碼了。

最後,重要的一點,就是,和Activity一樣,service同樣也需要進行注冊,在AndroidManifest.xml裡添加:

 		  
   			  
       				  
   			   
		 

當然,因為要監聽來電狀態,少不了讀取通話記錄和讀取電話狀態的權限,在AndroidManifest.xml裡添加:



這樣,在該需要啟用該監聽服務時,就可以通過Intent來啟動該服務,當啟用該服務後,即使退出了Activity,也可以實現監聽,因為service依然在後台運行,這就是service最基本的功能。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved