zoukankan      html  css  js  c++  java
  • [置顶] android开发之来电自动拒接并自动回复短信_上课模式app

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

    当然了,需要权限的.

    尝试做了个雏形出来.

    界面如下:

    主要代码如下:

    package jason.teacher;
    
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.List;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.os.Bundle;
    import android.telephony.PhoneStateListener;
    import android.telephony.SmsManager;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import com.android.internal.telephony.ITelephony;
    
    public class MainActivity extends Activity {
    	
        public final static String TAG = "jason.com";
        TelephonyManager tpm;
        String num;//存储来电号码
        Button end;//退出按钮
        EditText sms;//回复短信的内容编辑框
        SharedPreferences sp;
        int count = 0;//来电总数
        int peo = 0;//来电的号码个数,跟来电总数有区别,这个不包括重复来电,
        TextView counttext;//拦截数量通知的显示
        HashMap<String, String> numMap;//用来存储来电号码
        @Override
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);
            sp = this.getSharedPreferences("SP", MODE_PRIVATE);
            counttext = (TextView) findViewById(R.id.count);
            sms = (EditText) findViewById(R.id.sms);
            end = (Button) findViewById(R.id.start);
            numMap = new HashMap<String, String>();
            if(sp.getString("sms", null) != null){
            	sms.setText(sp.getString("sms", "我现在正在上课,一会儿下课了联系你"));
            }
            tpm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);//获取电话通讯服务
             tpm.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);//给电话服务增加状态监听器,监听来电,通话,挂断等状态
            end.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				Editor editor = sp.edit();
    				editor.putString("sms", sms.getText().toString());
    				editor.commit();//这里是默认自动保存用户编辑过的回复短信内容的,
    				finish();
    			}
    		});
        }
        class MyPhoneStateListener extends PhoneStateListener {
        	@Override
            public void onCallStateChanged(int state, String incomingNumber) {
        		num = incomingNumber;
                switch(state) {
                case TelephonyManager.CALL_STATE_IDLE: //空闲
                    break;
                case TelephonyManager.CALL_STATE_RINGING: //来电
                	endCall();//自动挂断
                	if(!numMap.containsKey(num)){//如果之前没有来电,则把这个号码加入已经来电过的列表
                		sendMes();
                		numMap.put(num, null);
                		peo ++;
                		updateUi();//更新来电数目
                	}
                	break;
                case TelephonyManager.CALL_STATE_OFFHOOK: //摘机(正在通话中)
                    break;
                }
            }
        	private void updateUi(){
        		if(count > 0){
        			counttext.setVisibility(View.VISIBLE);
        		}
        		counttext.setText("已拒接" + count + "个来电,共" + peo +"个人联系过您,请到通话记录查看");
        	}
        	private void endCall()//估计这里是唯一有点难度的,用到了java的反射
            {  
                Class<TelephonyManager> c = TelephonyManager.class;           
                try
                {  
                    Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);  
                    getITelephonyMethod.setAccessible(true);  
                    ITelephony iTelephony = null;
                    iTelephony = (ITelephony) getITelephonyMethod.invoke(tpm, (Object[]) null);  
                    iTelephony.endCall();
                    count ++;
                    updateUi();
                }  
                catch (Exception e)  
                {  
                    Log.e(TAG, "Fail to answer ring call.", e);  
                }          
            }  
        	
        	private void sendMes(){
        		//直接调用短信接口发短信
        		SmsManager smsManager = SmsManager.getDefault();
        		List<String> divideContents = smsManager.divideMessage(sms.getText().toString()); 
        		for (String text : divideContents) {    
        			smsManager.sendTextMessage(num, null, text, null, null);  
        		}
        	}
        }
    }
    

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

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

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

    package com.android.internal.telephony;
    	interface ITelephony{
    		boolean endCall();
    		void answerRingingCall();
    	}

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

    private void endCall()
            {  
                Class<TelephonyManager> c = TelephonyManager.class;           
                try
                {  
                    Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);  
                    getITelephonyMethod.setAccessible(true);  
                    ITelephony iTelephony = null;
                    iTelephony = (ITelephony) getITelephonyMethod.invoke(tpm, (Object[]) null);  
                    iTelephony.endCall();
                    count ++;
                    updateUi();
                }  
                catch (Exception e)  
                {  
                    Log.e(TAG, "Fail to answer ring call.", e);  
                }          
            }  

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

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

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

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

    的话,来电话的时候竟然不会进行挂断操作,尝试了好几次都是如此,最后只能再把这个权限加上,虽然在我看来完全没用,安装的时候还会让人觉得你这个应用会不会偷偷打电话啊.


    当然了,这个完全可以做成后台服务的形式,不过老师就是上课才用,也没那么多要求,如果继续丰富一下,还是比较实用的.

    作者:jason0539

    微博:http://weibo.com/2553717707

    博客:http://blog.csdn.net/jason0539(转载请说明出处)

  • 相关阅读:
    copy深浅拷贝
    def函数
    内置函数
    for / while 循环
    报告的实现
    运行用例
    集合获取依赖用例
    解决依赖关系(单层和递归两种方式)、获取依赖用例去运行
    接口测试平台开发之接口开发(用例集合)
    接口测试平台开发之接口开发(项目管理、接口管理、用例管理)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3306247.html
Copyright © 2011-2022 走看看