Service-黑名单来电自动挂断

这只是一个学习例程,很多功能有待完善

允许用户动态加载手机通讯录中的电话号码,勾选某些号码作为黑名单,一旦将某些号码设为黑名单,当该号码自动挂断该号码

Android没有对外公开挂断电话的API,如果需要挂断电话,必须使用AIDL与电话管理Service进行通信,并调用服务中的API实现结束通话

为了调用远程的AIDL Service,需要上图所示的两个aidl文件

BlockMain.Java  界面提供一个按钮让用户打开对话框来勾选黑名单、

[java] view plain copy
  1. public class BlockMain extends Activity {  
  2.     ArrayList<String> blockList = new ArrayList<String>();//保存黑名单电话  
  3.     ArrayList<String> numList = new ArrayList<String>(); //保存通讯录电话  
  4.     TelephonyManager tManager;  
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.main);  
  9.         // 获取系统的TelephonyManager管理器  
  10.         tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);  
  11.         PhoneStateListener listener = new PhoneStateListener(){  
  12.             @Override  
  13.             public void onCallStateChanged(int state, String incomingNumber) {  
  14.                 switch(state){  
  15.                 case TelephonyManager.CALL_STATE_IDLE:  
  16.                     break;  
  17.                 case TelephonyManager.CALL_STATE_OFFHOOK:  
  18.                     break;  
  19.                 // 当电话呼入时  
  20.                 case TelephonyManager.CALL_STATE_RINGING:  
  21.                     // 如果该号码属于黑名单  
  22.                     if(isBlock(incomingNumber)){  
  23.                         System.out.println("**挂断电话**");  
  24.                         try{  
  25.                             Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);  
  26.                             // 获取远程TELEPHONY_SERVICE的IBinder对象的代理  
  27.                             IBinder binder = (IBinder) method.invoke(nullnew Object[]{TELEPHONY_SERVICE});  
  28.                             // 将IBinder对象的代理转换为ITelephony对象  
  29.                             ITelephony telephony = ITelephony.Stub.asInterface(binder);  
  30.                             // 挂断电话  
  31.                             telephony.endCall();  
  32.                         }catch(Exception e){  
  33.                             e.printStackTrace();  
  34.                         }  
  35.                           
  36.                     }  
  37.                     break;  
  38.                 }  
  39.                 super.onCallStateChanged(state, incomingNumber);  
  40.             }  
  41.         };  
  42.         // 通过TelephonyManager监听通话状态的改变  
  43.         tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);  
  44.         // 获取程序的按钮,并为它的单击事件绑定监听器  
  45.         findViewById(R.id.managerBlock).setOnClickListener(new OnClickListener() {  
  46.               
  47.             @Override  
  48.             public void onClick(View v) {  
  49.                 final Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,   
  50.                         nullnullnullnull);  
  51.                 BaseAdapter adapter = new BaseAdapter(){  
  52.                         @Override  
  53.                         public int getCount() {  
  54.                             return cursor.getCount();  
  55.                         }  
  56.   
  57.                         @Override  
  58.                         public Object getItem(int position) {  
  59.                             return position;  
  60.                         }  
  61.   
  62.                         @Override  
  63.                         public long getItemId(int position) {  
  64.                             return position;  
  65.                         }  
  66.   
  67.                         @Override  
  68.                         public View getView(int position, View convertView,  
  69.                                 ViewGroup parent) {  
  70.                             cursor.moveToPosition(position);  
  71.                             CheckBox rb = new CheckBox(BlockMain.this);  
  72.                             String number = cursor.getString(cursor.getColumnIndex(  
  73.                                     ContactsContract.CommonDataKinds.Phone.NUMBER))  
  74.                                     .replace("-""")  
  75.                                     .replace(" """);  
  76.                             rb.setText(number);  
  77.                             numList.add(number);  
  78.                             // 如果该号码已经被加入黑名单、默认勾选该号码  
  79.                             if(isBlock(number)){  
  80.                                 rb.setChecked(true);  
  81.                             }  
  82.                             return rb;  
  83.                         }  
  84.                     };  
  85.                     // 加载list.xml布局文件对应的View  
  86.                     final View selectView = getLayoutInflater().inflate(R.layout.list, null);  
  87.                     // 获取selectView中的名为list的ListView组件  
  88.                     final ListView listView = (ListView) selectView.findViewById(R.id.list);  
  89.                     listView.setAdapter(adapter);  
  90.                     new AlertDialog.Builder(BlockMain.this)  
  91.                     .setView(selectView)  
  92.                     .setPositiveButton("确定",  
  93.                             new DialogInterface.OnClickListener() {  
  94.                                 @Override  
  95.                                 public void onClick(DialogInterface dialog, int which) {  
  96.                                     // 清空blockList集合  
  97.                                     blockList.clear();  
  98.                                     // 遍历listView组件的每个列表项,这里只是遍历当前页  
  99.                                     int numOfVisibleView = listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();  
  100.                                     for (int i = 0; i < numOfVisibleView; i++)  
  101.                                     {  
  102.                                         CheckBox checkBox = (CheckBox)  
  103.                                             listView.getChildAt(i);  
  104.                                         // 如果该列表项被勾选  
  105.                                         if (checkBox.isChecked())  
  106.                                         {  
  107.                                             // 添加该列表项的电话号码  
  108.                                             blockList.add(checkBox  
  109.                                                 .getText().toString());  
  110.                                         }  
  111.                                     }  
  112.       
  113.                                 }  
  114.                             }).show();  
  115.                 }  
  116.                   
  117.         });  
  118.     }  
  119.       
  120.     // 判断某个电话号码是否在黑名单之内  
  121.     public boolean isBlock(String phone){  
  122.         System.out.println("呼入号码:"+phone);  
  123.         System.out.println("-----"+blockList);  
  124.         for (String s1 : blockList){  
  125.             if(s1.equals(phone)){  
  126.                 return true;  
  127.             }  
  128.         }  
  129.         return false;  
  130.     }  
  131.   
  132. }  

mainfest文件 配置相应权限

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="crazyit.manager"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="8"  
  9.         android:targetSdkVersion="18" />  
  10.     <!-- 授予该应用控制通话的权限 -->  
  11.     <uses-permission android:name="android.permission.CALL_PHONE" />    
  12.     <!-- 授予该应用读取通话状态的权限 -->  
  13.     <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  14.     <!-- 授予读联系人ContentProvider的权限 -->  
  15.     <uses-permission android:name="android.permission.READ_CONTACTS" />  
  16.     <!-- 授予写联系人ContentProvider的权限 -->  
  17.     <uses-permission android:name="android.permission.WRITE_CONTACTS" />  
  18.   
  19.     <application  
  20.         android:allowBackup="true"  
  21.         android:icon="@drawable/ic_launcher"  
  22.         android:label="@string/app_name"  
  23.         android:theme="@style/AppTheme" >  
  24.         <activity  
  25.             android:name="crazyit.manager.BlockMain"  
  26.             android:label="@string/app_name" >  
  27.             <intent-filter>  
  28.                 <action android:name="android.intent.action.MAIN" />  
  29.   
  30.                 <category android:name="android.intent.category.LAUNCHER" />  
  31.             </intent-filter>  
  32.         </activity>  
  33.     </application>  
  34.   
  35. </manifest>  


备注:

本例程只能勾选当前显示页的号码,

[java] view plain copy
  1. numOfVisibleView = listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();  
这是在原例程进行修改,原例程如果遇到号码很多(超过手机一页,需要还滑动翻页)的情况会出现bug

具体情况如 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=249149

在网上寻找解决方案,还是没有合适的方法,

暂且用numOfVisibleView表示当前显示页的号码数,将此也页面的电话号码加入黑名单。

(还找到一个解决方案,但自己没有修改成功http://blog.csdn.net/fengyuzhengfan/article/details/38166967)

发布了34 篇原创文章 · 获赞 4 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章