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

          本实例允许用户动态添加号码到黑名单,并实现黑名单来电自动挂断。程序通过创建PhoneStateListener监听器来监听TelephonyManager的通话状态来实现该功能。

由于自Android 10之后Android不再对外公开挂断电话的API,如果需要挂断电话必须使用AIDL与电话管理Service进行通信,并调用服务中的API实现结束电话。

为了调用远程的AIDL Service,开发者需要将Android源码中的如下两个文拷到指定位置:

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

android.telephony包下的NeighboringCellInfo.aidl

Android开发之黑名单来电自动挂断_第1张图片

这样就会在gen文件夹下生成相应的.Java文件。

另外调用API的方法如果有不解的地方可以参考:Class.forName()的作用与使用总结

另外本实例使用BaseAdapter作为ListView的适配器,BaseAdapter具有很强的定制型。

演示图片:

Android开发之黑名单来电自动挂断_第2张图片

程序代码:

package com.jph.callguard;

import java.lang.reflect.Method;
import java.util.ArrayList;
import com.android.internal.telephony.ITelephony;
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.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
/**
 * Describe:</br>
 * 黑名单自动挂断
 * 本实例实现了获取联系人,并将选中的联系人添加到黑名单中
 * 并通过ITelephony.aidl与NeighboringCellInfo.aidl
 * 接口使用AIDL与电话管理Servic进行通信挂断黑名单中的电话
 * @author jph
 * Time:2014.07.24 
 * */
public class CallGuard extends Activity {
	Button btnManage;
	TelephonyManager tManager;
	//创建一个集合用于保存黑名单中的号码
	ArrayList<String>blockList=new ArrayList<String>();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnManage=(Button)findViewById(R.id.btnManage);
		tManager=(TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		//创建电话状态监听器
		PhoneStateListener pStateListener=new PhoneStateListener(){
			@Override
			public void onCallStateChanged(int state, String incomingNumber) {
				// TODO Auto-generated method stub
				switch (state) {
				case TelephonyManager.CALL_STATE_IDLE://空闲状态不做处理					
					break;
				case TelephonyManager.CALL_STATE_OFFHOOK://接起电话不做处理					
					break;
				case TelephonyManager.CALL_STATE_RINGING://正在响铃
					//如果来电号码在黑名单中则自动挂断
					if (isBlock(incomingNumber)) {
						try {
							//获取android.os.ServiceManager类的对象的getService()方法
							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) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}					
					break;
				}
				super.onCallStateChanged(state, incomingNumber);
			}			
		};
		//为TelephonyManager添加监听器
		tManager.listen(pStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		btnManage.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//查询通信录中的电话号码
				final Cursor cursor=getContentResolver().query(
						ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
						null, null, null, null);
				//创建一个BaseAdapter作为ListView的适配器
				BaseAdapter adapter=new BaseAdapter() {					
					@Override
					public View getView(int position, View convertView, ViewGroup parent) {
						// TODO Auto-generated method stub
						//将游标的指针移动到指定位置
						cursor.moveToPosition(position);
						CheckBox box=new CheckBox(CallGuard.this);
						//获取指定位置的电话号码
						String number=cursor.getString(cursor.getColumnIndex(
								ContactsContract.CommonDataKinds.Phone.NUMBER));
						//去掉电话号码中间的中划线、空格
						number.replace("-", "").replace(" ", "");
						box.setText(number);
						//如果该号码已经被加入黑名单、默认勾选该号码
						if (isBlock(number)) {
							box.setChecked(true);
						}
						return box;
					}
					@Override
					public long getItemId(int position) {
						// TODO Auto-generated method stub
						return position;
					}
					
					@Override
					public Object getItem(int position) {
						// TODO Auto-generated method stub
						return position;
					}
					//返回列表的总条数
					@Override
					public int getCount() {
						// TODO Auto-generated method stub
						return cursor.getCount();
					}
				};
				//加载line布局文件
				View view=getLayoutInflater().inflate(R.layout.line, null);
				//获取line布局文件中Id为list的组件
				final ListView list=(ListView)view.findViewById(R.id.list);
				list.setAdapter(adapter);
				new AlertDialog.Builder(CallGuard.this).setView(view).setPositiveButton("确定", 
						new DialogInterface.OnClickListener() {							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								// TODO Auto-generated method stub
								blockList.clear();
								for (int i = 0; i < list.getCount(); i++) {
									CheckBox box=(CheckBox)list.getChildAt(i);
									//如果联系人被选中则将其添加到blockList集合
									if (box.isChecked()) {
										blockList.add(box.getText().toString());
									}																		
								}							
							}
						}).show();
			}
		});		
	}
	private boolean isBlock(String number) {
		// TODO Auto-generated method stub
		//判断号码是否在blockList集合中
		for (String s:blockList) {
			if (s.equals(number)) {
				return true;
			}
		}
		return false;		
	}
}

最后别忘添加相应的权限:

AndroidManifest.xml

<!-- 授予该应用控制通话的权限 -->
	<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" />



你可能感兴趣的:(aidl,黑名单来电自动挂断,ITelephony.aidl)