android项目 之 来电管家(5)

编程入门 行业动态 更新时间:2024-10-10 03:23:15

android项目 之 来电<a href=https://www.elefans.com/category/jswz/34/1769965.html style=管家(5)"/>

android项目 之 来电管家(5)

       上面四节,已经实现了界面设计,黑名单(白名单的添加与删除与黑名单同理,不再赘述),启用监听开关,定时拦截开关,及拦截模式选择等功能,下面就要实现来电管家最核心的功能,也就是拦截功能。

        主要思路

                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.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;@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();System.out.println("create");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubtManager = (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);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();callListener = null;tManager = null;System.out.println("destory");stopSelf();}@Overridepublic boolean onUnbind(Intent intent) {// TODO Auto-generated method stubreturn 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{@Overridepublic 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;elsecallEnd_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 blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (RemoteException e) {// TODO Auto-generated catch blocke.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(timepareTo(startTime) >= 0 && timepareTo(endTime) <= 0){return true;}}return false;}//判断给定号码是否在白名单中 public boolean isInWhiteList(String phone){Cursor cursor = db.rawQuery("select * from whiteList where number='"+phone+"';", null);cursor.moveToFirst();//如果该号码在白名单中,则返回trueif(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;}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}}

             代码很长,但核心的就是CustomPhoneCallListener这一部分,里面的主要思路就是通过读取用户的设置信息,判断是否拦截。

             这里同时也实现了,将拦截信息写入数据库,所以也就有了上述代码中的数据库的相关代码了。

             最后,重要的一点,就是,和Activity一样,service同样也需要进行注册,在AndroidManifest.xml里添加:

 		<service android:name="com.example.callmanager.ListenService"  android:enabled="true" >  <intent-filter>  <action android:name="com.example.callmanager.ListenService" />  </intent-filter>  </service> 

          当然,因为要监听来电状态,少不了读取通话记录和读取电话状态的权限,在AndroidManifest.xml里添加:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>


         这样,在该需要启用该监听服务时,就可以通过Intent来启动该服务,当启用该服务后,即使退出了Activity,也可以实现监听,因为service依然在后台运行,这就是service最基本的功能。

       

 

 

 

更多推荐

android项目 之 来电管家(5)

本文发布于:2024-03-23 02:09:46,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1739203.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:管家   项目   android

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!