挂断电话——黑名单拦截

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

时间: 2024-10-08 08:16:15

挂断电话——黑名单拦截的相关文章

android怎么实现自动接听和挂断电话功能

原文地址:http://zhidao.baidu.com/link?url=LVQ9uI0sHUWtKOroOLc21aaAWOuJDZnqL4TXfwF5bQOUqCULMl3Ayzg5BBY29CuqQVcyvAY6DlrYpmUhyoiNGkOJhn1t37SZCmdrSNyIyby Android自动接听和挂断电话实现原理:http://blog.csdn.net/chenda_lin/article/details/41346493 Android提供的系统服务之--Telephony

Android自动接听&amp;挂断电话(包含怎么应对4.1以上版本的权限检

一  前言 这两天要研究类似白名单黑名单以及手势自动接听的一些功能,所以呢,自然而然的涉及到怎么自动接听/挂断电话的功能了.对于自动接听这一块,android4.1版本及其以上的版本和之前的版本处理逻辑不太一样,因为google增加了权限检查...所以,按照以前的方法可能不能实现自动接听了. 二  android低版本自动接听/挂断实现 1. copy android源代码的ITelephony.aidl文件到自己的项目为什么要copy这个文件到自己的项目中呢?这是因为接听/挂断电话的方法在接口

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

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

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

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

Android挂断电话以及Java Class Loader

Android中,要自己实现一个挂断电话方法时,很久之前可以endCall().不过现在已经不行了,要应用反射机制,获取到 "android.os.ServiceManager" 的Class,然后通过反射调用其中的方法,具体如下: 在这个过程中,相当于远程调用系统的Service方法,也就是用到了AIDL机制,需要找到系统的两个AIDL拷贝到自己的项目中 : 然后方法代码如下: //挂断电话操作 private void endCall() { //IBinder b = Servi

Android 实现自动接听和挂断电话功能

添加权限 <uses-permission android:name="android.permission.CALL_PHONE"/> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> main.xml <?xml version="1.0" encoding="utf-8"?> <Line

Android开发教程--自定义接听/挂断电话功能

1.首先在manifest中加入如下的权限 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" > </uses-permission> <uses-permission android:name=

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

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

手机卫士06_挂电话拦截短信,资产目录_来电去电_自定义吐司

1.1 反射调用系统隐藏api挂掉电话 Android 1.5之前可以通过 TelephonyManager,tm.endCall();//但是列表找不到 谷歌认为挂掉电话是危及手机根本功能的动作,所以隐藏了这个api 在1.5之后,要通过反射调用这一api才能实现 两个网站 ①www.greocide.com //搜索源码的网站 搜索TelephonyManager,查找版本最低的版本即可(越低越容易理解) 这个api被隐藏掉了,不能直接获取到TelephonyManager.对象. ②通过g