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)

时间: 2024-10-12 21:06:36

Service-黑名单来电自动挂断的相关文章

Android开发之黑名单来电自动挂断

本实例允许用户动态添加号码到黑名单,并实现黑名单来电自动挂断.程序通过创建PhoneStateListener监听器来监听TelephonyManager的通话状态来实现该功能. 由于自Android 10之后Android不再对外公开挂断电话的API,如果需要挂断电话必须使用AIDL与电话管理Service进行通信,并调用服务中的API实现结束电话. 为了调用远程的AIDL Service,开发者需要将Android源码中的如下两个文拷到指定位置: com.android.internal.t

解决低电量自动关机时如果有来电自动关断电话

1.问题描述: 低电量时,由于系统已经无法继续提供通话服务,为了不影响通话服务质量或其它问题,因此在自动关机时应自动挂断电话 2.解决思路: 在低电量自动关机时,如果此时有来电,调用挂断电话的接口,挂断电话. 3.实现方式: BatteryService.java private void shutdownIfNoPowerLocked() { // shut down gracefully if our battery is critically low and we are not powe

Android开发之来电电话挂断实现

在Android1.5版本之前,实现挂断电话是非常容易的事,只需要调用TelephonyManager的endCall()方法就可以了,但在1.5版本之后,Google工程师为了手机的安全期间,把endCall的方法隐藏掉了.所以实现挂断电话可以通过反射的方法,执行endCall方法.具体实现如下: TelephonyManager在源码里是这样描述的:Context.getSystemService(Context.TELEPHONY_SERVICE)},我们通过TELEPHONY_SERVI

android项目实现电话自动挂断的功能

private void endCall() {        try {            /*             * 1.得到字节码文件             * 2.得到对应的方法getService             * 4.执行这个方法             * 以上是反射过程             * 5.拷贝aidl文件             * 6.生成java代码             * 7,执行endCall():             */  

菜鸟学freeswitch(二)webRTC拨软电话自动挂断

2019-01-08 17:39:49.221806 [ERR] mod_sofia.c:2343 CODEC NEGOTIATION ERROR. SDP:v=0o=- 3481799438673358832 2 IN IP4 127.0.0.1s=-t=0 0a=group:BUNDLE audioa=msid-semantic: WMS MP9KUnaULVHFpwTqhoSfv1fphnZ1jZqMmqsPm=audio 57630 UDP/TLS/RTP/SAVPF 111 103 1

android 自动拒接后再取消自动拒接,该联系人来电界面无图标显示,且点击挂断无反应

1.    设置一个联系人为自动拒接 2.    该联系人来电 3.    取消该联系人的自动拒接 4.    该联系人来电 Error: 来电界面无头像显示,直接显示黑屏,且点击拒接按钮出现通话过程的界面,而实际后台已经挂断 修改CallNotifier.java文件中onDisconnect()方法中以下位置添加如下代码: if (!mIsShouldSendtoVoicemail && ok2Ring) { Toast.makeText(PhoneApp.getInstance().

Android 电话自动接听和挂断详解

1.通过aidl及反射实现挂断电话 具体分三步: (1)ITelephony.aidl ,必须新建com.android.internal.telephony包并放入ITelephony.aidl文件(构建后在gen下有ITelephony.java文件,这是aidl生成的接口),文件内容如下: package com.android.internal.telephony; interface ITelephony{ boolean endCall(); void answerRingingCa

android 自己主动拒接后再取消自己主动拒接,该联系人来电界面无图标显示,且点击挂断无反应

1.    设置一个联系人为自己主动拒接 2.    该联系人来电 3.    取消该联系人的自己主动拒接 4.    该联系人来电 Error: 来电界面无头像显示,直接显示黑屏,且点击拒接button出现通话过程的界面,而实际后台已经挂断 改动CallNotifier.java文件里onDisconnect()方法中下面位置加入例如以下代码: if (!mIsShouldSendtoVoicemail && ok2Ring) { Toast.makeText(PhoneApp.getI

Android之——自动挂断电话的实现

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47072451 通过<Android之--AIDL小结>与<Android之--AIDL深入>两篇博文,相信大家已经对Android AIDL有了一定的了解,下面,我们就利用Android的AIDL实现自动挂断电话的功能,好了,不多说了,我们直接进入主题. 1.准备AIDL文件 挂断电话的AIDL文件都是Android自带的文件,我们可以从Android的源代码中找到