初学Android,手机管理器之自动挂断黑名单的来电(六十四)

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

为了调用远程AIDL Service,需要将Android源码中如下两个文件复制到项目的相应位置

com.android.internal.telephony 包下的ITelephony.aidl

android.telephony 包下的NeighboringCellInfo.aidl


AndroidManifest.xml 增加如下权限

    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <!--  授予读联系人ContentProvider的权限 --> 
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <!--  授予写联系人ContentProvider的权限 -->
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <!-- 添加访问手机状态的权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

package WangLi.Service.BlockList;

import java.lang.reflect.Method;
import java.util.ArrayList;

import com.android.internal.telephony.ITelephony;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.ContactsContract;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;

public class BlockList extends Activity {
	// 记录黑名单的List
	ArrayList<String> blockList = new ArrayList<String>();
	TelephonyManager tManager;
	// 监听通话状态的监听器
	CustomPhoneCallListener cpListener;

	public class CustomPhoneCallListener extends 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)) {
					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);
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取系统的TelephonyManager管理器
		tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		cpListener = new CustomPhoneCallListener();
		// 通过TelephonyManager监听通话状态的改变
		tManager.listen(cpListener, 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(BlockList.this);
								// 获取联系人的电话号码,并去掉中间的中划线
								String number = cursor
										.getString(
												cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
										.replace("-", "");
								rb.setText(number);
								// 如果该号码已经被加入黑名单、默认勾选该号码
								if (isBlock(number)) {
									rb.setChecked(true);
								}
								return rb;
							}
						};
						// 加载list.xml布局文件对应的View
						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(BlockList.this)
								.setView(selectView)
								.setPositiveButton("确定",
										new DialogInterface.OnClickListener() {
											@Override
											public void onClick(
													DialogInterface dialog,
													int which) {
												// 清空blockList集合
												blockList.clear();
												// 遍历listView组件的每个列表项
												for (int i = 0; i < listView
														.getCount(); i++) {
													CheckBox checkBox = (CheckBox) listView
															.getChildAt(i);
													// 如果该列表项被勾选
													if (checkBox.isChecked()) {
														// 添加该列表项的电话号码
														blockList.add(checkBox
																.getText()
																.toString());
													}
												}
												System.out.println(blockList);
											}
										}).show();
					}
				});
	}

	// 判断某个电话号码是否在黑名单之内
	public boolean isBlock(String phone) {
		for (String s1 : blockList) {
			if (s1.equals(phone)) {
				return true;
			}
		}
		return false;
	}
}

效果


可以勾选电话簿的号码,加入到黑名单中


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值