这只是一个学习例程,很多功能有待完善
允许用户动态加载手机通讯录中的电话号码,勾选某些号码作为黑名单,一旦将某些号码设为黑名单,当该号码自动挂断该号码
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)