挂断电话——黑名单拦截

需要用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:我是菜鸟,勿喷,谢谢)

原文地址:https://www.cnblogs.com/mydomainlistentome/p/4693850.html