Android 小应用:“自动拨打电话app”制作心得
来源:互联网 发布:mod安装软件 编辑:程序博客网 时间:2024/04/30 10:11
前言
最近做了一个Android小应用,可以接受短信或服务器发来的指令,根据指令自动拨打保存在app里面对应的电话号码,觉得挺有意思的。而且通过这个app,让我熟悉了很多Android的知识,在这里分享并记录一下。
功能
- 保存电话号码及对应的指令。
- 指令可以从短信获取,也可以从服务器获取。
- 根据指令,获取相应的电话号码,并轮流拨打。
- 可以设置号码保护时间,在这个时间以内,即使获取到相应的指令,也不会拨打此号码。
- 可以设置从服务器获取指令的间隔。
- 可以打开或关闭从服务器获取指令。
- 可以打开或关闭从短信息获取指令。
知识点
- 为ActionBar添加按钮
- 子Activity向上导航的实现
- ListView的使用
- SQLite数据库的使用
- SharedPreferences的使用
- 如何拦截短信息
- 如何在不操作的情况下自动拨打电话
- 如何监听电话的拨打状态
- 使用Service实现不间断的后台网络请求
- 使用volley实现网络请求
- AndroidStudio添加model
实现思路
1.添加\修改\删除一条号码及对应的指令
- 将number和sms封装成bean;
- 创建ItemsDBHelper类,继承SQLiteOpenHelper;
- 使用ItemsDBHelper创建表items,列名分别为:number,sms;
- ItemsDBHelper判断数据库中有没有这条数据:
public boolean hasItem(ItemBean itemBean) { String selection = COLUMN_SMS + "=? AND " + COLUMN_NUMBER + "=?"; String[] selectionArgs = new String[] {itemBean.getSms(), itemBean.getNumber()}; Cursor cursor = this.db.query(TABLE_NAME, null, selection, selectionArgs, null, null,null); if(cursor == null || cursor.getCount() == 0) { return false; } else { return true; } }
- ItemsDBHelper封装添加\修改\删除方法:
public void saveItem(ItemBean itemBean) { if(hasItem(itemBean)) { return; } ContentValues values = new ContentValues(); values.put(COLUMN_SMS, itemBean.getSms()); values.put(COLUMN_NUMBER, itemBean.getNumber()); db.insert(TABLE_NAME, "", values); } public void deleteItem(ItemBean itemBean) { String selection = COLUMN_SMS + "=? AND " + COLUMN_NUMBER + "=?"; String[] selectionArgs = {itemBean.getSms(), itemBean.getNumber()}; this.db.delete(TABLE_NAME, selection, selectionArgs); } public void updateItem(ItemBean oldItemBean, ItemBean newItemBean) { deleteItem(oldItemBean); saveItem(newItemBean); }
2.在主界面上显示所有号码及对应的指令。
- 在ItemsDBHelper创建查询方法:
public ArrayList<ItemBean> loadItems() { ArrayList<ItemBean> itemBeans = new ArrayList<ItemBean>(); Cursor cursor = this.db.query(TABLE_NAME, null, null, null, null, null,null); if(cursor != null) { while (cursor.moveToNext()) { ItemBean itemBean = new ItemBean(); itemBean.setSms(cursor.getString(cursor.getColumnIndex(COLUMN_SMS))); itemBean.setNumber(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER))); itemBeans.add(itemBean); } } Log.i(Config.TAG, "ItemsDBHelper->loadItems: " + itemBeans); return itemBeans; }
- 在Adapter中,将数据取出,并显示。
mItems = mItemsDBHelper.loadItems();
在getView()
中将值赋给每一行:
holder.tvSms.setText(mItems.get(position).getSms());holder.tvNumber.setText(mItems.get(position).getNumber());
3.拦截短信息,获取到指令
4.不间断请求服务器,获取到指令
- 开启一个前台Service,每过一段时间请求一次服务器:
private void executeNetListen() { new Handler().postDelayed(new Runnable() { public void run() { if(getIsReceiveServerMsg()) { requestServer(); } executeNetListen(); } }, getIntervalTime()); }
5.根据指令获取到相应的号码
- 在ItemsDBHelper中,创建方法
getNumbers(String sms)
,返回一个放号码的ArrayList:
public ArrayList<String> getNumbers(String sms) { ArrayList<String> sNumbers = new ArrayList<String>(); String selection = COLUMN_SMS + "=?"; String[] selectionArgs = new String[] {sms}; Cursor cursor = this.db.query(TABLE_NAME, null, selection, selectionArgs, null, null,null); if(cursor != null) { while (cursor.moveToNext()) { String sNumber = cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER)); sNumbers.add(sNumber); } } return sNumbers; }
6.创建表current_task
- 表current_task用来存放当前需要打的电话,相当于一个队列的概念;
- 创建CurrentTaskDBHelper类,继承SQLiteOpenHelper;
- 使用CurrentTaskDBHelper创建表current_task,列名分别为:phone_number,add_time;
7.将号码添加到表current_task
- 如果当前要插入的号码,在表中已经存在,那么不再插入;
8.从表current_task提取一条号码出来
- 根据add_time,提取最先添加的一条号码;
- 提取出来以后,说明这个号码要被执行,可以从表中删掉;
9.创建表done_task
- 表done_task用来存放拨打过的电话,相当于一个历史记录的概念;
- 创建CurrentTaskDBHelper类,继承SQLiteOpenHelper;
- 使用CurrentTaskDBHelper创建表current_task,列名分别为:phone_number,add_time;
10.将号码同表done_task的号码做比较
- 将current_task提取的号码拿到done_task中查询;
- 离上次拨打过去的时间s_time,s_time =(当前时间 - add_time);
- 如果号码在dome_task中没有找到,或者s_time>号码保护时间,执行第11步,并跟新add_time为当前时间;
- 如果s_time<号码保护时间,执行第8步;
11.执行打电话的动作
- 系统将自动拨打电话;
12.监听到挂断状态
- 当通话界面收起的时候(通常是对方挂断电话,语音提示结束以后),挂断状态被监听到;
- 继续执行第8步;
13.拨打保护
- 创建标志位
FLAG_IS_ON_CALL_TASK
,保存在SharedPreferences
中,用来表示是否正在执行拨打任务; - 当拨打任务开始时,
FLAG_IS_ON_CALL_TASK
为true;任务结束后FLAG_IS_ON_CALL_TASK
为false; - 如果任务执行过程中,接受到新的指令,则只把号码添加到current_task中(第7步),而不调用电话拨打(第八步);
- 这样可以防止通话被干扰;
14.拨打任务结束
- 表current_task中的号码,会在任务执行过程中越来越少;
- 表current_task一条号码也没有时,从方法中return,结束当前任务;
总结
- 短信的拦截;
- 后台不断监听服务器信息;
- SQLite的查询、添加、修改、删除;
- current_task是一个队列,按顺序拨打;
- done_task会记录号码上次拨打的时间;
- 拨打任务的执行中,添加标志位,防止通话被干扰;
- current_task中没有号码,结束通话任务;
附上代码地址
https://github.com/deeepthinking/AutoPhoneCall
0 0
- Android 小应用:“自动拨打电话app”制作心得
- android自动拨打电话
- Android 自动拨打电话
- android-拨打电话应用
- 【Android】Android开发初学者实现拨打电话的功能,拨打电话app小demo实现
- App应用中拨打电话
- Android 应用中拨打电话
- Android应用之电话拨打
- Android 如何自动拨号+拨打电话
- Android小程序——拨打电话
- android小功能实现之拨打电话
- 拨打电话小程序
- iOS应用拨打电话
- (小笔记) android 直接拨打电话和进入拨打电话界面
- android监听通话时长只针对在APP中拨打电话
- android实现拨打电话
- android拨打电话
- android学习---拨打电话
- Activity四种启动模式及应用
- 在eclipse中将android工程打包成apk 获取正式版本 Android 打包签名 从生成keystore到完成签名
- 解读“Deep Neural Decision Forests” 2015 Winner of the David Marr Prize
- 多线程
- Tomcat Server处理一个http请求的过程
- Android 小应用:“自动拨打电话app”制作心得
- LDA(Latent Dirichlet Allocation)相关论文阅读小结
- 我的第一个博客
- Android数据输入测试的checklist
- 内存管理以及Autorelease和自动释放池
- 面向对象的六大原则之 —— 迪米特原则
- 利用Intellij IDEA构建开发环境
- hibernate get 和load
- tableview section之间的距离