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)代码结构:

说明:部分代码没上传--此代码仅供参考………

时间: 2024-10-18 02:16:09

Android实战_来电拦截专家的相关文章

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

11. 实战_使用GlobalKey一键启动程序参考文章:Android 两种注册.发送广播的区别http://www.jianshu.com/p/ea5e233d9f43 [Android]动态注册广播接收器 http://blog.csdn.net/etzmico/article/details/7317528 Android初学习 - 在BroadcastReceiver中启动Activity的问题 http://blog.csdn.net/cnmilan/article/details/

android实战网址

10套Android实战经典资料分享 收集了10套Android学习资料,分享给大家,希望对学习这方面的朋友有帮助 1.实战Android手机客户端的家校通平台V1.0(SurfaceView实现统计图表)下载地址:http://pan.baidu.com/share/link?shareid=3121570264&uk=506606919&third=15 2.基于智能手机Android平台音乐播放器全程开发实战下载地址:http://pan.baidu.com/share/link?s

用代码实现来电拦截

如果要进行来电拦截,首先要定义权限,然后写一个接收来电去电的广播.由于不同机型的问题,动态注册还是静态注册有待商榷,我这里用的是静态注册,模拟器测试通过. 一.申请权限 <!-- 添加访问手机电话状态的权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 拨打电话权限 --> <uses-permission android:name

【Android实战】记录自学自定义GifView过程,能同时支持gif和其他图片!【实用篇】

之前写了一篇博客,<[Android实战]记录自学自定义GifView过程,详解属性那些事![学习篇]> 关于自定义GifView的,详细讲解了学习过程及遇到的一些类的解释,然后完成了一个项目,能通过在xml加入自定义 view (MyGifView)中加入自定义属性(my:gif_src = "@drawable/coffee"),达到播放gif图片的效果. 但是,有几个问题 1.gif_src 属性只支持 gif 图,并不支持其他类型的图片 2.只支持默认的引用图片,不

Android实战技巧之四十三:终止一个线程引起的

这是一道老牌面试题.通常面试官会问你对Java线程的了解,然后再问此问题. 从理论到实践,这是一条好路子. 线程是操作系统实现多任务的一种方式,可以理解为线程是一个任务的执行单元.比如Android系统中每个App都会有自己的主线程,同时还可以创建worker thread"并行"为我们工作. Java中创建新线程的方法 Java对线程(Thread)提供了语言级的支持(依托虚拟机吧).java.lang包下有Thread类和Runnable接口,都可以替你完成创建新线程的工作. 1.

【Android实战】记录自学自己定义GifView过程,能同一时候支持gif和其它图片!【有用篇】

之前写了一篇博客.<[Android实战]记录自学自己定义GifView过程,具体解释属性那些事! [学习篇]> 关于自己定义GifView的,具体解说了学习过程及遇到的一些类的解释,然后完毕了一个项目,能通过在xml增加自己定义 view (MyGifView)中增加自己定义属性(my:gif_src = "@drawable/coffee").达到播放gif图片的效果. 可是.有几个问题 1.gif_src 属性仅仅支持 gif 图,并不支持其它类型的图片 2.仅仅支持

Android实战技巧:深入解析AsyncTask

AsyncTask的介绍及基本使用方法 关于AsyncTask的介绍和基本使用方法可以参考官方文档和Android实战技巧:多线程AsyncTask这里就不重复. AsyncTask引发的一个问题 上周遇到了一个极其诡异的问题,一个小功能从网络上下载一个图片,然后放到ImageView中,是用AsyncTask来实现的,本身逻辑也很简单,仅是在doInBackground中用HTTP请求把图片的输入流取出,然后用BitmapFactory去解析,然后再把得到的Bitmap放到ImageView中

Android实战简易教程-第四十枪(窃听风云之短信监听)

近期在做监听验证码短信自己主动填入的功能,无意间想到了一个短信监听的办法. 免责声明:短信监听本身是一种违法行为,这里仅仅是技术描写叙述.请大家学习技术就可以.(哈哈) 本实例是基于bmob提供的后台服务,将监听到的短信自己主动上传到bmob数据库中. 一.代码实现: 1.首先实现javabean对象. package com.example.messagecut; import cn.bmob.v3.BmobObject; public class MsgContent extends Bmo

Android实战技巧:ViewStub的应用

Android实战技巧:ViewStub的应用