android之来电自动拒接并自动回复短信_上课模式app「建议收藏」

上课的时候老师说总是错过电话,对方打来没人接还一遍遍的打,觉得可以有个app在上课期间自动拒接电话,并自动回复短信过去.当然了,需要权限的.尝试做了个雏形出来.界面如下:主要代码如下:package jason.teacher;import java.lang.reflect.Method;import java.util.HashMap;import ja

大家好,又见面了,我是全栈君。

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

当然了,需要权限的.

尝试做了个雏形出来.

界面如下:

android之来电自动拒接并自动回复短信_上课模式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://blog.csdn.net/jason0539(转载请说明出处)

扫码关注我微信公众号

android之来电自动拒接并自动回复短信_上课模式app「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121400.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • httprunner(4)录制生成测试用例[通俗易懂]

    httprunner(4)录制生成测试用例[通俗易懂]前言写用例之前,我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。har2case我们先来了解一下另一个项目har2case他的工作原理就是将当前主流的抓

    2022年7月31日
    3
  • 苹果电脑(Mac mini或Macbook或iMac)恢复出厂设置「建议收藏」

    苹果电脑(Mac mini或Macbook或iMac)恢复出厂设置「建议收藏」苹果电脑(Macmini或Macbook或iMac)恢复出厂设置,首先要做好如下的准备:第一:数据的备份;第二:保证正常的wifi连接;第三:有线的鼠标键盘连接;具体恢复操作步骤:步骤一:电脑启动时,按下键盘组合键(option+command+R,或alt+command+R);然后显示器屏幕上会显示小地球,且出现倒计时;步骤二:倒计时结束后,出现macOS实用工具,选择第四个…

    2022年6月16日
    572
  • Unity零基础到入门 ☀️| 游戏引擎 Unity 从0到1的 系统学习 路线【全面总结-建议收藏】![通俗易懂]

    Unity零基础到入门 ☀️| 游戏引擎 Unity 从0到1的 系统学习 路线【全面总结-建议收藏】![通俗易懂]Unity基础知识学习,Unity学习路线总结。本篇文章对Unity的学习路线做了一个全面系统的总结,对Unity有兴趣的小伙伴福利到了!敬请品尝~

    2022年6月12日
    28
  • 服务器托管双线技术方案怎么写_自己搭建内网穿透服务器全端口

    服务器托管双线技术方案怎么写_自己搭建内网穿透服务器全端口多线路接入技术就是在互联网数据中心(IDC)通过特殊的技术手段把不同的网络接入商(ISP)服务接入到一台服务器上或服务器集群,使服务器所提供的网络服务访问用户能尽可能以同一个ISP或互访速度较快的ISP连接来进行访问,从而解决或者减轻跨ISP用户访问网站的缓慢延迟(南北网络瓶颈)问题。多线路接入是一个技术概念可以有多种具体实现方式,由于大多用户都是网通与电信,为了见简单起见,我们只讨…

    2022年10月23日
    0
  • mysql 隐式类型转换_date_range函数

    mysql 隐式类型转换_date_range函数一、如果表定义的是varchar字段,传入的是数字,则会发生隐式转换。1、表DDL2、传int的sql3、传字符串的sql仔细看下表结构,rid的字段类型:而用户传入的是int,这里会有一个隐式转换的问题,隐式转换会导致全表扫描。把输入改成字符串类型,执行计划如下,这样就会很快了。此外,还需要注意的是:数字类型的0001等价于1字符串的0001和1不等价二、如果表定义的是int字段,传入的是字符串…

    2022年10月11日
    0
  • 十二、Maven项目模板「建议收藏」

    十二、Maven项目模板「建议收藏」Maven提供用户,使用原型的概念,不同类型的项目模板(以数字614)是一个非常大的列表。Maven帮助用户快速开始使用以下命令创建新的Java项目mvnarchetype:generate什么是原型?原型是一个Maven插件,其任务是创建一个项目结构按照其模板。我们将使用快速启动原型插件在这里创建一个简单的Java应用程序。使用项目模板让我们打开命令控制

    2022年7月19日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号