android开发之来电自动拒接并自动回复短信_上课模式app

上课的时候老师说总是错过电话,对方打来没人接还一遍遍的打,觉得可以有个app在上课期间自动拒接电话,并自动回复短信过去.

当然了,需要权限的.

尝试做了个雏形出来.

界面如下:

主要代码如下:

[java][/java] view plaincopyprint?

  1. package jason.teacher;
  2. import java.lang.reflect.Method;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import android.app.Activity;
  6. import android.content.Context;
  7. import android.content.SharedPreferences;
  8. import android.content.SharedPreferences.Editor;
  9. import android.os.Bundle;
  10. import android.telephony.PhoneStateListener;
  11. import android.telephony.SmsManager;
  12. import android.telephony.TelephonyManager;
  13. import android.util.Log;
  14. import android.view.View;
  15. import android.view.View.OnClickListener;
  16. import android.widget.Button;
  17. import android.widget.EditText;
  18. import android.widget.TextView;
  19. import com.android.internal.telephony.ITelephony;
  20. public class MainActivity extends Activity {
  21.     public final static String TAG = “jason.com”;
  22.     TelephonyManager tpm;
  23.     String num;//存储来电号码
  24.     Button end;//退出按钮
  25.     EditText sms;//回复短信的内容编辑框
  26.     SharedPreferences sp;
  27.     int count = 0;//来电总数
  28.     int peo = 0;//来电的号码个数,跟来电总数有区别,这个不包括重复来电,
  29.     TextView counttext;//拦截数量通知的显示
  30.     HashMap<String, String> numMap;//用来存储来电号码
  31.     @Override
  32.     public void onCreate(Bundle savedInstanceState) {
  33.         super.onCreate(savedInstanceState);
  34.         setContentView(R.layout.activity_main);
  35.         sp = this.getSharedPreferences(“SP”, MODE_PRIVATE);
  36.         counttext = (TextView) findViewById(R.id.count);
  37.         sms = (EditText) findViewById(R.id.sms);
  38.         end = (Button) findViewById(R.id.start);
  39.         numMap = new HashMap<String, String>();
  40.         if(sp.getString(“sms”, null) != null){
  41.             sms.setText(sp.getString(“sms”, “我现在正在上课,一会儿下课了联系你”));
  42.         }
  43.         tpm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);//获取电话通讯服务
  44.          tpm.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);//给电话服务增加状态监听器,监听来电,通话,挂断等状态
  45.         end.setOnClickListener(new OnClickListener() {
  46.             @Override
  47.             public void onClick(View v) {
  48.                 Editor editor = sp.edit();
  49.                 editor.putString(“sms”, sms.getText().toString());
  50.                 editor.commit();//这里是默认自动保存用户编辑过的回复短信内容的,
  51.                 finish();
  52.             }
  53.         });
  54.     }
  55.     class MyPhoneStateListener extends PhoneStateListener {
  56.         @Override
  57.         public void onCallStateChanged(int state, String incomingNumber) {
  58.             num = incomingNumber;
  59.             switch(state) {
  60.             case TelephonyManager.CALL_STATE_IDLE: //空闲
  61.                 break;
  62.             case TelephonyManager.CALL_STATE_RINGING: //来电
  63.                 endCall();//自动挂断
  64.                 if(!numMap.containsKey(num)){//如果之前没有来电,则把这个号码加入已经来电过的列表
  65.                     sendMes();
  66.                     numMap.put(num, null);
  67.                     peo ++;
  68.                     updateUi();//更新来电数目
  69.                 }
  70.                 break;
  71.             case TelephonyManager.CALL_STATE_OFFHOOK: //摘机(正在通话中)
  72.                 break;
  73.             }
  74.         }
  75.         private void updateUi(){
  76.             if(count > 0){
  77.                 counttext.setVisibility(View.VISIBLE);
  78.             }
  79.             counttext.setText(“已拒接” + count + “个来电,共” + peo +”个人联系过您,请到通话记录查看”);
  80.         }
  81.         private void endCall()//估计这里是唯一有点难度的,用到了java的反射
  82.         {
  83.             Class<TelephonyManager> c = TelephonyManager.class;
  84.             try
  85.             {
  86.                 Method getITelephonyMethod = c.getDeclaredMethod(“getITelephony”, (Class[]) null);
  87.                 getITelephonyMethod.setAccessible(true);
  88.                 ITelephony iTelephony = null;
  89.                 iTelephony = (ITelephony) getITelephonyMethod.invoke(tpm, (Object[]) null);
  90.                 iTelephony.endCall();
  91.                 count ++;
  92.                 updateUi();
  93.             }
  94.             catch (Exception e)
  95.             {
  96.                 Log.e(TAG, “Fail to answer ring call.”, e);
  97.             }
  98.         }
  99.         private void sendMes(){
  100.             //直接调用短信接口发短信
  101.             SmsManager smsManager = SmsManager.getDefault();
  102.             List<String> divideContents = smsManager.divideMessage(sms.getText().toString());
  103.             for (String text : divideContents) {
  104.                 smsManager.sendTextMessage(num, null, text, null, null);
  105.             }
  106.         }
  107.     }
  108. }

这里解释一下,在android在1.1版本后就已经把Phone类的相关API给隐藏起来了,想要用代码实现挂断电话的功能,就必须通过AIDL才行,然后利用反射来使用其方法。

第一步:在程序中新建一个包,包名必须为:com.android.internal.telephony,因为要使用aidl。

第二步:在这个包里面新建一个名为ITelephony.aidl的文件,然后在文件里面写入代码:

[java][/java] view plaincopyprint?

  1. package com.android.internal.telephony;
  2.     interface ITelephony{
  3.         boolean endCall();
  4.         void answerRingingCall();
  5.     }

这样就可以通过如下代码进行进一步获取拒接电话的api的操作了.

 

[java][/java] view plaincopyprint?

  1. private void endCall()
  2.         {
  3.             Class<TelephonyManager> c = TelephonyManager.class;
  4.             try
  5.             {
  6.                 Method getITelephonyMethod = c.getDeclaredMethod(“getITelephony”, (Class[]) null);
  7.                 getITelephonyMethod.setAccessible(true);
  8.                 ITelephony iTelephony = null;
  9.                 iTelephony = (ITelephony) getITelephonyMethod.invoke(tpm, (Object[]) null);
  10.                 iTelephony.endCall();
  11.                 count ++;
  12.                 updateUi();
  13.             }
  14.             catch (Exception e)
  15.             {
  16.                 Log.e(TAG, “Fail to answer ring call.”, e);
  17.             }
  18.         }

还有就是别忘了加权限,否则是一点效果都没有的.

[html][/html] view plaincopyprint?

  1. <uses-permission android:name=”android.permission.READ_PHONE_STATE” />
  2.     <uses-permission android:name=”android.permission.CALL_PHONE”/>
  3.     <uses-permission android:name=”android.permission.SEND_SMS”/>

不过有一点不解的是在这里没有用到打电话的权限,但是如果不加

[html][/html] view plaincopyprint?

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

的话,来电话的时候竟然不会进行挂断操作,尝试了好几次都是如此,最后只能再把这个权限加上,虽然在我看来完全没用,安装的时候还会让人觉得你这个应用会不会偷偷打电话啊.
当然了,这个完全可以做成后台服务的形式,不过老师就是上课才用,也没那么多要求,如果继续丰富一下,还是比较实用的.

标签