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实战_来电拦截专家的更多相关文章

  1. Android 代码实现来电拦截

    为了更好地理解这个Demo,我先向大家介绍一下需求与功能. 需求: 每天都会有很多无聊的电话,比如推销商品等,占用我们大量时间不说,有时候还会打乱我们的思路,扰乱我们的正常生活.所以实现一个对某些号码 ...

  2. 实现android手机来电拦截系统页面弹出自定义页面特效

    如何实现android手机来电拦截系统页面弹出自定义页面特效, 首先:    我们需要注册一个监听来电的广播PhoneStateReceiver 类:其次:    在onReceive里面我们获取an ...

  3. Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序

    Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序 1. 一键启动的过程 1.1 对于global key, 系统会根据global_keys.xml发送消息给某个组件 & ...

  4. 10.8 android输入系统_实战_使用GlobalKey一键启动程序

    11. 实战_使用GlobalKey一键启动程序参考文章:Android 两种注册(动态注册和静态注册).发送广播的区别http://www.jianshu.com/p/ea5e233d9f43 [A ...

  5. PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二手急速响应捡垃圾平台_3(附源码持续更新)

    说明 文章首发于HURUWO的博客小站,本平台做同步备份发布. 如有浏览或访问异常图片加载失败或者相关疑问可前往原博客下评论浏览. 原文链接 PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二 ...

  6. 9套Android实战经典项目资料分享给大家

    通过项目学习收获更大. 1.基于Android平台实战爱短信项目 下载地址:http://pan.baidu.com/s/1hr8CEry 2.Android平台实战CRM客户关系管理(AChartE ...

  7. Android监听来电和去电

    要监听android打电话和接电话,只需下面2步骤1.第一步,写一个Receiver继承自BroadcastReceiver import android.app.Service; import an ...

  8. [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...

  9. 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...

随机推荐

  1. 023医疗项目-模块二:药品目录的导入导出-从数据库中查出数据用XSSF导出excel并存放在虚拟目录最后下载(包括调试)

    我们要实现的效果:     进入到这个页面后,输入要查询的条件,查询出药品表的数据,然后按下导出按钮 ,就会在服务器的一个目录下生成一个药品表的excel表格.  点击"导出"之后 ...

  2. Web的形式发布静态文件

    Web的形式发布静态文件 虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件 ...

  3. 利用ViewHolder优化自定义Adapter的典型写法

    1 public class MarkerItemAdapter extends BaseAdapter { private Context mContext = null; private List ...

  4. [转]仿World Wind构造自己的C#版插件框架——WW插件机制精简改造

    很久没自己写东西啦,早该好好总结一下啦!一个大师说过“一个问题不应该被解决两次!”,除了一个好脑筋,再就是要坚持总结. 最近需要搞个系统的插件式框架,我参照World Wind的插件方式构建了个插件框 ...

  5. REST签名认证

    139 开放平台与应用之间以REST协议进行通讯,为了保证通信的安全性,开放平台加入签名认证机制.应用一旦创建,系统生成唯一并且不公开的secretkey,只有应用的拥有者和开放平台知道.因此,当应用 ...

  6. MVC出错案例之一:主外键映射失败

    今天在编写DomainModel和DomainMapper,最后放到OnModelCreating中运行的时候,给我抛出了如下错误: One or more validation errors wer ...

  7. CSS 实现加载动画之二-圆环旋转

    上次简单的介绍了下如何用代码实现菊花旋转的加载动画,动画点击,这次继续我们的动画系列,实现另外一种加载动画,圆环旋转.与上次不同的是,菊花旋转是通过改变元素透明度来实现动画,这次因为考虑到元素叠加,加 ...

  8. SpringMVC数据验证

    SpringMVC数据验证——第七章 注解式控制器的数据验证.类型转换及格式化——跟着开涛学SpringMVC 资源来自:http://jinnianshilongnian.iteye.com/blo ...

  9. Activiti系列:为什么Activiti 5.18 的REST的api总是返回404错误

    REST api可以访问了,如下 1.修改db.properties配置文件,让他访问sql server 2.在浏览器中输入如下地址,注意中间有一个service,这点和之前的不一样,在<Ac ...

  10. 20145215实验五 Java网络编程及安全

    20145215实验五 Java网络编程及安全 实验内容 掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验步骤 本次实验我的结对编程对象是20145208蔡野,我负责编写客 ...