这只是一个学习例程,很多功能有待完善
允许用户动态加载手机通讯录中的电话号码,勾选某些号码作为黑名单,一旦将某些号码设为黑名单,当该号码自动挂断该号码
Android没有对外公开挂断电话的API,如果需要挂断电话,必须使用AIDL与电话管理Service进行通信,并调用服务中的API实现结束通话
为了调用远程的AIDL Service,需要上图所示的两个aidl文件
BlockMain.java 界面提供一个按钮让用户打开对话框来勾选黑名单、
public class BlockMain extends Activity { ArrayList<String> blockList = new ArrayList<String>();//保存黑名单电话 ArrayList<String> numList = new ArrayList<String>(); //保存通讯录电话 TelephonyManager tManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取系统的TelephonyManager管理器 tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); PhoneStateListener listener = new PhoneStateListener(){ @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: // 如果该号码属于黑名单 if(isBlock(incomingNumber)){ System.out.println("**挂断电话**"); try{ Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class); // 获取远程TELEPHONY_SERVICE的IBinder对象的代理 IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE}); // 将IBinder对象的代理转换为ITelephony对象 ITelephony telephony = ITelephony.Stub.asInterface(binder); // 挂断电话 telephony.endCall(); }catch(Exception e){ e.printStackTrace(); } } break; } super.onCallStateChanged(state, incomingNumber); } }; // 通过TelephonyManager监听通话状态的改变 tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); // 获取程序的按钮,并为它的单击事件绑定监听器 findViewById(R.id.managerBlock).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); BaseAdapter adapter = new BaseAdapter(){ @Override public int getCount() { return cursor.getCount(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { cursor.moveToPosition(position); CheckBox rb = new CheckBox(BlockMain.this); String number = cursor.getString(cursor.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER)) .replace("-", "") .replace(" ", ""); rb.setText(number); numList.add(number); // 如果该号码已经被加入黑名单、默认勾选该号码 if(isBlock(number)){ rb.setChecked(true); } return rb; } }; // 加载list.xml布局文件对应的View final View selectView = getLayoutInflater().inflate(R.layout.list, null); // 获取selectView中的名为list的ListView组件 final ListView listView = (ListView) selectView.findViewById(R.id.list); listView.setAdapter(adapter); new AlertDialog.Builder(BlockMain.this) .setView(selectView) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 清空blockList集合 blockList.clear(); // 遍历listView组件的每个列表项,这里只是遍历当前页 int numOfVisibleView = listView.getLastVisiblePosition() - listView.getFirstVisiblePosition(); for (int i = 0; i < numOfVisibleView; i++) { CheckBox checkBox = (CheckBox) listView.getChildAt(i); // 如果该列表项被勾选 if (checkBox.isChecked()) { // 添加该列表项的电话号码 blockList.add(checkBox .getText().toString()); } } } }).show(); } }); } // 判断某个电话号码是否在黑名单之内 public boolean isBlock(String phone){ System.out.println("呼入号码:"+phone); System.out.println("-----"+blockList); for (String s1 : blockList){ if(s1.equals(phone)){ return true; } } return false; } }
mainfest文件 配置相应权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="crazyit.manager" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <!-- 授予该应用控制通话的权限 --> <uses-permission android:name="android.permission.CALL_PHONE" /> <!-- 授予该应用读取通话状态的权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 授予读联系人ContentProvider的权限 --> <uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- 授予写联系人ContentProvider的权限 --> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="crazyit.manager.BlockMain" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
备注:
本例程只能勾选当前显示页的号码,
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)
时间: 2024-10-12 21:06:36