zoukankan      html  css  js  c++  java
  • 挂断电话——黑名单拦截

    需要用Aidl,来与系统进程进行交互

    (关于aidl的介绍:

    http://chenfeng0104.iteye.com/blog/1255302

    http://www.cnblogs.com/mydomainlistentome/p/4687173.html)

     首先在src下建立这样的包:

      com.android.internal.telephony

    然后在这个包下建立这样的aidl文件:

      ITelephony.aidl 

    package com.android.internal.telephony ;
    interface ITelephony {
        boolean endCall() ;    // 挂断电话
        void answerRingingCall() ;    // 拨打电话
    }

    利用反射,在后台打印出隐藏的可以挂断电话的private类型的方法

    private ITelephony getITelephony() {
        ITelephony iTelephony=null;
        Class<TelephonyManager> cls=TelephonyManager.class;
        Method [] method= cls.getDeclaredMethods();
        for(int i=0;i<method.length;i++){
            System.out.println("方法:"+method[i]);
        }

    找到这个方法:

    I/System.out(1406): 方法:private com.android.internal.telephony.ITelephony android.telephony.TelephonyManager.getITelephony()
    07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getLteOnCdmaModeStatic()
    07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getNetworkClass(int)
    07-31 21:59:27.522: I/System.out(1406): 方法:public static java.lang.String android.telephony.TelephonyManager.getNetworkTypeName(int)
    07-31 21:59:27.522: I/System.out(1406): 方法:public static int android.telephony.TelephonyManager.getPhoneType(int)
    07-31 21:59:27.522: I/System.out(1406): 方法:private int android.telephony.TelephonyManager.getPhoneTypeFromNetworkType()

    然后将这个方法解封,调用

    private ITelephony getITelephony() {
            ITelephony iTelephony = null;
            Class<TelephonyManager> cls = TelephonyManager.class;
            Method method = null;
            // Method [] method= cls.getDeclaredMethods();
            // for(int i=0;i<method.length;i++){
            // System.out.println("方法:"+method[i]);
            // }
            try {
                method = cls.getDeclaredMethod("getITelephony");
                // 取消封装
                method.setAccessible(true);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            try {
                // 使用invoke来执行这个私有方法
                iTelephony = (ITelephony) method.invoke(telephone);
                return iTelephony;
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return iTelephony;
        }

     解决以上的问题就可以实现电话拦截了,下面是全部代码:

    service实现挂断:

    package com.example.phonelistendemo;
    
    import java.lang.reflect.Method;
    
    import com.android.internal.telephony.ITelephony;
    
    import android.app.Service;
    import android.content.Intent;
    import android.media.AudioManager;
    import android.os.Binder;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    
    public class ServicePhone extends Service {
        private TelephonyManager telephone = null;
        private AudioManager audio = null;
        private IBinder mbinder = new BinderImpl();
        private String num = null;
    
        public void onCreate() {
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            mbinder = null;
            num = null;
            super.onDestroy();
        }
    
        public class BinderImpl extends Binder implements IService {
            @Override
            public String getInterfaceDescriptor() {
                return "过滤电话:“" + ServicePhone.this.num + "”设置成功!";
            }
        }
    
        public IBinder onBind(Intent arg0) {
            audio = (AudioManager) getSystemService(AUDIO_SERVICE);
            num = arg0.getStringExtra("Nums");
            telephone = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
            backGroundExecution();
            return mbinder;
        }
    
        // 启动子线程
        public void backGroundExecution() {
            Thread thread = new Thread(null, backGroundProgress, "phoneListener");
            thread.start();
        }
    
        // 实例化子线程
        private Runnable backGroundProgress = new Runnable() {
            public void run() {
                telephone.listen(new PhoneStateListenerImpl(),
                        PhoneStateListener.LISTEN_CALL_STATE);
            }
        };
    
        private class PhoneStateListenerImpl extends PhoneStateListener {
            public void onCallStateChanged(int state, String incomingNumber) {
                switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    if (incomingNumber.equals(num)) {
                        ITelephony iTelephony=getITelephony();
                        if(iTelephony!=null){
                            try {
                                //挂断电话
                                iTelephony.endCall();
                            } catch (RemoteException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    break;
                case TelephonyManager.CALL_STATE_IDLE:

              //挂断提示音开启
              //audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);

               break;

                }
            }
        }
    
        private ITelephony getITelephony() {
            ITelephony iTelephony = null;
            Class<TelephonyManager> cls = TelephonyManager.class;
            Method method = null;
            // Method [] method= cls.getDeclaredMethods();
            // for(int i=0;i<method.length;i++){
            // System.out.println("方法:"+method[i]);
            // }
            try {
                method = cls.getDeclaredMethod("getITelephony");
                // 取消封装
                method.setAccessible(true);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            try {
                // 使用invoke来执行这个私有方法
                iTelephony = (ITelephony) method.invoke(telephone);
                return iTelephony;
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return iTelephony;
        }
    
    }

    broadcastReceive 接收电话状态

    package com.example.phonelistendemo; 
    
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    public class ReceivePhone extends BroadcastReceiver { 
        public void onReceive(Context content, Intent intent) {
            // 拨打电话
            if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
                Intent in=new Intent(content,ServicePhone.class);
                content.startService(in);
    
            } else{
                Intent in=new Intent(content, ServicePhone.class);
                content.startService(in);
            }
        }
    
    }

    定义IService接口 标记绑定状态

     

    package com.example.phonelistendemo;
    
    public interface IService {
    
    }

    MainActivity

    package com.example.phonelistendemo;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import com.example.phonelisten_Limite.R;
    import com.example.phonelisten_Limite.R.id;
    import com.example.phonelistendemo.ServicePhone.BinderImpl;
    
    public class MainActivity extends Activity {
        private Button bind, unBind;
        private EditText num;
        private  ServiceConnection connect;
        private IService service;
        private String getNum;
        
        
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            connect=new ServiceConnection() {
                public void onServiceDisconnected(ComponentName arg0) {
                    
                }
                
                public void onServiceConnected(ComponentName arg0, IBinder arg1) {
                    MainActivity.this.service=(BinderImpl)arg1;
                    try {
                        Toast.makeText(MainActivity.this, arg1.getInterfaceDescriptor(), Toast.LENGTH_LONG).show();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            };
            init();
        }
        
        private void init() {
            bind = (Button) findViewById(R.id.bind);
            unBind = (Button) findViewById(id.unBind);
            num = (EditText) findViewById(id.num);
    
            bind.setOnClickListener(new BindListenImpl());
            unBind.setOnClickListener(new UnBindListenImpl());
        }
        
        
        public class BindListenImpl implements OnClickListener {
            public void onClick(View arg0) {
                getNum=num.getText().toString();
                Intent intent=new Intent(MainActivity.this,ServicePhone.class);
                intent.putExtra("Nums", getNum);
                bindService(intent, connect, BIND_AUTO_CREATE);
            }
    
        }
    
        public class UnBindListenImpl implements OnClickListener {
            public void onClick(View arg0) {
                if(MainActivity.this.service != null) {
                    unbindService(connect) ;
                    stopService(new Intent(MainActivity.this,ServicePhone.class)) ;
                    getNum=null;
                    Toast.makeText(MainActivity.this, "黑名单已取消", Toast.LENGTH_LONG)
                            .show();
                    MainActivity.this.service = null ;
                }
    
            }
    
        }
    
        
        
        
        
        
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }

     

    权限配置

    <uses-permission android:name="android.permission.CALL_PHONE"/>

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

    广播配置:

    <receiver android:name="com.example.phonelistendemo.ReceivePhone">
    <intent-filter android:priority="999" >
    <action android:name="android.intent.action.PHONE_STATE" />
    <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
    </receiver>

    布局自行解决

                      (ps:我是菜鸟,勿喷,谢谢)

  • 相关阅读:
    归并排序
    mysql 基本查询
    APP版本升级
    top命令详解
    iptables原理详解
    Linux--iptables常用命令
    iptables语法常用命令总结(表格)
    iptables原理--图示理解
    GIT的Windows客户端使用
    Linux下GIT服务器端和客户端搭建
  • 原文地址:https://www.cnblogs.com/mydomainlistentome/p/4693850.html
Copyright © 2011-2022 走看看