Android实战_来电拦截专家
1 项目演示:



2 代码演示:
1)MainActivity类代码:
MainActivity类代码:
package com.example.phoneinteceptor_one;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.bean.BlackInfo;
import com.example.db.BlackInfoDao;
/**
* 主界面
1. 查询所有黑名单的列表并显示
2. 在查询输入框中输入关键字时, 显示所有匹配的黑名单列表
3. 在添加界面, 点击确认将信息保存到数据库表, 并回到主界面显示最新的列表
4. 长按某个黑名单项显示删除/修改的上下文菜单
点击删除的菜单项删除选定的黑名单, 并显示最新的列表
选中一些黑名单后项后, 点击删除按钮, 提示删除所有选中的黑名单
选中全选则所有黑名单选中, 否则都不选中
点击修改的上下文菜单项进入修改界面, 并显示选中的黑名单信息
在修改界面, 修改信息后, 点击确定修改表中对应的数据, 回到主界面显示新列表
*/
public class MainActivity extends Activity implements OnItemClickListener, OnClickListener, OnCheckedChangeListener {
private ListView lv_black_list;
private List<BlackInfo> data;
private BlackInfoDao blackInfoDao;
private BlackAdapter adapter;
private EditText atv_black_list_search;
private Button btn_black_list_delete;
private CheckBox cb_black_list_selectall;
//内部类---实现监听文本框的输入查询的内容时刻监听
private TextWatcher watcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
//在内容改变之后 就回调
@Override
public void afterTextChanged(Editable s) {
//获取输入的数据
String key = s.toString();
//查询要查询的列表数据--赋值给data
data = blackInfoDao.getBlacks(key);
//更新列表
lv_black_list.setAdapter(adapter);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取显示的listview id
lv_black_list = (ListView) findViewById(R.id.lv_black_list);
btn_black_list_delete = (Button) findViewById(R.id.btn_black_list_delete);
cb_black_list_selectall = (CheckBox) findViewById(R.id.cb_black_list_selectall);
btn_black_list_delete.setOnClickListener(this);
//实现点击item事件方法
lv_black_list.setOnItemClickListener(this);
//需要数据 --集合数据--数据的初始化
blackInfoDao = new BlackInfoDao(this);
cb_black_list_selectall.setOnCheckedChangeListener(this);
// data = new DataSource().getAllBlacks();
data = blackInfoDao.getAll();//从数据库里面取数据
// BaseAdapter
//创建一个适配器--是一个抽象类 定义一个类去继承他
adapter = new BlackAdapter();
//显示设置数据到适配器
lv_black_list.setAdapter(adapter);
atv_black_list_search = (EditText) findViewById(R.id.atv_black_list_search);
//监听atv_black_list_search数据的改变
atv_black_list_search.addTextChangedListener(watcher);
//实现长按住一个item 弹出一个对话框 出来 是否删除还是取消-当前的activiet就是这类型的this
lv_black_list.setOnCreateContextMenuListener(this);
}
//lv_black_list.setOnCreateContextMenuListener(this);
//实现长按住一个item 默认的回调的方法1
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
//获取poistion
AdapterContextMenuInfo contextMenuInfo = (AdapterContextMenuInfo) menuInfo;
int position = contextMenuInfo.position;
//ItemId 不能一样menu.add(position, ItemId, 1, "更新");
menu.add(position, 1, 1, "更新");
menu.add(position, 2, 1, "删除");
}
//实现长按住一个item 默认的回调的方法2--获取是点击的删除还是更新
@Override
public boolean onContextItemSelected(MenuItem item) {
//获取点击的向
int itemId = item.getItemId();
if(itemId==1) {//更新
} else if(itemId==2) {//删除
//获取poistion
int position = item.getGroupId();
blackInfoDao.delete(data.get(position).get_id());
data.remove(position);//移除位置标号
adapter.notifyDataSetChanged();//通知更新界面
}
return super.onContextItemSelected(item);
}
//实现点击添加按钮 实现跳转到添加页面去
public void startAdd(View view){
int resultCode=1;
//startActivity(new Intent(this,BlackAddActivity.class));
//为了实现到添加数据成功之后--返回来更新列比列表的信息 所有--
startActivityForResult(new Intent(this,BlackAddActivity.class),resultCode);
}
//实现点击退出按钮
public void exit(View view){
finish();
}
//当添加界面返回时调用----完数据之后 就返回来---
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
//回调方法--requestCode请求码--resultCode结果码
if(requestCode==1 && resultCode==2){
//都满足--就更新就界面
data = blackInfoDao.getAll();
//去更新感应最新的数据
lv_black_list.setAdapter(adapter);
}
}
class BlackAdapter extends BaseAdapter {
//巧妙之处
private String[] types = {"电话+短信","电话","短信"};
@Override
public int getCount() { // 数据集合中数据的个数
return data.size();
}
@Override
public Object getItem(int position) {// 返回指定下标的数据对象
return data.get(position);
}
@Override
public long getItemId(int position) {// 这个不重要
return position;
}
// 此方法最关键
// 根据指定的下标返回将要显示的item中的一个View对象
// 返回的View对象中必须包含显示的数据--包含对应的数据
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//加载item的布局文件--打气筒
convertView = View.inflate(MainActivity.this, R.layout.black_item, null);
//设置对应的数据到对应的视图中
TextView number =(TextView) convertView.findViewById(R.id.tv_item_number);
TextView name =(TextView) convertView.findViewById(R.id.tv_item_name);
TextView type =(TextView) convertView.findViewById(R.id.tv_item_type);
//获取当前位置的数据 返回的是的一个对象
BlackInfo info = data.get(position);
//把数据放到按键中去
number.setText(info.getNumber());
name.setText(info.getName());
//巧妙的地方就在这
type.setText(types[info.getType()]);
//返回
return convertView;
}
}
//实现点击item向 回调方法
@Override
public void onItemClick(AdapterView<?> arg0, View view, int poisoion, long arg3) {
CheckBox box = (CheckBox) view.findViewById(R.id.cb_item_black);//点击复选框
box.toggle();//切换选中状态
//弹出对话框
Toast.makeText(this,data.get(poisoion).getNumber(),0).show();
}
@Override
public void onClick(View v) {
if (v == btn_black_list_delete) {
List<Integer> selectIds = new ArrayList<Integer>();
for (BlackInfo blackNumber : data) {
if (blackNumber.isChecked()) {
selectIds.add(blackNumber.get_id());
}
}
if (selectIds.size() == 0) {
Toast.makeText(this, "请选择要删除的项", 0).show();
} else {
showDeleteDialog(selectIds);
}
}
}
private void showDeleteDialog(final List<Integer> selectIds) {
new AlertDialog.Builder(this)
.setTitle("黑名单删除")
.setMessage("你确认删除选中项吗?")
.setPositiveButton(R.string.confirm,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
blackInfoDao.deleteBlacks(selectIds);
List<BlackInfo> list = blackInfoDao
.getAll();
list.addAll(list);
adapter.notifyDataSetChanged();
}
}).setNegativeButton(R.string.cancel, null).show();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
for (BlackInfo blackNumber : data) {
blackNumber.setChecked(isChecked);
}
adapter.notifyDataSetChanged();
}
}
2)BlackAddActivity类代码:
package com.example.phoneinteceptor_one;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;
import com.example.bean.BlackInfo;
import com.example.db.BlackInfoDao;
public class BlackAddActivity extends Activity {
public Button btn_black_add_cancel;
private BlackInfoDao blackInfoDao;
private BlackInfo info = new BlackInfo();
private EditText et_black_add_number;
private EditText et_black_add_name;
private RadioGroup rg_black_add_actions;
//内部类--点击复选框的监听事件
private OnCheckedChangeListener listener = new OnCheckedChangeListener () {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//这是checkedId是你选择的RadioButton的id
RadioButton rb =(RadioButton) group.findViewById(checkedId);
String tog = (String)rb.getTag(); //0 1 2
//Log.d("BlackAddActivity","togtogtogtogtog=="+tog);
info.setType(Integer.parseInt(tog)); //转换成整形设置到实例
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_black_add);
//实例化义务逻辑实例
blackInfoDao = new BlackInfoDao(this);
et_black_add_number = (EditText) findViewById(R.id.et_black_add_number);
et_black_add_name = (EditText) findViewById(R.id.et_black_add_name);
rg_black_add_actions = (RadioGroup) findViewById(R.id.rg_black_add_actions);
//实现点击复选框的监听事件
rg_black_add_actions.setOnCheckedChangeListener(listener);
//点击取消时 实现回到主界面
findViewById(R.id.btn_black_add_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//回到上一个界面--干掉自己
finish();
}
});
}
//实现点击确认 保存数据到数据库
public void saveBlackInfo(View view){
//验证数据是否输入合法
String number = et_black_add_number.getText().toString().trim();
if(number.length()==0){
Toast.makeText(this, "电话号码不能为空", 0).show();
return ;
}
info.setNumber(number);
//name
String name = et_black_add_name.getText().toString().trim();
if(number.length()==0){
name = number;//不指定名称 就把你的号码 赋值给你的名称
// Toast.makeText(this, "必须指定号码", 0).show();
}
info.setName(name);
//保存数据到表里面
blackInfoDao.add(info);
//设置一个返回的结果码、-给要返回的界面一个结果码--以便标识出来
int resultCode = 2;
setResult(resultCode);
//返回到上一个界面--通知上一个界面 更新列表
finish();//所谓的是自己干掉自己
Toast.makeText(this, "添加成功!", 0).show();
}
}
3)AndroidManifest.xml权限配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.phoneinteceptor_one"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- 接收短信广播的权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<!-- 读取短信内容的权限 -->
<uses-permission android:name="android.permission.READ_SMS"/>
<!-- 接收开机广播的权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- 读取电话状态的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 打/挂电话的权限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar" >
<activity
android:name="com.example.phoneinteceptor_one.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>
<activity
android:name="com.example.phoneinteceptor_one.BlackAddActivity"
android:label="@string/title_activity_black_add" >
</activity>
<!--注册一个广播接收器 SmsReceiver 优先级0==100 优先级设置为最大值 短信-->
<receiver android:name="com.example.receiver.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<!-- 注册一个广播接收器 BootReceiver 开机服务-->
<receiver android:name="com.example.receiver.BootReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name="com.example.receiver.ListenerPhoneService"></service>
</application>
</manifest>
4)代码结构:

说明:部分代码没上传--此代码仅供参考………
Android实战_来电拦截专家的更多相关文章
- Android 代码实现来电拦截
为了更好地理解这个Demo,我先向大家介绍一下需求与功能. 需求: 每天都会有很多无聊的电话,比如推销商品等,占用我们大量时间不说,有时候还会打乱我们的思路,扰乱我们的正常生活.所以实现一个对某些号码 ...
- 实现android手机来电拦截系统页面弹出自定义页面特效
如何实现android手机来电拦截系统页面弹出自定义页面特效, 首先: 我们需要注册一个监听来电的广播PhoneStateReceiver 类:其次: 在onReceive里面我们获取an ...
- Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序
Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序 1. 一键启动的过程 1.1 对于global key, 系统会根据global_keys.xml发送消息给某个组件 & ...
- 10.8 android输入系统_实战_使用GlobalKey一键启动程序
11. 实战_使用GlobalKey一键启动程序参考文章:Android 两种注册(动态注册和静态注册).发送广播的区别http://www.jianshu.com/p/ea5e233d9f43 [A ...
- PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二手急速响应捡垃圾平台_3(附源码持续更新)
说明 文章首发于HURUWO的博客小站,本平台做同步备份发布. 如有浏览或访问异常图片加载失败或者相关疑问可前往原博客下评论浏览. 原文链接 PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二 ...
- 9套Android实战经典项目资料分享给大家
通过项目学习收获更大. 1.基于Android平台实战爱短信项目 下载地址:http://pan.baidu.com/s/1hr8CEry 2.Android平台实战CRM客户关系管理(AChartE ...
- Android监听来电和去电
要监听android打电话和接电话,只需下面2步骤1.第一步,写一个Receiver继承自BroadcastReceiver import android.app.Service; import an ...
- [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...
随机推荐
- 08SpringMvc_(1)继承AbstractCommandController的Action[能够以实体的形式,收集客户端参数].(2)日期转换器和编码过滤器
上一篇文章说过要介绍两个控制器.这篇文章就介绍第二个控制器AbstractCommandController(这个类已经快要被废弃了,有更好的代替者,但还是要好好学这个类).这个控制器的额作用是为了收 ...
- C#中的Decimal类型
这种类型又称财务类型,起源于有效数字问题.FLOAT 单精度,有效数字7位.有效数字是整数部分和小数部分加起来一共多少位.当使用科学计数法的,FLOAT型会出现很严重的错误.比如 8773234578 ...
- [转]有关WorldWind1.4的worldwind.cs窗口设计器打开错误的解决方法
Solution for Designer error when opening WorldWind.cs in WW1.4.0 When I load the WW project in my Vi ...
- Linux下Qt的安装与配置
参考资料:http://www.cnblogs.com/emouse/archive/2013/01/28/2880142.html Linux 下编译.安装.配置 QT 下载qt 这里用的是4.7. ...
- JS 之BOM
BOM的核心对象是window,表示浏览器的一个实例. 使用框架时,window.top对象指顶层框架,也就是浏览器窗口.window.parent对象指包含当前窗口的框架,也就是父框架.window ...
- Solr(5.1.0) 与Tomcat 从0开始安装与配置
1.什么是Solr? Solr是一个基于Lucene的Java搜索引擎服务器.Solr 提供了层面搜索.命中醒目显示并且支持多种输出格式(包括 XML/XSLT 和 JSON 格式).它易于安装和配置 ...
- iOS中UIMenuController的使用
不知你有没有发现,在你的微信朋友中,长按一段文字(正文或者评论),会弹出这样子的玩意: 要想在你的view或者viewController中实现长按弹出菜单栏你必须要调用becomeFirstResp ...
- Object C学习笔记21-typedef用法
在上一章的学习过程中遇到了一个关键字typedef,这个关键字是C语言中的关键字,因为Object C是C的扩展同样也是支持typedef的. 一. 基本作用 typedef是C中的关键字,它的主要作 ...
- GridView的常规用法
GridView控件在Asp.net中相当常用,以下是控件的解释,有些是常用的,有些是偶尔用到的,查找.使用.记录,仅此而已.(最后附带DropDownList控件) ASP.NET中GridView ...
- WCF 入门 (21)
前言 再不写一篇就太监了,哈哈. 第21集 WCF里面的Binding Bindings in WCF 其实不太了解为什么第21集才讲这个Binding,下面都是一些概念性的东西,不过作为一个入门视频 ...