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

jopen 10年前

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

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

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

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

android.telephony包下的NeighboringCellInfo.aidl

f1.jpg

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

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

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

演示图片:


f2.gif

程序代码:

    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" />