Service-黑名单来电自动挂断

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

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

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)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值