文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 实现电话拦截及拦截提示音功能的开发

2022-06-06 07:54

关注

  本文所讲的内容是在Android系统中如何写程序进行电话拦截,并发出拦截提示音提醒用户,可以说此功能还是比较实用的。

       1、电话拦截

       这个功能大家可能都知道了,就是利用反射原理调用ITelephony的隐藏方法来实现。

       2、拦截后提示忙音/空号/已关机/已停机

       这个功能其实是要用到MMI指令,具体如何设置呼叫转移的指定可以参考这里 http://baike.baidu.com/view/206402.html?fromTaglist。

       在本文中我们会用到“遇忙转移”的功能。中国移动的设置方式是 **67#电话号码#,取消方式为 ##67#。”无条件转移“用21代替67即可。这两个指令可以直接在手机的拨号界面输入并拨号测试。ITelephony的endcall方法挂断电话后,会提示电话忙。如果事前设置好了忙时转移到一个空号/已关机/已停机的电话号码,就会提示您拨的电话号码是空号/已关机/已停机。

       其实大家可以下载 xxx卫士看下,它设置来电拒接模式后,都是会启动设置MMI指令的界面。然后再去“设置->通话设置->来电转接”,看看 “占线时转接” 设置好的电话号码,就可以知道空号/已关机/已停机对应的电话号码是什么了。

       1、修改一下BLOCKED_NUMBER这个变量值,把它设置为你要测试拦截的电话号码。

       2、全部功能是在一个Activity里实现的,所以大家要先运行这个Activity,然后点击“设置呼叫转移”,设置好呼叫转移后,不要关闭这个Activity,关了就拦截不了电话了。有心的朋友可以自己去写一个Service在后台运行拦截功能。

       实现方式1:

       代码如下:


package net.toeach.android.callforwarding;   
import java.lang.reflect.Method;   
import android.app.Activity;   
import android.content.BroadcastReceiver;   
import android.content.Context;   
import android.content.Intent;   
import android.content.IntentFilter;   
import android.media.AudioManager;   
import android.net.Uri;   
import android.os.Bundle;   
import android.os.Handler;   
import android.os.Message;   
import android.os.RemoteException;   
import android.telephony.TelephonyManager;   
import android.util.Log;   
import android.view.View;   
import android.view.View.OnClickListener;   
import com.android.internal.telephony.ITelephony;   
  
public class MainActivity extends Activity {   
 private static final String TAG = MainActivity.class.getSimpleName();   
 private final static int OP_REGISTER = 100;   
 private final static int OP_CANCEL = 200;   
 private final static String BLOCKED_NUMBER = "1892501xxxx";//要拦截的号码   
 //占线时转移,这里13800000000是空号,所以会提示所拨的号码为空号   
  private final String ENABLE_SERVICE = "tel:**67*13800000000%23";   
  //占线时转移   
  private final String DISABLE_SERVICE = "tel:%23%2367%23";   
 private IncomingCallReceiver mReceiver;   
  private ITelephony iTelephony;   
  private AudioManager mAudioManager;   
  @Override  
  public void onCreate(Bundle savedInstanceState) {   
    super.onCreate(savedInstanceState);   
    setContentView(R.layout.main);   
    findViewById(R.id.btnEnable).setOnClickListener(new OnClickListener(){   
  public void onClick(View v) {   
     //设置呼叫转移   
     Message message = mHandler.obtainMessage();   
  message.what = OP_REGISTER;   
  mHandler.dispatchMessage(message);   
  }   
    });   
    findViewById(R.id.btnDisable).setOnClickListener(new OnClickListener(){   
  public void onClick(View v) {   
  //取消呼叫转移   
       Message message = mHandler.obtainMessage();   
    message.what = OP_CANCEL;   
    mHandler.dispatchMessage(message);   
  }   
    });   
    mReceiver = new IncomingCallReceiver();   
 IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");     
    registerReceiver(mReceiver, filter);// 注册BroadcastReceiver   
    mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);   
    //利用反射获取隐藏的endcall方法   
    TelephonyManager telephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);   
 try {   
  Method getITelephonyMethod = TelephonyManager.class.getDeclaredMethod("getITelephony", (Class[]) null);   
  getITelephonyMethod.setAccessible(true);   
  iTelephony = (ITelephony) getITelephonyMethod.invoke(telephonyMgr, (Object[]) null);   
   } catch (Exception e) {   
   e.printStackTrace();   
   }   
  }   
  private Handler mHandler = new Handler() {   
 public void handleMessage(Message response) {   
   int what = response.what;   
   switch(what) {   
    case OP_REGISTER:{   
    Intent i = new Intent(Intent.ACTION_CALL);   
       i.setData(Uri.parse(ENABLE_SERVICE));   
       startActivity(i);   
    break;   
    }   
    case OP_CANCEL:{   
    Intent i = new Intent(Intent.ACTION_CALL);   
       i.setData(Uri.parse(DISABLE_SERVICE));   
       startActivity(i);   
    break;   
    }   
   }   
 }   
 };   
 private class IncomingCallReceiver extends BroadcastReceiver{   
 @Override  
 public void onReceive(Context context, Intent intent) {   
  String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);   
     Log.i(TAG, "State: "+ state);   
  String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);   
     Log.d(TAG, "Incomng Number: " + number);   
     if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){//电话正在响铃        
     if(number.equals(BLOCKED_NUMBER)){//拦截指定的电话号码   
      //先静音处理   
      mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);   
      Log.d(TAG, "Turn ringtone silent");   
      try {   
      //挂断电话   
   iTelephony.endCall();   
   } catch (RemoteException e) {   
   e.printStackTrace();   
   }   
   //再恢复正常铃声   
         mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);   
     }   
     }   
 }   
 }   
}  

         AndroidManifest.xml 如下:


<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android "  
   package="net.toeach.android.callforwarding"  
   android:versionCode="1"  
   android:versionName="1.0">  
  <application android:icon="@drawable/icon" android:label="@string/app_name">  
    <activity android:name=".MainActivity"  
         android:label="@string/app_name">  
      <intent-filter>  
        <action android:name="android.intent.action.MAIN" />  
        <category android:name="android.intent.category.LAUNCHER" />  
      </intent-filter>  
    </activity>  
  </application>  
  <uses-sdk android:minSdkVersion="8" />  
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>  
  <uses-permission android:name="android.permission.CALL_PHONE"/>  
</manifest>   

        实现方式2:

       1、建立包android.refuseCalling。

       refuseCalling.java代码如下:


package android.refuseCalling;   
import android.app.Activity;   
import android.net.Uri;   
import android.os.Bundle;   
import java.lang.reflect.InvocationTargetException;   
import java.lang.reflect.Method;   
import android.content.Context;   
import android.content.Intent;   
import android.os.RemoteException;   
import android.telephony.PhoneStateListener;   
import android.telephony.TelephonyManager;   
import android.util.Log;   
import android.widget.TextView;   
import com.android.internal.telephony.ITelephony;   
public class refuseCalling extends Activity {   
  private static final String TAG = "Telephony";   
  private TextView view = null;   
  private TelephonyManager tManager = null;   
  private ITelephony iTelephony = null;   
   //占线时转移,提示所拨的号码为空号   
  private final String ENABLE_SERVICE = "tel:**67*13800000000%23";   
   //占线时转移,提示所拨的号码为关机   
  private final String ENABLE_POWEROFF_SERVICE = "tel:**67*13810538911%23";   
  //占线时转移,提示所拨的号码为停机   
  private final String ENABLE_STOP_SERVICE = "tel:**21*13701110216%23";   
  //占线时转移   
  private final String DISABLE_SERVICE = "tel:%23%2321%23";   
  @Override  
  protected void onCreate(Bundle savedInstanceState) {   
    super.onCreate(savedInstanceState);   
    //打开监听电话功能   
    TelephonyManager mTelephonyMgr = (TelephonyManager) this  
        .getSystemService(Context.TELEPHONY_SERVICE);   
    mTelephonyMgr.listen(new TeleListener(),   
        PhoneStateListener.LISTEN_CALL_STATE);   
    //gui   
    view = new TextView(this);   
    view.setText("listen the state of phone\n");   
    setContentView(view);   
    tManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);   
    //初始化iTelephony   
    Class <TelephonyManager> c = TelephonyManager.class;   
    Method getITelephonyMethod = null;   
    try {   
    getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[])null);   
    getITelephonyMethod.setAccessible(true);   
    } catch (SecurityException e) {   
    // TODO Auto-generated catch block   
    e.printStackTrace();   
    } catch (NoSuchMethodException e) {   
    // TODO Auto-generated catch block   
    e.printStackTrace();   
    }   
    try {   
    iTelephony = (ITelephony) getITelephonyMethod.invoke(tManager, (Object[])null);   
    } catch (IllegalArgumentException e) {   
    // TODO Auto-generated catch block   
    e.printStackTrace();   
    } catch (IllegalAccessException e) {   
    // TODO Auto-generated catch block   
    e.printStackTrace();   
    } catch (InvocationTargetException e) {   
    // TODO Auto-generated catch block   
    e.printStackTrace();   
    }   
    //启用空号提示   
    Intent i = new Intent(Intent.ACTION_CALL);   
    i.setData(Uri.parse(ENABLE_STOP_SERVICE));   
    startActivity(i);   
    Log.v(TAG, "启用空号提示");   
  }   
  class TeleListener extends PhoneStateListener {   
    @Override  
    public void onCallStateChanged(int state, String incomingNumber) {   
      super.onCallStateChanged(state, incomingNumber);   
      switch (state) {   
      case TelephonyManager.CALL_STATE_IDLE: {   
        Log.e(TAG, "CALL_STATE_IDLE");   
        view.append("CALL_STATE_IDLE " + "\n");   
        break;   
      }   
      case TelephonyManager.CALL_STATE_OFFHOOK: {   
        Log.e(TAG, "CALL_STATE_OFFHOOK");   
        view.append("CALL_STATE_OFFHOOK" + "\n");   
        break;   
      }   
      case TelephonyManager.CALL_STATE_RINGING: {   
        Log.e(TAG, "CALL_STATE_RINGING");   
        view.append("CALL_STATE_RINGING" + "\n");   
        try {   
          iTelephony.endCall();             
        } catch (RemoteException e1) {   
          // TODO Auto-generated catch block   
          e1.printStackTrace();   
        }           
        break;   
      }   
      default:   
        break;   
      }   
    }   
  }   
  protected void onStop() {   
    super.onStop();   
    }   
  protected void onDestroy() {   
    super.onDestroy();   
    finish();   
    Intent i = new Intent(Intent.ACTION_CALL);   
    i.setData(Uri.parse(DISABLE_SERVICE));   
    startActivity(i);   
    }   
}  

       2、建立包android.telephony。

       NeighboringCellInfo.aidl代码如下:

       package android.telephony;

       3、建立包 com.android.internal.telephony。

       ITelephony.aidl代码如下:


  
package com.android.internal.telephony;   
import android.os.Bundle;   
import java.util.List;   
import android.telephony.NeighboringCellInfo;   
//import com.FrameSpeed.NeighboringCellInfo;   
  
interface ITelephony {   
    
  void dial(String number);  
  
  void call(String number);   
    
  boolean showCallScreen();   
    
  boolean showCallScreenWithDialpad(boolean showDialpad);   
    
  boolean endCall();   
    
  void answerRingingCall();   
    
  void silenceRinger();   
    
  boolean isOffhook();   
    
  boolean isRinging();   
    
  boolean isIdle();   
    
  boolean isRadioOn();   
    
  boolean isSimPinEnabled();   
    
  void cancelMissedCallsNotification();   
    
  boolean supplyPin(String pin);   
     
  boolean supplyPuk(String puk, String pin);   
    
  boolean handlePinMmi(String dialString);  
  
  void toggleRadioOnOff();   
    
  boolean setRadio(boolean turnOn);   
    
  void updateServiceLocation();   
    
  void enableLocationUpdates();   
    
  void disableLocationUpdates();   
    
  int enableApnType(String type);   
    
  int disableApnType(String type);   
    
  boolean enableDataConnectivity();   
    
  boolean disableDataConnectivity();   
    
  boolean isDataConnectivityPossible();   
  Bundle getCellLocation();   
    
  List<NeighboringCellInfo> getNeighboringCellInfo();   
   int getCallState();   
   int getDataActivity();   
   int getDataState();   
    
  int getActivePhoneType();   
    
  int getCdmaEriIconIndex();   
    
  int getCdmaEriIconMode();   
    
  String getCdmaEriText();   
    
  boolean needsOtaServiceProvisioning();   
    
  int getVoiceMessageCount();   
    
  int getNetworkType();   
    
  boolean hasIccCard();   
}   
parcelable NeighboringCellInfo; 

  4、AndroidManifest.xml代码如下:


<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
   package="android.refuseCalling"  
   android:versionCode="1"  
   android:versionName="1.0">  
   <uses-permission android:name="android.permission.READ_PHONE_STATE" />    
   <uses-permission android:name="android.permission.CALL_PHONE" />    
   <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />        
  <application android:icon="@drawable/icon" android:label="@string/app_name">  
    <activity android:name=".refuseCalling"  
         android:label="@string/app_name">  
      <intent-filter>  
        <action android:name="android.intent.action.MAIN" />  
        <category android:name="android.intent.category.LAUNCHER" />  
      </intent-filter>  
    </activity>  
  </application>  
</manifest>  

希望通过此文能对开发Android 开发电话应用的朋友提供帮助,谢谢大家对本站的支持!

您可能感兴趣的文章:Android震动与提示音实现代码android开发之蜂鸣提示音和震动提示的实现原理与参考代码Android仿微信新消息提示音


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯